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
(46) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <sag...@us...> - 2011-04-13 17:44:38
|
Revision: 852
http://modplug.svn.sourceforge.net/modplug/?rev=852&view=rev
Author: saga-games
Date: 2011-04-13 17:44:31 +0000 (Wed, 13 Apr 2011)
Log Message:
-----------
[Fix] Damn... installer was copying release note images to a wrong directory!
[Imp] Update Checker: Update URL can now be reset in the config dialog.
[Mod] Mod Conversion: When converting from MOD/S3M to XM/IT, compatible play is automatically enabled.
[Ref] More refactoring in view_pat.cpp
Modified Paths:
--------------
trunk/OpenMPT/installer/install.iss
trunk/OpenMPT/mptrack/Draw_pat.cpp
trunk/OpenMPT/mptrack/ModConvert.cpp
trunk/OpenMPT/mptrack/UpdateCheck.cpp
trunk/OpenMPT/mptrack/UpdateCheck.h
trunk/OpenMPT/mptrack/View_pat.cpp
trunk/OpenMPT/mptrack/View_pat.h
trunk/OpenMPT/mptrack/mptrack.rc
Modified: trunk/OpenMPT/installer/install.iss
===================================================================
--- trunk/OpenMPT/installer/install.iss 2011-04-13 13:44:49 UTC (rev 851)
+++ trunk/OpenMPT/installer/install.iss 2011-04-13 17:44:31 UTC (rev 852)
@@ -73,7 +73,7 @@
; release notes
Source: ..\packageTemplate\ReleaseNotesImages\general\*.*; DestDir: {app}\ReleaseNotesImages\general\; Flags: ignoreversion sortfilesbyextension
-Source: ..\packageTemplate\ReleaseNotesImages\1.19\*.*; DestDir: {app}\ReleaseNotesImages\1.18\; Flags: ignoreversion sortfilesbyextension
+Source: ..\packageTemplate\ReleaseNotesImages\1.19\*.*; DestDir: {app}\ReleaseNotesImages\1.19\; Flags: ignoreversion sortfilesbyextension
Source: ..\packageTemplate\OMPT_1.19_ReleaseNotes.html; DestDir: {app}; Flags: ignoreversion
; soundtouch license stuff
Modified: trunk/OpenMPT/mptrack/Draw_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Draw_pat.cpp 2011-04-13 13:44:49 UTC (rev 851)
+++ trunk/OpenMPT/mptrack/Draw_pat.cpp 2011-04-13 17:44:31 UTC (rev 852)
@@ -509,7 +509,7 @@
r.top = rect.top;
r.bottom = rect.bottom;
// Drop position depends on whether hovered channel is left or right of dragged item.
- r.left = ((m_nDropItem & DRAGITEM_VALUEMASK) < (m_nDragItem & DRAGITEM_VALUEMASK) || m_bShiftDragging) ? rect.left : rect.right - 3;
+ r.left = ((m_nDropItem & DRAGITEM_VALUEMASK) < (m_nDragItem & DRAGITEM_VALUEMASK) || m_bShiftDragging) ? rect.left : rect.right - 2;
r.right = r.left + 2;
::FillRect(hdc, &r, CMainFrame::brushText);
}
Modified: trunk/OpenMPT/mptrack/ModConvert.cpp
===================================================================
--- trunk/OpenMPT/mptrack/ModConvert.cpp 2011-04-13 13:44:49 UTC (rev 851)
+++ trunk/OpenMPT/mptrack/ModConvert.cpp 2011-04-13 17:44:31 UTC (rev 852)
@@ -458,6 +458,11 @@
CHANGEMODTYPE_WARNING(wMixmode);
}
+ // Automatically enable compatible mode when converting from MOD and S3M, since it's automatically enabled in those formats.
+ if((nOldType & (MOD_TYPE_MOD|MOD_TYPE_S3M)) && (nNewType & (MOD_TYPE_XM|MOD_TYPE_IT)))
+ {
+ m_SndFile.SetModFlag(MSF_COMPATIBLE_PLAY, true);
+ }
if((nNewType & (MOD_TYPE_XM|MOD_TYPE_IT)) && !m_SndFile.GetModFlag(MSF_COMPATIBLE_PLAY))
{
CHANGEMODTYPE_WARNING(wCompatibilityMode);
Modified: trunk/OpenMPT/mptrack/UpdateCheck.cpp
===================================================================
--- trunk/OpenMPT/mptrack/UpdateCheck.cpp 2011-04-13 13:44:49 UTC (rev 851)
+++ trunk/OpenMPT/mptrack/UpdateCheck.cpp 2011-04-13 17:44:31 UTC (rev 852)
@@ -17,10 +17,12 @@
#endif
+const CString CUpdateCheck::defaultUpdateURL = "http://update.openmpt.org/check/%s";
+
// Static configuration variables
time_t CUpdateCheck::lastUpdateCheck = 0;
int CUpdateCheck::updateCheckPeriod = 7;
-CString CUpdateCheck::updateBaseURL = "http://update.openmpt.org/check/%s";
+CString CUpdateCheck::updateBaseURL = CUpdateCheck::defaultUpdateURL;
bool CUpdateCheck::showUpdateHint = true;
@@ -271,6 +273,7 @@
BEGIN_MESSAGE_MAP(CUpdateSetupDlg, CPropertyPage)
ON_COMMAND(IDC_BUTTON1, OnCheckNow)
+ ON_COMMAND(IDC_BUTTON2, OnResetURL)
ON_COMMAND(IDC_RADIO1, OnSettingsChanged)
ON_COMMAND(IDC_RADIO2, OnSettingsChanged)
ON_COMMAND(IDC_RADIO3, OnSettingsChanged)
@@ -342,3 +345,9 @@
CMainFrame::GetMainFrame()->PostMessage(WM_COMMAND, ID_INTERNETUPDATE);
}
+
+void CUpdateSetupDlg::OnResetURL()
+//--------------------------------
+{
+ SetDlgItemText(IDC_EDIT1, CUpdateCheck::defaultUpdateURL);
+}
Modified: trunk/OpenMPT/mptrack/UpdateCheck.h
===================================================================
--- trunk/OpenMPT/mptrack/UpdateCheck.h 2011-04-13 13:44:49 UTC (rev 851)
+++ trunk/OpenMPT/mptrack/UpdateCheck.h 2011-04-13 17:44:31 UTC (rev 852)
@@ -27,6 +27,8 @@
{
public:
+ static const CString defaultUpdateURL;
+
// Force creation via "new" as we're using "delete this".
static CUpdateCheck *Create(bool autoUpdate) { return new CUpdateCheck(autoUpdate); };
void DoUpdateCheck();
@@ -76,6 +78,7 @@
virtual BOOL OnSetActive();
afx_msg void OnSettingsChanged() { SetModified(TRUE); }
afx_msg void OnCheckNow();
+ afx_msg void OnResetURL();
DECLARE_MESSAGE_MAP()
};
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2011-04-13 13:44:49 UTC (rev 851)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2011-04-13 17:44:31 UTC (rev 852)
@@ -534,7 +534,7 @@
if (!bNoMove) SetCurSel(m_dwStartSel, dwPos);
if (!bScroll) return TRUE;
// Scroll to row
- row = dwPos >> 16;
+ row = GetRowFromCursor(dwPos);
if (row < (int)pSndFile->Patterns[m_nPattern].GetNumRows())
{
row += m_nMidRow;
@@ -557,11 +557,11 @@
}
}
// Scroll to column
- col = (dwPos & 0xFFFF) >> 3;
+ col = GetChanFromCursor(dwPos);
if (col < (int)pSndFile->m_nChannels)
{
int maxcol = (rect.right - m_szHeader.cx) - 4;
- maxcol -= GetColumnOffset(dwPos&7);
+ maxcol -= GetColumnOffset(GetColTypeFromCursor(dwPos));
maxcol /= GetColumnWidth();
if (col < xofs)
{
@@ -650,7 +650,7 @@
UINT nRepCnt = LOWORD(pMsg->lParam);
UINT nFlags = HIWORD(pMsg->lParam);
KeyEventType kT = ih->GetKeyEventType(nFlags);
- InputTargetContext ctx = (InputTargetContext)(kCtxViewPatterns+1 + (m_dwCursor & 0x07));
+ InputTargetContext ctx = (InputTargetContext)(kCtxViewPatterns + 1 + GetColTypeFromCursor(m_dwCursor));
if (ih->KeyEvent(ctx, nChar, nRepCnt, nFlags, kT) != kcNull) {
return true; // Mapped to a command, no need to pass message on.
@@ -771,20 +771,20 @@
DWORD endSel = ((m_dwBeginSel>>16)<(m_dwEndSel>>16)) ? m_dwEndSel : m_dwBeginSel;
pModDoc->GetPatternUndo()->PrepareUndo(m_nPattern, 0, 0, pSndFile->m_nChannels, pSndFile->Patterns[m_nPattern].GetNumRows());
- int finalDest = (startSel>>16)+((endSel>>16)-(startSel>>16))*2;
- for (int row=finalDest; row>(int)(startSel >> 16); row-=2)
+ int finalDest = GetRowFromCursor(startSel) + (GetRowFromCursor(endSel) - GetRowFromCursor(startSel))*2;
+ for (int row = finalDest; row > (int)GetRowFromCursor(startSel); row -= 2)
{
- int offset = row-(startSel>>16);
- for (UINT i=(startSel & 0xFFFF); i<=(endSel & 0xFFFF); i++) if ((i & 7) <= LAST_COLUMN)
+ int offset = row - GetRowFromCursor(startSel);
+ for (UINT i=(startSel & 0xFFFF); i<=(endSel & 0xFFFF); i++) if (GetColTypeFromCursor(i) <= LAST_COLUMN)
{
- UINT chn = i >> 3;
- if ((chn >= pSndFile->m_nChannels) || (row >= pSndFile->Patterns[m_nPattern].GetNumRows())) continue;
- MODCOMMAND *dest = &p[row * pSndFile->m_nChannels + chn];
- MODCOMMAND *src = &p[(row-offset/2) * pSndFile->m_nChannels + chn];
- MODCOMMAND *blank= &p[(row-1) * pSndFile->m_nChannels + chn];
+ UINT chn = GetChanFromCursor(i);
+ if ((chn >= pSndFile->GetNumChannels()) || (row >= pSndFile->Patterns[m_nPattern].GetNumRows())) continue;
+ MODCOMMAND *dest = &p[row * pSndFile->GetNumChannels() + chn];
+ MODCOMMAND *src = &p[(row-offset/2) * pSndFile->GetNumChannels() + chn];
+ MODCOMMAND *blank= &p[(row-1) * pSndFile->GetNumChannels() + chn];
//memcpy(dest/*+(i%5)*/, src/*+(i%5)*/, /*sizeof(MODCOMMAND) - (i-chn)*/ sizeof(BYTE));
//Log("dst: %d; src: %d; blk: %d\n", row, (row-offset/2), (row-1));
- switch(i & 7)
+ switch(GetColTypeFromCursor(i))
{
case NOTE_COLUMN: dest->note = src->note; blank->note = NOTE_NONE; break;
case INST_COLUMN: dest->instr = src->instr; blank->instr = 0; break;
@@ -821,16 +821,16 @@
DWORD endSel = ((m_dwBeginSel>>16)<(m_dwEndSel>>16)) ? m_dwEndSel : m_dwBeginSel;
pModDoc->GetPatternUndo()->PrepareUndo(m_nPattern, 0, 0, pSndFile->m_nChannels, pSndFile->Patterns[m_nPattern].GetNumRows());
- int finalDest = (startSel>>16)+((endSel>>16)-(startSel>>16))/2;
+ int finalDest = GetRowFromCursor(startSel) + (GetRowFromCursor(endSel) - GetRowFromCursor(startSel))/2;
- for (int row=(startSel >> 16); row <= finalDest; row++)
+ for (int row = GetRowFromCursor(startSel); row <= finalDest; row++)
{
- int offset = row - (startSel >> 16);
- int srcRow = (startSel >> 16) + (offset * 2);
+ int offset = row - GetRowFromCursor(startSel);
+ int srcRow = GetRowFromCursor(startSel) + (offset * 2);
- for (UINT i = (startSel & 0xFFFF); i <= (endSel & 0xFFFF); i++) if ((i & 7) <= LAST_COLUMN)
+ for (UINT i = (startSel & 0xFFFF); i <= (endSel & 0xFFFF); i++) if (GetColTypeFromCursor(i) <= LAST_COLUMN)
{
- const CHANNELINDEX chn = i >> 3;
+ const CHANNELINDEX chn = GetChanFromCursor(i);
if ((chn >= pSndFile->GetNumChannels()) || (srcRow >= pSndFile->Patterns[m_nPattern].GetNumRows())
|| (row >= pSndFile->Patterns[m_nPattern].GetNumRows())) continue;
MODCOMMAND *dest = pSndFile->Patterns[m_nPattern].GetpModCommand(row, chn);
@@ -855,7 +855,7 @@
//memcpy(dest/*+(i%5)*/, src/*+(i%5)*/, /*sizeof(MODCOMMAND) - (i-chn)*/ sizeof(BYTE));
Log("dst: %d; src: %d\n", row, srcRow);
- switch(i & 7)
+ switch(GetColTypeFromCursor(i))
{
case NOTE_COLUMN: dest->note = src->note; break;
case INST_COLUMN: dest->instr = src->instr; break;
@@ -866,13 +866,13 @@
}
}
}
- for (int row=finalDest+1; row<=(endSel>>16); row++)
+ for (int row = finalDest + 1; row <= GetRowFromCursor(endSel); row++)
{
- for (UINT i = (startSel & 0xFFFF); i <= (endSel & 0xFFFF); i++) if ((i & 7) <= LAST_COLUMN)
+ for (UINT i = (startSel & 0xFFFF); i <= (endSel & 0xFFFF); i++) if (GetColTypeFromCursor(i) <= LAST_COLUMN)
{
- UINT chn = i >> 3;
+ UINT chn = GetChanFromCursor(i);
MODCOMMAND *dest = pSndFile->Patterns[m_nPattern].GetpModCommand(row, chn);
- switch(i & 7)
+ switch(GetColTypeFromCursor(i))
{
case NOTE_COLUMN: dest->note = NOTE_NONE; break;
case INST_COLUMN: dest->instr = 0; break;
@@ -919,13 +919,13 @@
DWORD tmp = m_dwEndSel;
bool invalidateAllCols = false;
- for (UINT row=(m_dwBeginSel >> 16); row<=(m_dwEndSel >> 16); row++) { // for all selected rows
- for (UINT i=(m_dwBeginSel & 0xFFFF); i<=(m_dwEndSel & 0xFFFF); i++) if ((i & 7) < 5) { // for all selected cols
+ for (UINT row = GetRowFromCursor(m_dwBeginSel); row <= GetRowFromCursor(m_dwEndSel); row++) { // for all selected rows
+ for (UINT i=(m_dwBeginSel & 0xFFFF); i<=(m_dwEndSel & 0xFFFF); i++) if (GetColTypeFromCursor(i) <= LAST_COLUMN) { // for all selected cols
- UINT chn = i >> 3;
+ UINT chn = GetChanFromCursor(i);
if ((chn >= pSndFile->m_nChannels) || (row >= pSndFile->Patterns[m_nPattern].GetNumRows())) continue;
MODCOMMAND *m = &p[row * pSndFile->m_nChannels + chn];
- switch(i & 7)
+ switch(GetColTypeFromCursor(i))
{
case NOTE_COLUMN: // Clear note
if (rm.note)
@@ -982,7 +982,7 @@
// If selection ends on effect command column, extent invalidation area to
// effect param column as well.
- if ((tmp & 7) == EFFECT_COLUMN)
+ if (GetColTypeFromCursor(tmp) == EFFECT_COLUMN)
tmp++;
// If invalidation on all columns is wanted, extent invalidation area.
@@ -1036,7 +1036,7 @@
{
if (nFlags & MK_CONTROL)
{
- TogglePendingMute((GetPositionFromPoint(point)&0xFFFF)>>3);
+ TogglePendingMute(GetChanFromCursor(GetPositionFromPoint(point)));
}
}
else if ((point.x >= m_szHeader.cx) && (point.y > m_szHeader.cy))
@@ -1057,7 +1057,7 @@
{
// Set first selection point
m_dwStartSel = GetPositionFromPoint(point);
- if (((m_dwStartSel & 0xFFFF) >> 3) < pModDoc->GetNumChannels())
+ if (GetChanFromCursor(m_dwStartSel) < pModDoc->GetNumChannels())
{
m_dwStatus |= PATSTATUS_MOUSEDRAGSEL;
@@ -1067,8 +1067,8 @@
}
if ((CMainFrame::m_dwPatternSetup & PATTERN_DRAGNDROPEDIT)
&& ((m_dwBeginSel != m_dwEndSel) || (m_dwStatus & PATSTATUS_CTRLDRAGSEL))
- && ((m_dwStartSel >> 16) >= (m_dwBeginSel >> 16))
- && ((m_dwStartSel >> 16) <= (m_dwEndSel >> 16))
+ && (GetRowFromCursor(m_dwStartSel) >= GetRowFromCursor(m_dwBeginSel))
+ && (GetRowFromCursor(m_dwStartSel) <= GetRowFromCursor(m_dwEndSel))
&& ((m_dwStartSel & 0xFFFF) >= (m_dwBeginSel & 0xFFFF))
&& ((m_dwStartSel & 0xFFFF) <= (m_dwEndSel & 0xFFFF)))
{
@@ -1080,7 +1080,7 @@
} else
{
// Fix: Horizontal scrollbar pos screwed when selecting with mouse
- SetCursorPosition( m_dwStartSel >> 16, m_dwStartSel & 0xFFFF );
+ SetCursorPosition( GetRowFromCursor(m_dwStartSel), m_dwStartSel & 0xFFFF );
}
}
}
@@ -1090,7 +1090,7 @@
// Mark row number => mark whole row (start)
InvalidateSelection();
DWORD dwPoint = GetPositionFromPoint(point);
- if((dwPoint >> 16) < pModDoc->GetSoundFile()->Patterns[m_nPattern].GetNumRows())
+ if(GetRowFromCursor(dwPoint) < pModDoc->GetSoundFile()->Patterns[m_nPattern].GetNumRows())
{
m_dwBeginSel = m_dwStartSel = dwPoint;
m_dwEndSel = m_dwBeginSel | 0xFFFF;
@@ -1156,7 +1156,7 @@
{
DWORD dwPos = m_dwBeginSel;
// Fix: Horizontal scrollbar pos screwed when selecting with mouse
- SetCursorPosition( dwPos >> 16, dwPos & 0xFFFF );
+ SetCursorPosition( GetRowFromCursor(dwPos), dwPos & 0xFFFF );
//UpdateIndicator();
}
}
@@ -1296,18 +1296,18 @@
m_nMenuParam = GetPositionFromPoint(pt);
// Right-click outside selection? Reposition cursor to the new location
- if (((m_nMenuParam >> 16) < (m_dwBeginSel >> 16))
- || ((m_nMenuParam >> 16) > (m_dwEndSel >> 16))
+ if ((GetRowFromCursor(m_nMenuParam) < GetRowFromCursor(m_dwBeginSel))
+ || (GetRowFromCursor(m_nMenuParam) > GetRowFromCursor(m_dwEndSel))
|| ((m_nMenuParam & 0xFFFF) < (m_dwBeginSel & 0xFFFF))
|| ((m_nMenuParam & 0xFFFF) > (m_dwEndSel & 0xFFFF)))
{
if (pt.y > m_szHeader.cy) { //ensure we're not clicking header
// Fix: Horizontal scrollbar pos screwed when selecting with mouse
- SetCursorPosition( m_nMenuParam >> 16, m_nMenuParam & 0xFFFF );
+ SetCursorPosition( GetRowFromCursor(m_nMenuParam), m_nMenuParam & 0xFFFF );
}
}
- UINT nChn = (m_nMenuParam & 0xFFFF) >> 3;
- if ((nChn < pSndFile->m_nChannels) && (pSndFile->Patterns[m_nPattern]))
+ const CHANNELINDEX nChn = GetChanFromCursor(m_nMenuParam);
+ if ((nChn < pSndFile->GetNumChannels()) && (pSndFile->Patterns[m_nPattern]))
{
CString MenuText;
CInputHandler* ih = (CMainFrame::GetMainFrame())->GetInputHandler();
@@ -1434,7 +1434,7 @@
DWORD dwPos = GetPositionFromPoint(point);
if ((pModDoc) && (m_nPattern < pModDoc->GetSoundFile()->Patterns.Size()))
{
- UINT row = dwPos >> 16;
+ UINT row = GetRowFromCursor(dwPos);
UINT max = pModDoc->GetSoundFile()->Patterns[m_nPattern].GetNumRows();
if ((row) && (row >= max)) row = max-1;
dwPos &= 0xFFFF;
@@ -1462,7 +1462,7 @@
} else
{
// Fix: Horizontal scrollbar pos screwed when selecting with mouse
- SetCursorPosition( dwPos >> 16, dwPos & 0xFFFF );
+ SetCursorPosition( GetRowFromCursor(dwPos), dwPos & 0xFFFF );
}
}
}
@@ -1537,21 +1537,20 @@
OnMuteChannel(false);
}
-void CViewPattern::OnMuteChannel(BOOL current)
+void CViewPattern::OnMuteChannel(bool current)
//--------------------------------------------
{
CModDoc *pModDoc = GetDocument();
if (pModDoc)
{
- UINT nChn = current ? (m_dwCursor&0xFFFF)>>3 : (m_nMenuParam&0xFFFF)>>3;
+ const CHANNELINDEX nChn = GetChanFromCursor(current ? m_dwCursor : m_nMenuParam);
pModDoc->SoloChannel(nChn, false); //rewbs.merge: recover old solo/mute behaviour
pModDoc->MuteChannel(nChn, !pModDoc->IsChannelMuted(nChn));
//If we just unmuted a channel, make sure none are still considered "solo".
if(!pModDoc->IsChannelMuted(nChn))
{
- const CHANNELINDEX nNumChn = pModDoc->GetNumChannels();
- for(CHANNELINDEX i = 0; i < nNumChn; i++)
+ for(CHANNELINDEX i = 0; i < pModDoc->GetNumChannels(); i++)
{
pModDoc->SoloChannel(i, false);
}
@@ -1570,17 +1569,14 @@
// When trying to solo a channel that is already the only unmuted channel,
// this will result in unmuting all channels, in order to satisfy user habits.
// In all other cases, soloing a channel unsoloes all and mutes all except this channel
-void CViewPattern::OnSoloChannel(BOOL current)
+void CViewPattern::OnSoloChannel(bool current)
//--------------------------------------------
{
CModDoc *pModDoc = GetDocument();
- if (!pModDoc) {
- return;
- }
+ if (pModDoc == nullptr) return;
- const CHANNELINDEX nNumChn = pModDoc->GetNumChannels();
- const CHANNELINDEX nChn = current ? (m_dwCursor&0xFFFF)>>3 : (m_nMenuParam&0xFFFF)>>3;
- if (nChn >= nNumChn)
+ const CHANNELINDEX nChn = GetChanFromCursor(current ? m_dwCursor : m_nMenuParam);
+ if (nChn >= pModDoc->GetNumChannels())
{
return;
}
@@ -1588,7 +1584,7 @@
if (pModDoc->IsChannelSolo(nChn))
{
bool nChnIsOnlyUnMutedChan=true;
- for (CHANNELINDEX i = 0; i < nNumChn; i++) //check status of all other chans
+ for (CHANNELINDEX i = 0; i < pModDoc->GetNumChannels(); i++) //check status of all other chans
{
if (i != nChn && !pModDoc->IsChannelMuted(i))
{
@@ -1602,7 +1598,7 @@
return;
}
}
- for(CHANNELINDEX i = 0; i < nNumChn; i++)
+ for(CHANNELINDEX i = 0; i < pModDoc->GetNumChannels(); i++)
{
pModDoc->MuteChannel(i, !(i == nChn)); //mute all chans except nChn, unmute nChn
pModDoc->SoloChannel(i, (i == nChn)); //unsolo all chans except nChn, solo nChn
@@ -1618,7 +1614,7 @@
if (pModDoc)
{
UINT nNumChn = pModDoc->GetNumChannels();
- UINT nChn = (m_nMenuParam & 0xFFFF) >> 3;
+ UINT nChn = GetChanFromCursor(m_nMenuParam);
if (nChn < nNumChn)
{
// MultiRecordMask[nChn>>3] ^= (1 << (nChn & 7));
@@ -1638,7 +1634,7 @@
CModDoc *pModDoc = GetDocument();
if (pModDoc){
UINT nNumChn = pModDoc->GetNumChannels();
- UINT nChn = (m_nMenuParam & 0xFFFF) >> 3;
+ UINT nChn = GetChanFromCursor(m_nMenuParam);
if (nChn < nNumChn){
pModDoc->Record2Channel(nChn);
InvalidateChannelsHeaders();
@@ -1675,7 +1671,7 @@
if (!pModDoc || !( IsEditingEnabled_bmsg() )) return;
pSndFile = pModDoc->GetSoundFile();
if (!pSndFile->Patterns[m_nPattern]) return;
- row = m_dwBeginSel >> 16;
+ row = GetRowFromCursor(m_dwBeginSel);
maxrow = pSndFile->Patterns[m_nPattern].GetNumRows();
if (colmax >= pSndFile->m_nChannels) colmax = pSndFile->m_nChannels-1;
if (colmin > colmax) return;
@@ -1695,10 +1691,10 @@
}
}
//rewbs.customKeys
- DWORD finalPos = (min(m_dwEndSel >> 16, m_dwBeginSel >> 16) << 16 | (m_dwEndSel & 0xFFFF));
+ DWORD finalPos = (GetSelectionStartRow() << 16) | (m_dwEndSel & 0xFFFF);
SetCurSel(finalPos, finalPos);
// Fix: Horizontal scrollbar pos screwed when selecting with mouse
- SetCursorPosition( finalPos >> 16, finalPos & 0xFFFF );
+ SetCursorPosition( GetRowFromCursor(finalPos), finalPos & 0xFFFF );
//end rewbs.customKeys
pModDoc->SetModified();
@@ -1710,9 +1706,9 @@
void CViewPattern::OnDeleteRows()
//-------------------------------
{
- UINT colmin = (m_dwBeginSel & 0xFFFF) >> 3;
- UINT colmax = (m_dwEndSel & 0xFFFF) >> 3;
- UINT nrows = (m_dwEndSel >> 16) - (m_dwBeginSel >> 16) + 1;
+ UINT colmin = GetChanFromCursor(m_dwBeginSel);
+ UINT colmax = GetChanFromCursor(m_dwEndSel);
+ UINT nrows = GetRowFromCursor(m_dwEndSel) - GetRowFromCursor(m_dwBeginSel) + 1;
DeleteRows(colmin, colmax, nrows);
//m_dwEndSel = (m_dwEndSel & 0x0000FFFF) | (m_dwBeginSel & 0xFFFF0000);
}
@@ -1724,8 +1720,8 @@
CModDoc *pModDoc = GetDocument();
if (!pModDoc) return;
CSoundFile *pSndFile = pModDoc->GetSoundFile();
- UINT nrows = (m_dwEndSel >> 16) - (m_dwBeginSel >> 16) + 1;
- DeleteRows(0, pSndFile->m_nChannels-1, nrows);
+ UINT nrows = GetRowFromCursor(m_dwEndSel) - GetRowFromCursor(m_dwBeginSel) + 1;
+ DeleteRows(0, pSndFile->GetNumChannels() - 1, nrows);
m_dwEndSel = (m_dwEndSel & 0x0000FFFF) | (m_dwBeginSel & 0xFFFF0000);
}
@@ -1739,16 +1735,16 @@
if (!pModDoc || !(IsEditingEnabled_bmsg())) return;
pSndFile = pModDoc->GetSoundFile();
if (!pSndFile->Patterns[m_nPattern]) return;
- row = m_dwBeginSel >> 16;
+ row = GetRowFromCursor(m_dwBeginSel);
maxrow = pSndFile->Patterns[m_nPattern].GetNumRows();
- if (colmax >= pSndFile->m_nChannels) colmax = pSndFile->m_nChannels-1;
+ if (colmax >= pSndFile->GetNumChannels()) colmax = pSndFile->GetNumChannels() - 1;
if (colmin > colmax) return;
- pModDoc->GetPatternUndo()->PrepareUndo(m_nPattern, 0,0, pSndFile->m_nChannels, maxrow);
+ pModDoc->GetPatternUndo()->PrepareUndo(m_nPattern, 0,0, pSndFile->GetNumChannels(), maxrow);
for (UINT r=maxrow; r>row; )
{
r--;
- MODCOMMAND *m = pSndFile->Patterns[m_nPattern] + r * pSndFile->m_nChannels + colmin;
+ MODCOMMAND *m = pSndFile->Patterns[m_nPattern] + r * pSndFile->GetNumChannels() + colmin;
for (UINT c=colmin; c<=colmax; c++, m++)
{
if (r <= row)
@@ -1756,7 +1752,7 @@
m->Clear();
} else
{
- *m = *(m - pSndFile->m_nChannels);
+ *m = *(m - pSndFile->GetNumChannels());
}
}
}
@@ -1779,8 +1775,8 @@
if (!pSndFile->Patterns[m_nPattern]) return;
row = m_nRow;
maxrow = pSndFile->Patterns[m_nPattern].GetNumRows();
- colmin = (m_dwBeginSel & 0xFFFF) >> 3;
- colmax = (m_dwEndSel & 0xFFFF) >> 3;
+ colmin = GetChanFromCursor(m_dwBeginSel);
+ colmax = GetChanFromCursor(m_dwEndSel);
InsertRows(colmin, colmax);
}
@@ -1865,7 +1861,7 @@
{
CSoundFile* pSndFile = pModDoc->GetSoundFile();
UINT nCurrentOrder = SendCtrlMessage(CTRLMSG_GETCURRENTORDER);
- UINT nCurrentChannel = ((m_dwCursor & 0xFFFF) >> 3) + 1;
+ UINT nCurrentChannel = GetChanFromCursor(m_dwCursor) + 1;
m_pGotoWnd->UpdatePos(m_nRow, nCurrentChannel, m_nPattern, nCurrentOrder, pSndFile);
@@ -2179,8 +2175,8 @@
CSoundFile *pSndFile = pModDoc->GetSoundFile();
if ((!pSndFile->Patterns.IsValidPat(m_nPattern)) || (!pSndFile->Patterns[m_nPattern].GetNumRows())) return;
BEGIN_CRITICAL();
- // Cut instrument\xB4s/samples in virtual channels
- for (CHANNELINDEX i = pSndFile->m_nChannels; i < MAX_CHANNELS; i++)
+ // Cut instruments/samples in virtual channels
+ for (CHANNELINDEX i = pSndFile->GetNumChannels(); i < MAX_CHANNELS; i++)
{
pSndFile->Chn[i].dwFlags |= CHN_NOTEFADE | CHN_KEYOFF;
}
@@ -2215,8 +2211,8 @@
{
CSoundFile *pSndFile = pModDoc->GetSoundFile();
if ((!pSndFile->Patterns[m_nPattern].GetNumRows()) || (!pSndFile->Patterns[m_nPattern])) return;
- MODCOMMAND *m = pSndFile->Patterns[m_nPattern] + m_nRow * pSndFile->m_nChannels + ((m_dwCursor & 0xFFFF) >> 3);
- switch(m_dwCursor & 7)
+ MODCOMMAND *m = pSndFile->Patterns[m_nPattern] + m_nRow * pSndFile->GetNumChannels() + GetChanFromCursor(m_dwCursor);
+ switch(GetColTypeFromCursor(m_dwCursor))
{
case NOTE_COLUMN:
case INST_COLUMN:
@@ -2247,8 +2243,8 @@
if ((pModDoc) && (pMainFrm) && (IsEditingEnabled_bmsg()))
{
PrepareUndo(m_dwBeginSel, m_dwEndSel);
- UINT nChn = (m_dwCursor & 0xFFFF) >> 3;
- UINT nCursor = m_dwCursor & 0x07;
+ UINT nChn = GetChanFromCursor(m_dwCursor);
+ UINT nCursor = GetColTypeFromCursor(m_dwCursor);
CSoundFile *pSndFile = pModDoc->GetSoundFile();
MODCOMMAND *p = pSndFile->Patterns[m_nPattern] + m_nRow*pSndFile->m_nChannels + nChn;
@@ -2311,7 +2307,7 @@
if (pModDoc)
{
//CSoundFile *pSndFile = pModDoc->GetSoundFile();
- UINT row0 = m_dwBeginSel >> 16, row1 = m_dwEndSel >> 16, nchn = (m_dwBeginSel & 0xFFFF) >> 3;
+ UINT row0 = GetRowFromCursor(m_dwBeginSel), row1 = GetRowFromCursor(m_dwEndSel), nchn = GetChanFromCursor(m_dwBeginSel);
if (m_pEffectVis)
{
//window already there, update data
@@ -2529,8 +2525,8 @@
CModDoc *pModDoc = GetDocument();
if (pModDoc)
{
- const UINT row0 = m_dwBeginSel >> 16, row1 = m_dwEndSel >> 16;
- const UINT col0 = ((m_dwBeginSel & 0xFFFF)+7) >> 3, col1 = (m_dwEndSel & 0xFFFF) >> 3;
+ const UINT row0 = GetRowFromCursor(m_dwBeginSel), row1 = GetRowFromCursor(m_dwEndSel);
+ const UINT col0 = ((m_dwBeginSel & 0xFFFF)+7) >> 3, col1 = GetChanFromCursor(m_dwEndSel);
CSoundFile *pSndFile = pModDoc->GetSoundFile();
MODCOMMAND *pcmd = pSndFile->Patterns[m_nPattern];
const MODCOMMAND::NOTE noteMin = pSndFile->GetModSpecifications().noteMin;
@@ -2578,7 +2574,7 @@
pOldPattern = pSndFile->Patterns[m_nPattern];
if ((nChannels < 1) || (nRows < 1) || (!pOldPattern)) return;
dx = (int)((m_dwDragPos & 0xFFF8) >> 3) - (int)((m_dwStartSel & 0xFFF8) >> 3);
- dy = (int)(m_dwDragPos >> 16) - (int)(m_dwStartSel >> 16);
+ dy = (int)GetRowFromCursor(m_dwDragPos) - (int)GetRowFromCursor(m_dwStartSel);
if ((!dx) && (!dy)) return;
pModDoc->GetPatternUndo()->PrepareUndo(m_nPattern, 0,0, nChannels, nRows);
pNewPattern = CPattern::AllocatePattern(nRows, nChannels);
@@ -3711,12 +3707,12 @@
SetCurrentColumn(m_dwCursor + 1);
return wParam;
case kcNavigateNextChanSelect:
- case kcNavigateNextChan:SetCurrentColumn(((((m_dwCursor >> 3) + 1) % pSndFile->m_nChannels) << 3) | (m_dwCursor & 0x07)); return wParam;
+ case kcNavigateNextChan: SetCurrentColumn((((GetChanFromCursor(m_dwCursor) + 1) % pSndFile->m_nChannels) << 3) | GetColTypeFromCursor(m_dwCursor)); return wParam;
case kcNavigatePrevChanSelect:
- case kcNavigatePrevChan:{if (m_dwCursor >> 3)
- SetCurrentColumn(((((m_dwCursor >> 3) - 1) % pSndFile->m_nChannels) << 3) | (m_dwCursor & 0x07));
+ case kcNavigatePrevChan:{if(GetChanFromCursor(m_dwCursor) > 0)
+ SetCurrentColumn((((GetChanFromCursor(m_dwCursor) - 1) % pSndFile->m_nChannels) << 3) | GetColTypeFromCursor(m_dwCursor));
else
- SetCurrentColumn((m_dwCursor & 0x07) | ((pSndFile->m_nChannels-1) << 3));
+ SetCurrentColumn(GetColTypeFromCursor(m_dwCursor) | ((pSndFile->m_nChannels-1) << 3));
UINT n = (m_nRow << 16) | (m_dwCursor);
SetCurSel(n, n); return wParam;}
@@ -3776,11 +3772,11 @@
SelectBeatOrMeasure(wParam == kcSelectBeat); return wParam;
case kcClearRow: OnClearField(-1, false); return wParam;
- case kcClearField: OnClearField(m_dwCursor & 0x07, false); return wParam;
- case kcClearFieldITStyle: OnClearField(m_dwCursor & 0x07, false, true); return wParam;
+ case kcClearField: OnClearField(GetColTypeFromCursor(m_dwCursor), false); return wParam;
+ case kcClearFieldITStyle: OnClearField(GetColTypeFromCursor(m_dwCursor), false, true); return wParam;
case kcClearRowStep: OnClearField(-1, true); return wParam;
- case kcClearFieldStep: OnClearField(m_dwCursor & 0x07, true); return wParam;
- case kcClearFieldStepITStyle: OnClearField(m_dwCursor & 0x07, true, true); return wParam;
+ case kcClearFieldStep: OnClearField(GetColTypeFromCursor(m_dwCursor), true); return wParam;
+ case kcClearFieldStepITStyle: OnClearField(GetColTypeFromCursor(m_dwCursor), true, true); return wParam;
case kcDeleteRows: OnDeleteRows(); return wParam;
case kcDeleteAllRows: DeleteRows(0, pSndFile->m_nChannels-1,1); return wParam;
case kcInsertRow: OnInsertRows(); return wParam;
@@ -3822,7 +3818,7 @@
case kcEditPasteFlood: OnEditPasteFlood(); return wParam;
case kcEditPushForwardPaste: OnEditPushForwardPaste(); return wParam;
case kcEditSelectAll: OnEditSelectAll(); return wParam;
- case kcTogglePluginEditor: TogglePluginEditor((m_dwCursor & 0xFFFF) >> 3); return wParam;
+ case kcTogglePluginEditor: TogglePluginEditor(GetChanFromCursor(m_dwCursor)); return wParam;
case kcToggleFollowSong: SendCtrlMessage(CTRLMSG_PAT_FOLLOWSONG, 1); return wParam;
case kcChangeLoopStatus: SendCtrlMessage(CTRLMSG_PAT_LOOP, -1); return wParam;
case kcNewPattern: SendCtrlMessage(CTRLMSG_PAT_NEWPATTERN); return wParam;
@@ -4151,7 +4147,7 @@
//Enter note off in pattern?
if ((note < NOTE_MIN) || (note > NOTE_MAX))
return;
- if ((m_dwCursor & 7) > 1 && (bChordMode || !fromMidi))
+ if (GetColTypeFromCursor(m_dwCursor) > INST_COLUMN && (bChordMode || !fromMidi))
return;
if (!pModDoc || !pMainFrm || !(IsEditingEnabled()))
return;
@@ -4779,7 +4775,7 @@
}
PrepareUndo(m_dwBeginSel, m_dwEndSel);
- UINT nChn = (m_dwCursor & 0xFFFF) >> 3;
+ UINT nChn = GetChanFromCursor(m_dwCursor);
CSoundFile *pSndFile = pModDoc->GetSoundFile();
MODCOMMAND *p = pSndFile->Patterns[m_nPattern] + m_nRow*pSndFile->m_nChannels + nChn;
MODCOMMAND oldcmd = *p;
@@ -5389,23 +5385,27 @@
}
-UINT CViewPattern::GetSelectionStartRow() {
-//-----------------------------------------
+ROWINDEX CViewPattern::GetSelectionStartRow()
+//-------------------------------------------
+{
return min(GetRowFromCursor(m_dwBeginSel), GetRowFromCursor(m_dwEndSel));
}
-UINT CViewPattern::GetSelectionEndRow() {
-//---------------------------------------
+ROWINDEX CViewPattern::GetSelectionEndRow()
+//-----------------------------------------
+{
return max(GetRowFromCursor(m_dwBeginSel), GetRowFromCursor(m_dwEndSel));
}
-UINT CViewPattern::GetSelectionStartChan() {
-//------------------------------------------
+CHANNELINDEX CViewPattern::GetSelectionStartChan()
+//------------------------------------------------
+{
return min(GetChanFromCursor(m_dwBeginSel), GetChanFromCursor(m_dwEndSel));
}
-UINT CViewPattern::GetSelectionEndChan() {
-//----------------------------------------
+CHANNELINDEX CViewPattern::GetSelectionEndChan()
+//----------------------------------------------
+{
return max(GetChanFromCursor(m_dwBeginSel), GetChanFromCursor(m_dwEndSel));
}
@@ -5428,16 +5428,7 @@
return chans.GetCount();
}
-ROWINDEX CViewPattern::GetRowFromCursor(DWORD cursor) {return cursor >> 16;}
-//---------------------------------------------------
-
-CHANNELINDEX CViewPattern::GetChanFromCursor(DWORD cursor) {return static_cast<CHANNELINDEX>((cursor & 0xFFFF) >> 3);}
-//-------------------------------------------------------
-UINT CViewPattern::GetColTypeFromCursor(DWORD cursor) {return cursor & 0x07;}
-//---------------------------------------------------
-
-
bool CViewPattern::IsInterpolationPossible(ROWINDEX startRow, ROWINDEX endRow, CHANNELINDEX chan,
PatternColumns colType, CSoundFile* pSndFile)
//--------------------------------------------------------------------------------------
@@ -5486,7 +5477,7 @@
void CViewPattern::OnTogglePendingMuteFromClick()
//-----------------------------------------------
{
- TogglePendingMute((m_nMenuParam&0xFFFF)>>3);
+ TogglePendingMute(GetChanFromCursor(m_nMenuParam));
}
void CViewPattern::OnPendingSoloChnFromClick()
@@ -5752,7 +5743,7 @@
} else if(startRow == GetSelectionStartRow() && endRow == GetSelectionEndRow())
{
// Whole beat or measure is already selected
- if((m_dwBeginSel & 0x07) == 0 && (m_dwEndSel & 0x07) == LAST_COLUMN)
+ if(GetColTypeFromCursor(m_dwBeginSel) == NOTE_COLUMN && GetColTypeFromCursor(m_dwEndSel) == LAST_COLUMN)
{
// Whole channel is already selected => expand selection to whole row.
startMask = 0;
@@ -5766,8 +5757,8 @@
else
{
// Some arbitrary selection: Remember start / end column
- startMask |= (m_dwBeginSel & 0x07);
- endMask |= (m_dwEndSel & 0x07);
+ startMask |= GetColTypeFromCursor(m_dwBeginSel);
+ endMask |= GetColTypeFromCursor(m_dwEndSel);
}
SetCurSel((startRow << 16) | startMask, (endRow << 16) | endMask);
}
Modified: trunk/OpenMPT/mptrack/View_pat.h
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.h 2011-04-13 13:44:49 UTC (rev 851)
+++ trunk/OpenMPT/mptrack/View_pat.h 2011-04-13 17:44:31 UTC (rev 852)
@@ -282,8 +282,8 @@
afx_msg void OnTogglePendingMuteFromClick(); //rewbs.customKeys
afx_msg void OnPendingSoloChnFromClick();
afx_msg void OnPendingUnmuteAllChnFromClick();
- afx_msg void OnSoloChannel(BOOL current); //rewbs.customKeys
- afx_msg void OnMuteChannel(BOOL current); //rewbs.customKeys
+ afx_msg void OnSoloChannel(bool current); //rewbs.customKeys
+ afx_msg void OnMuteChannel(bool current); //rewbs.customKeys
afx_msg void OnUnmuteAll();
afx_msg void OnRecordSelect();
// -> CODE#0012
@@ -367,15 +367,15 @@
bool BuildChannelMiscCtxMenu(HMENU hMenu, CSoundFile* pSndFile);
bool BuildPCNoteCtxMenu(HMENU hMenu, CInputHandler* ih, CSoundFile* pSndFile);
- UINT GetSelectionStartRow();
- UINT GetSelectionEndRow();
- UINT GetSelectionStartChan();
- UINT GetSelectionEndChan();
+ ROWINDEX GetSelectionStartRow();
+ ROWINDEX GetSelectionEndRow();
+ CHANNELINDEX GetSelectionStartChan();
+ CHANNELINDEX GetSelectionEndChan();
UINT ListChansWhereColSelected(PatternColumns colType, CArray<UINT,UINT> &chans);
- static ROWINDEX GetRowFromCursor(DWORD cursor);
- static CHANNELINDEX GetChanFromCursor(DWORD cursor);
- static UINT GetColTypeFromCursor(DWORD cursor);
+ static ROWINDEX GetRowFromCursor(DWORD cursor) { return (cursor >> 16); };
+ static CHANNELINDEX GetChanFromCursor(DWORD cursor) { return static_cast<CHANNELINDEX>((cursor & 0xFFFF) >> 3); };
+ static UINT GetColTypeFromCursor(DWORD cursor) { return (cursor & 0x07); };
bool IsInterpolationPossible(ROWINDEX startRow, ROWINDEX endRow, CHANNELINDEX chan, PatternColumns colType, CSoundFile* pSndFile);
void Interpolate(PatternColumns type);
Modified: trunk/OpenMPT/mptrack/mptrack.rc
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.rc 2011-04-13 13:44:49 UTC (rev 851)
+++ trunk/OpenMPT/mptrack/mptrack.rc 2011-04-13 17:44:31 UTC (rev 852)
@@ -197,11 +197,12 @@
CONTROL "Weekly (recommended)",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,12,42,240,8
CONTROL "Monthly",IDC_RADIO4,"Button",BS_AUTORADIOBUTTON,12,54,240,8
GROUPBOX "Advanced Settings",IDC_STATIC,6,78,258,60
- LTEXT "Update server URL:",IDC_STATIC,12,90,246,8
+ LTEXT "Update server URL:",IDC_STATIC,12,90,186,8
EDITTEXT IDC_EDIT1,12,102,246,12,ES_AUTOHSCROLL
LTEXT "",IDC_LASTUPDATE,6,168,258,24
LTEXT "Do not change this unless you are absolutely sure of what you are doing.",IDC_STATIC,12,120,246,12
PUSHBUTTON "Check for Updates",IDC_BUTTON1,6,144,84,18
+ PUSHBUTTON "Reset",IDC_BUTTON2,204,87,54,12
END
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-13 13:45:01
|
Revision: 851
http://modplug.svn.sourceforge.net/modplug/?rev=851&view=rev
Author: saga-games
Date: 2011-04-13 13:44:49 +0000 (Wed, 13 Apr 2011)
Log Message:
-----------
A whole ton of refacting!
- ReArrangeChannels and MoveChannel have been moved to CModDoc
- Many channel adding/removing functions have been rewritten to use ReArrangeChannels, to avoid all this mess of copypasta
- Related changes to code and semantics (ReArrangeChannels returns CHANNELINDEX_INVALID on failure, changed CheckUnusedChannels() to CheckUsedChannels(), replaced big arrays with vectors, etc...)
Modified Paths:
--------------
trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp
trunk/OpenMPT/mptrack/Moddoc.cpp
trunk/OpenMPT/mptrack/Moddoc.h
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/View_pat.cpp
trunk/OpenMPT/mptrack/View_pat.h
trunk/OpenMPT/mptrack/dlg_misc.cpp
trunk/OpenMPT/mptrack/dlg_misc.h
trunk/OpenMPT/mptrack/test/test.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
trunk/OpenMPT/soundlib/Sndfile.h
Modified: trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp
===================================================================
--- trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp 2011-04-13 00:44:30 UTC (rev 850)
+++ trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp 2011-04-13 13:44:49 UTC (rev 851)
@@ -200,11 +200,11 @@
{
newChnOrder.push_back(newpat[nChn]);
}
- if(m_pSndFile->ReArrangeChannels(newChnOrder) != nChannels)
+ if(pModDoc->ReArrangeChannels(newChnOrder) != nChannels)
{
- MessageBox("Rearranging channels failed");
END_CRITICAL();
EndWaitCursor();
+ MessageBox("Rearranging channels failed");
ResetState(true, true, true, true, true);
LeaveCriticalSection(&applying);
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2011-04-13 00:44:30 UTC (rev 850)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2011-04-13 13:44:49 UTC (rev 851)
@@ -1491,7 +1491,7 @@
int nRenderPasses = 1;
// Channel mode
- bool unusedChannels[MAX_BASECHANNELS];
+ vector<bool> usedChannels;
vector<DWORD> channelFlags;
// Instrument mode
vector<bool> instrMuteState;
@@ -1500,8 +1500,7 @@
if(wsdlg.m_bChannelMode)
{
// Don't save empty channels
- memset(unusedChannels, false, sizeof(unusedChannels));
- CheckUnusedChannels(unusedChannels);
+ CheckUsedChannels(usedChannels);
nRenderPasses = m_SndFile.GetNumChannels();
channelFlags.resize(nRenderPasses, 0);
@@ -1510,7 +1509,7 @@
// Save channels' flags
channelFlags[i] = m_SndFile.ChnSettings[i].dwFlags;
// Ignore muted channels
- if(channelFlags[i] & CHN_MUTE) unusedChannels[i] = true;
+ if(channelFlags[i] & CHN_MUTE) usedChannels[i] = false;
// Mute each channel
m_SndFile.ChnSettings[i].dwFlags |= CHN_MUTE;
}
@@ -1559,7 +1558,7 @@
if(i > 0) m_SndFile.ChnSettings[i - 1].dwFlags |= CHN_MUTE;
// Was this channel actually muted? Don't process it then.
- if(unusedChannels[i] == true)
+ if(usedChannels[i] == false)
continue;
// Add channel number & name (if available) to path string
if(strlen(m_SndFile.ChnSettings[i].szName) > 0)
Modified: trunk/OpenMPT/mptrack/Moddoc.h
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.h 2011-04-13 00:44:30 UTC (rev 850)
+++ trunk/OpenMPT/mptrack/Moddoc.h 2011-04-13 13:44:49 UTC (rev 851)
@@ -274,8 +274,13 @@
// operations
public:
bool ChangeModType(MODTYPE wType);
- bool ChangeNumChannels(UINT nNewChannels, const bool showCancelInRemoveDlg = true);
+ bool ChangeNumChannels(CHANNELINDEX nNewChannels, const bool showCancelInRemoveDlg = true);
+ CHANNELINDEX ReArrangeChannels(const vector<CHANNELINDEX> &fromToArray);
+ bool MoveChannel(CHANNELINDEX chn_from, CHANNELINDEX chn_to);
+ bool RemoveChannels(const vector<bool> &keepMask);
+ void CheckUsedChannels(vector<bool> &usedMask, CHANNELINDEX maxRemoveCount = MAX_BASECHANNELS) const;
+
bool ConvertInstrumentsToSamples();
UINT RemovePlugs(const bool (&keepMask)[MAX_MIXPLUGINS]);
@@ -342,8 +347,6 @@
void LearnMacro(int macro, long param);
void SetElapsedTime(ORDERINDEX nOrd, ROWINDEX nRow);
- bool RemoveChannels(bool bChnMask[MAX_BASECHANNELS]);
-
bool RestartPosToPattern();
bool HasMPTHacks(const bool autofix = false);
@@ -373,8 +376,6 @@
BOOL InitializeMod();
void* GetChildFrame(); //rewbs.customKeys
- void CheckUnusedChannels(bool mask[MAX_BASECHANNELS], CHANNELINDEX maxRemoveCount = MAX_BASECHANNELS) const;
-
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CModDoc)
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2011-04-13 00:44:30 UTC (rev 850)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2011-04-13 13:44:49 UTC (rev 851)
@@ -32,156 +32,267 @@
}
-// Change the number of channels
-bool CModDoc::ChangeNumChannels(UINT nNewChannels, const bool showCancelInRemoveDlg)
-//----------------------------------------------------------------------------------
+// Change the number of channels.
+// Return true on success.
+bool CModDoc::ChangeNumChannels(CHANNELINDEX nNewChannels, const bool showCancelInRemoveDlg)
+//------------------------------------------------------------------------------------------
{
const CHANNELINDEX maxChans = m_SndFile.GetModSpecifications().channelsMax;
- if (nNewChannels > maxChans) {
+ if (nNewChannels > maxChans)
+ {
CString error;
error.Format("Error: Max number of channels for this file type is %d", maxChans);
::AfxMessageBox(error, MB_OK|MB_ICONEXCLAMATION);
return false;
}
- if (nNewChannels == m_SndFile.m_nChannels) return false;
- if (nNewChannels < m_SndFile.m_nChannels)
+ if (nNewChannels == GetNumChannels()) return false;
+
+ if (nNewChannels < GetNumChannels())
{
+ // Remove channels
UINT nChnToRemove = 0;
CHANNELINDEX nFound = 0;
//nNewChannels = 0 means user can choose how many channels to remove
- if(nNewChannels > 0) {
- nChnToRemove = m_SndFile.m_nChannels - nNewChannels;
+ if(nNewChannels > 0)
+ {
+ nChnToRemove = GetNumChannels() - nNewChannels;
nFound = nChnToRemove;
- } else {
+ } else
+ {
nChnToRemove = 0;
- nFound = m_SndFile.m_nChannels;
+ nFound = GetNumChannels();
}
CRemoveChannelsDlg rem(&m_SndFile, nChnToRemove, showCancelInRemoveDlg);
- CheckUnusedChannels(rem.m_bChnMask, nFound);
+ CheckUsedChannels(rem.m_bKeepMask, nFound);
if (rem.DoModal() != IDOK) return false;
// Removing selected channels
- RemoveChannels(rem.m_bChnMask);
+ return RemoveChannels(rem.m_bKeepMask);
} else
{
+ // Increasing number of channels
BeginWaitCursor();
- // Increasing number of channels
- BEGIN_CRITICAL();
- for (UINT i=0; i<m_SndFile.Patterns.Size(); i++) if (m_SndFile.Patterns[i])
+ vector<CHANNELINDEX> channels(nNewChannels, CHANNELINDEX_INVALID);
+ for(CHANNELINDEX nChn = 0; nChn < GetNumChannels(); nChn++)
{
- MODCOMMAND *p = m_SndFile.Patterns[i];
- MODCOMMAND *newp = CPattern::AllocatePattern(m_SndFile.Patterns[i].GetNumRows(), nNewChannels);
- if (!newp)
- {
- END_CRITICAL();
- AddToLog("ERROR: Not enough memory to create new channels!\nPattern Data is corrupted!\n");
- return false;
- }
- for (UINT j=0; j<m_SndFile.Patterns[i].GetNumRows(); j++)
- {
- memcpy(&newp[j*nNewChannels], &p[j*m_SndFile.m_nChannels], m_SndFile.m_nChannels*sizeof(MODCOMMAND));
- }
- m_SndFile.Patterns[i] = newp;
- CPattern::FreePattern(p);
+ channels[nChn] = nChn;
}
- //if channel was removed before and is added again, mute status has to be unset! (bug 1814)
- for (UINT i=m_SndFile.m_nChannels; i<nNewChannels; i++)
+ const bool success = (ReArrangeChannels(channels) == nNewChannels);
+ if(success)
{
- m_SndFile.InitChannel(i);
+ SetModified();
+ UpdateAllViews(NULL, HINT_MODTYPE);
}
-
- m_SndFile.m_nChannels = nNewChannels;
- m_SndFile.SetupMODPanning();
- END_CRITICAL();
- EndWaitCursor();
+ return success;
}
- SetModified();
- GetPatternUndo()->ClearUndo();
- UpdateAllViews(NULL, HINT_MODTYPE);
- return true;
}
-bool CModDoc::RemoveChannels(bool m_bChnMask[MAX_BASECHANNELS])
-//---------------------------------------------------------
-//To remove all channels whose index corresponds to true value at m_bChnMask[] array. Code is almost non-modified copy of
-//the code which was in CModDoc::ChangeNumChannels(UINT nNewChannels) - the only differences are the lines before
-//BeginWaitCursor(), few lines in the end and that nNewChannels is renamed to nRemaningChannels.
+// To remove all channels whose index corresponds to false in the keepMask vector.
+// Return true on success.
+bool CModDoc::RemoveChannels(const vector<bool> &keepMask)
+//--------------------------------------------------------
{
- UINT nRemainingChannels = 0;
- //First calculating how many channels are to be left
- UINT i = 0;
- for(i = 0; i<m_SndFile.m_nChannels; i++)
+ UINT nRemainingChannels = 0;
+ //First calculating how many channels are to be left
+ for(CHANNELINDEX nChn = 0; nChn < GetNumChannels(); nChn++)
+ {
+ if(keepMask[nChn]) nRemainingChannels++;
+ }
+ if(nRemainingChannels == GetNumChannels() || nRemainingChannels < m_SndFile.GetModSpecifications().channelsMin)
+ {
+ CString str;
+ if(nRemainingChannels == GetNumChannels()) str.Format("No channels chosen to be removed.");
+ else str.Format("No removal done - channel number is already at minimum.");
+ CMainFrame::GetMainFrame()->MessageBox(str, "Remove channel", MB_OK | MB_ICONINFORMATION);
+ return false;
+ }
+
+ BeginWaitCursor();
+ // Create new channel order, with only channels from m_bChnMask left.
+ vector<CHANNELINDEX> channels(nRemainingChannels, 0);
+ CHANNELINDEX i = 0;
+ for(CHANNELINDEX nChn = 0; nChn < GetNumChannels(); nChn++)
+ {
+ if(keepMask[nChn])
{
- if(!m_bChnMask[i]) nRemainingChannels++;
+ channels[i++] = nChn;
}
- if(nRemainingChannels == m_SndFile.m_nChannels || nRemainingChannels < m_SndFile.GetModSpecifications().channelsMin)
- {
- CString str;
- if(nRemainingChannels == m_SndFile.m_nChannels) str.Format("No channels chosen to be removed.");
- else str.Format("No removal done - channel number is already at minimum.");
- CMainFrame::GetMainFrame()->MessageBox(str , "Remove channel", MB_OK | MB_ICONINFORMATION);
- return false;
- }
+ }
+ const bool success = (ReArrangeChannels(channels) == nRemainingChannels);
+ if(success)
+ {
+ SetModified();
+ UpdateAllViews(NULL, HINT_MODTYPE);
+ }
+ EndWaitCursor();
+ return success;
- BeginWaitCursor();
- BEGIN_CRITICAL();
- for (i=0; i<m_SndFile.Patterns.Size(); i++) if (m_SndFile.Patterns[i])
+}
+
+
+// Base code for adding, removing, moving and duplicating channels. Returns new number of channels on success, CHANNELINDEX_INVALID otherwise.
+// The new channel vector can contain CHANNELINDEX_INVALID for adding new (empty) channels.
+CHANNELINDEX CModDoc::ReArrangeChannels(const vector<CHANNELINDEX> &newOrder)
+//---------------------------------------------------------------------------
+{
+ //newOrder[i] tells which current channel should be placed to i:th position in
+ //the new order, or if i is not an index of current channels, then new channel is
+ //added to position i. If index of some current channel is missing from the
+ //newOrder-vector, then the channel gets removed.
+
+ const CHANNELINDEX nRemainingChannels = static_cast<CHANNELINDEX>(newOrder.size());
+
+ if(nRemainingChannels > m_SndFile.GetModSpecifications().channelsMax || nRemainingChannels < m_SndFile.GetModSpecifications().channelsMin)
+ {
+ CString str;
+ str.Format(GetStrI18N(_TEXT("Can't apply change: Number of channels should be within [%u,%u]")), m_SndFile.GetModSpecifications().channelsMin, m_SndFile.GetModSpecifications().channelsMax);
+ CMainFrame::GetMainFrame()->MessageBox(str , "ReArrangeChannels", MB_OK | MB_ICONINFORMATION);
+ return CHANNELINDEX_INVALID;
+ }
+
+ bool first = true;
+ if(nRemainingChannels != GetNumChannels())
+ {
+ // For now, changing number of channels can't be undone
+ GetPatternUndo()->ClearUndo();
+ }
+
+ BEGIN_CRITICAL();
+ for(PATTERNINDEX nPat = 0; nPat < m_SndFile.Patterns.Size(); nPat++)
+ {
+ if(m_SndFile.Patterns[nPat])
{
- MODCOMMAND *p = m_SndFile.Patterns[i];
- MODCOMMAND *newp = CPattern::AllocatePattern(m_SndFile.Patterns[i].GetNumRows(), nRemainingChannels);
- if (!newp)
+ if(nRemainingChannels == GetNumChannels())
{
+ GetPatternUndo()->PrepareUndo(nPat, 0, 0, GetNumChannels(), m_SndFile.Patterns[nPat].GetNumRows(), !first);
+ first = false;
+ }
+
+ MODCOMMAND *p = m_SndFile.Patterns[nPat];
+ MODCOMMAND *newp = CPattern::AllocatePattern(m_SndFile.Patterns[nPat].GetNumRows(), nRemainingChannels);
+ if(!newp)
+ {
END_CRITICAL();
- AddToLog("ERROR: Not enough memory to resize patterns!\nPattern Data is corrupted!");
- return true;
+ CMainFrame::GetMainFrame()->MessageBox("ERROR: Pattern allocation failed in ReArrangechannels(...)" , "ReArrangeChannels", MB_OK | MB_ICONINFORMATION);
+ return CHANNELINDEX_INVALID;
}
MODCOMMAND *tmpsrc = p, *tmpdest = newp;
- for (UINT j=0; j<m_SndFile.Patterns[i].GetNumRows(); j++)
+ for(ROWINDEX nRow = 0; nRow < m_SndFile.Patterns[nPat].GetNumRows(); nRow++) //Scrolling rows
{
- for (UINT k=0; k<m_SndFile.m_nChannels; k++, tmpsrc++)
+ for(CHANNELINDEX nChn = 0; nChn < nRemainingChannels; nChn++, tmpdest++) //Scrolling channels.
{
- if (!m_bChnMask[k]) *tmpdest++ = *tmpsrc;
+ if(newOrder[nChn] < GetNumChannels()) //Case: getting old channel to the new channel order.
+ *tmpdest = tmpsrc[nRow * GetNumChannels() + newOrder[nChn]];
+ else //Case: figure newOrder[k] is not the index of any current channel, so adding a new channel.
+ *tmpdest = MODCOMMAND::Empty();
+
}
}
- m_SndFile.Patterns[i] = newp;
+ m_SndFile.Patterns[nPat] = newp;
CPattern::FreePattern(p);
}
- UINT tmpchn = 0;
- for (i=0; i<m_SndFile.m_nChannels; i++)
+ }
+
+ MODCHANNEL chns[MAX_BASECHANNELS];
+ MODCHANNELSETTINGS settings[MAX_BASECHANNELS];
+ vector<UINT> recordStates(GetNumChannels(), 0);
+ vector<bool> chnMutePendings(GetNumChannels(), false);
+
+ for(CHANNELINDEX nChn = 0; nChn < GetNumChannels(); nChn++)
+ {
+ settings[nChn] = m_SndFile.ChnSettings[nChn];
+ chns[nChn] = m_SndFile.Chn[nChn];
+ recordStates[nChn] = IsChannelRecord(nChn);
+ chnMutePendings[nChn] = m_SndFile.m_bChannelMuteTogglePending[nChn];
+ }
+
+ ReinitRecordState();
+
+ for(CHANNELINDEX nChn = 0; nChn < nRemainingChannels; nChn++)
+ {
+ if(newOrder[nChn] < GetNumChannels())
{
- if (!m_bChnMask[i])
- {
- if (tmpchn != i)
- {
- m_SndFile.ChnSettings[tmpchn] = m_SndFile.ChnSettings[i];
- m_SndFile.Chn[tmpchn] = m_SndFile.Chn[i];
- }
- tmpchn++;
- } else
- {
- if (i >= nRemainingChannels)
- {
- m_SndFile.InitChannel(i);
- m_SndFile.Chn[i].dwFlags |= CHN_MUTE;
- }
- }
+ m_SndFile.ChnSettings[nChn] = settings[newOrder[nChn]];
+ m_SndFile.Chn[nChn] = chns[newOrder[nChn]];
+ if(recordStates[newOrder[nChn]] == 1) Record1Channel(nChn, true);
+ if(recordStates[newOrder[nChn]] == 2) Record2Channel(nChn, true);
+ m_SndFile.m_bChannelMuteTogglePending[nChn] = chnMutePendings[newOrder[nChn]];
}
- m_SndFile.m_nChannels = nRemainingChannels;
- END_CRITICAL();
- EndWaitCursor();
- SetModified();
- GetPatternUndo()->ClearUndo();
- UpdateAllViews(NULL, HINT_MODTYPE);
- return false;
+ else
+ {
+ m_SndFile.InitChannel(nChn);
+ }
+ }
+ // Reset MOD panning (won't affect other module formats)
+ m_SndFile.SetupMODPanning();
+
+ m_SndFile.m_nChannels = nRemainingChannels;
+
+ // Reset removed channels. Most notably, clear the channel name.
+ for(CHANNELINDEX nChn = GetNumChannels(); nChn < MAX_BASECHANNELS; nChn++)
+ {
+ m_SndFile.InitChannel(nChn);
+ m_SndFile.Chn[nChn].dwFlags |= CHN_MUTE;
+ }
+
+ END_CRITICAL();
+
+ return GetNumChannels();
}
+bool CModDoc::MoveChannel(CHANNELINDEX chnFrom, CHANNELINDEX chnTo)
+//-----------------------------------------------------------------
+{
+ //Implementation of move channel using ReArrangeChannels(...). So this function
+ //only creates correct newOrder-vector used in the ReArrangeChannels(...).
+ if(chnFrom == chnTo) return false;
+ if(chnFrom >= GetNumChannels() || chnTo >= GetNumChannels())
+ {
+ CString str = "Error: Bad move indexes in CSoundFile::MoveChannel(...)";
+ CMainFrame::GetMainFrame()->MessageBox(str , "MoveChannel(...)", MB_OK | MB_ICONINFORMATION);
+ return true;
+ }
+ vector<CHANNELINDEX> newOrder;
+ //First creating new order identical to current order...
+ for(CHANNELINDEX i = 0; i < GetNumChannels(); i++)
+ {
+ newOrder.push_back(i);
+ }
+ //...and then add the move channel effect.
+ if(chnFrom < chnTo)
+ {
+ CHANNELINDEX temp = newOrder[chnFrom];
+ for(UINT i = chnFrom; i < chnTo; i++)
+ {
+ newOrder[i] = newOrder[i + 1];
+ }
+ newOrder[chnTo] = temp;
+ }
+ else //case chnFrom > chnTo(can't be equal, since it has been examined earlier.)
+ {
+ CHANNELINDEX temp = newOrder[chnFrom];
+ for(UINT i = chnFrom; i >= chnTo + 1; i--)
+ {
+ newOrder[i] = newOrder[i - 1];
+ }
+ newOrder[chnTo] = temp;
+ }
+
+ if(newOrder.size() != ReArrangeChannels(newOrder))
+ {
+ CMainFrame::GetMainFrame()->MessageBox("BUG: Channel number changed in MoveChannel()" , "", MB_OK | MB_ICONINFORMATION);
+ }
+ return false;
+}
+
+
// Functor for converting instrument numbers to sample numbers in the patterns
struct ConvertInstrumentsToSamplesInPatterns
//==========================================
@@ -1230,15 +1341,16 @@
// Check which channels contain note data. maxRemoveCount specified how many empty channels are reported at max.
-void CModDoc::CheckUnusedChannels(bool mask[MAX_BASECHANNELS], CHANNELINDEX maxRemoveCount) const
-//-----------------------------------------------------------------------------------------------
+void CModDoc::CheckUsedChannels(vector<bool> &usedMask, CHANNELINDEX maxRemoveCount) const
+//----------------------------------------------------------------------------------------
{
// Checking for unused channels
- const int nChannels = m_SndFile.GetNumChannels();
+ const int nChannels = GetNumChannels();
+ usedMask.resize(nChannels);
for(int iRst = nChannels - 1; iRst >= 0; iRst--)
{
- mask[iRst] = IsChannelUnused(iRst);
- if(mask[iRst])
+ usedMask[iRst] = !IsChannelUnused(iRst);
+ if(!usedMask[iRst])
{
// Found enough empty channels yet?
if((--maxRemoveCount) == 0) break;
@@ -1251,7 +1363,7 @@
bool CModDoc::IsChannelUnused(CHANNELINDEX nChn) const
//----------------------------------------------------
{
- const CHANNELINDEX nChannels = m_SndFile.GetNumChannels();
+ const CHANNELINDEX nChannels = GetNumChannels();
if(nChn >= nChannels)
{
return true;
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2011-04-13 00:44:30 UTC (rev 850)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2011-04-13 13:44:49 UTC (rev 851)
@@ -1127,8 +1127,6 @@
const bool bItemSelected = m_bInItemRect || ((m_nDragItem & DRAGITEM_MASK) == DRAGITEM_CHNHEADER);
if (/*(!m_bDragging) ||*/ (!pModDoc)) return;
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
-
m_bDragging = false;
m_bInItemRect = false;
ReleaseCapture();
@@ -1187,18 +1185,18 @@
pModDoc->MuteChannel(nItemNo, !pModDoc->IsChannelMuted(nItemNo));
pModDoc->UpdateAllViews(this, HINT_MODCHANNELS | ((nItemNo / CHANNELS_IN_TAB) << HINT_SHIFT_CHNTAB));
}
- } else if(nTargetNo < pSndFile->GetNumChannels())
+ } else if(nTargetNo < pModDoc->GetNumChannels())
{
// Dragged to other channel header => move or copy channel
InvalidateRect(&m_rcDropItem, FALSE);
const bool duplicate = (nFlags & MK_SHIFT) ? true : false;
- vector<CHANNELINDEX> channels(pSndFile->GetNumChannels() + (duplicate ? 1 : 0), 0);
+ vector<CHANNELINDEX> channels(pModDoc->GetNumChannels() + (duplicate ? 1 : 0), 0);
CHANNELINDEX i = 0;
bool modified = duplicate;
- for(CHANNELINDEX nChn = 0; nChn < pSndFile->GetNumChannels(); nChn++)
+ for(CHANNELINDEX nChn = 0; nChn < pModDoc->GetNumChannels(); nChn++)
{
if(nChn == nTargetNo)
{
@@ -1217,7 +1215,7 @@
modified = true;
}
}
- if(modified && pSndFile->ReArrangeChannels(channels) != 0)
+ if(modified && pModDoc->ReArrangeChannels(channels) != CHANNELINDEX_INVALID)
{
if(duplicate)
{
@@ -2671,15 +2669,17 @@
SetSelectionInstrument(GetCurrentInstrument());
}
+
void CViewPattern::OnRemoveChannelDialog()
//----------------------------------------
{
CModDoc *pModDoc = GetDocument();
- if(pModDoc == 0) return;
+ if(pModDoc == nullptr) return;
pModDoc->ChangeNumChannels(0);
SetCurrentPattern(m_nPattern); //Updating the screen.
}
+
void CViewPattern::OnRemoveChannel()
//----------------------------------
{
@@ -2700,33 +2700,35 @@
str.Format("Remove channel %d? This channel still contains note data!\nNote: Operation affects all patterns and has no undo", nChn + 1);
if(isEmpty || CMainFrame::GetMainFrame()->MessageBox(str , "Remove channel", MB_YESNO | MB_ICONQUESTION) == IDYES)
{
- bool chnMask[MAX_BASECHANNELS];
- for(CHANNELINDEX i = 0; i < MAX_BASECHANNELS; i++) {chnMask[i] = false;}
- chnMask[nChn] = TRUE;
- pModDoc->RemoveChannels(chnMask);
+ vector<bool> keepMask(pModDoc->GetNumChannels(), true);
+ keepMask[nChn] = false;
+ pModDoc->RemoveChannels(keepMask);
SetCurrentPattern(m_nPattern); //Updating the screen.
}
}
-void CViewPattern::OnAddChannelFront()
-//------------------------------------
+void CViewPattern::AddChannelBefore(CHANNELINDEX nBefore)
+//-------------------------------------------------------
{
- UINT nChn = GetChanFromCursor(m_nMenuParam);
CModDoc *pModDoc = GetDocument();
- CSoundFile* pSndFile;
- if (pModDoc == 0 || (pSndFile = pModDoc->GetSoundFile()) == 0) return;
+ if(pModDoc == nullptr) return;
BeginWaitCursor();
- //First adding channel as the last channel...
- if (pModDoc->ChangeNumChannels(pSndFile->m_nChannels + 1))
+ // Create new channel order, with channel nBefore being an invalid (and thus empty) channel.
+ vector<CHANNELINDEX> channels(pModDoc->GetNumChannels() + 1, CHANNELINDEX_INVALID);
+ CHANNELINDEX i = 0;
+ for(CHANNELINDEX nChn = 0; nChn < pModDoc->GetNumChannels() + 1; nChn++)
{
- pSndFile->InitChannel(pSndFile->m_nChannels-1);
- //...and then moving it to right position.
- pSndFile->MoveChannel(pSndFile->m_nChannels-1, nChn);
+ if(nChn != nBefore)
+ {
+ channels[nChn] = i++;
+ }
+ }
+ if (pModDoc->ReArrangeChannels(channels) != CHANNELINDEX_INVALID)
+ {
pModDoc->SetModified();
- pModDoc->GetPatternUndo()->ClearUndo();
pModDoc->UpdateAllViews(NULL, HINT_MODCHANNELS); //refresh channel headers
pModDoc->UpdateAllViews(NULL, HINT_MODTYPE); //updates(?) the channel number to general tab display
SetCurrentPattern(m_nPattern);
@@ -2735,70 +2737,45 @@
}
-void CViewPattern::OnAddChannelAfter()
-//------------------------------------
-{
- UINT nChn = ((m_nMenuParam&0xFFFF)>>3)+1;
- CModDoc *pModDoc = GetDocument();
- CSoundFile* pSndFile;
- if (pModDoc == 0 || (pSndFile = pModDoc->GetSoundFile()) == 0) return;
-
- BeginWaitCursor();
- if (pModDoc->ChangeNumChannels(pSndFile->m_nChannels + 1))
- {
- pSndFile->InitChannel(pSndFile->m_nChannels-1);
- pSndFile->MoveChannel(pSndFile->m_nChannels-1, nChn);
-
- pModDoc->SetModified();
- pModDoc->GetPatternUndo()->ClearUndo();
- pModDoc->UpdateAllViews(NULL, HINT_MODCHANNELS);
- pModDoc->UpdateAllViews(NULL, HINT_MODTYPE);
- SetCurrentPattern(m_nPattern);
- }
- EndWaitCursor();
-}
-
void CViewPattern::OnDuplicateChannel()
//------------------------------------
{
CModDoc *pModDoc = GetDocument();
- CSoundFile* pSndFile;
- if (pModDoc == 0 || (pSndFile = pModDoc->GetSoundFile()) == 0)
- return;
+ if (pModDoc == nullptr) return;
if(AfxMessageBox(GetStrI18N(_TEXT("This affects all patterns, proceed?")), MB_YESNO) != IDYES)
return;
const CHANNELINDEX nDupChn = GetChanFromCursor(m_nMenuParam);
- if(nDupChn >= pSndFile->GetNumChannels())
+ if(nDupChn >= pModDoc->GetNumChannels())
return;
- CHANNELINDEX nNumChnNew = pSndFile->GetNumChannels()+1;
- // Create vector {0, 1,..., n-1, n, n, n+1, n+2, ..., nNumChnNew-2), where n = nDupChn.
- vector<CHANNELINDEX> vecChns(nNumChnNew);
+ BeginWaitCursor();
+ // Create new channel order, with channel nDupChn duplicated.
+ vector<CHANNELINDEX> channels(pModDoc->GetNumChannels() + 1, 0);
CHANNELINDEX i = 0;
- for(i = 0; i<nDupChn+1; i++)
- vecChns[i] = i;
- vecChns[i] = nDupChn;
- i++;
- for(; i<nNumChnNew; i++)
- vecChns[i] = i-1;
+ for(CHANNELINDEX nChn = 0; nChn < pModDoc->GetNumChannels() + 1; nChn++)
+ {
+ channels[nChn] = i;
+ if(nChn != nDupChn)
+ {
+ i++;
+ }
+ }
- nNumChnNew = pSndFile->ReArrangeChannels(vecChns);
-
// Check that duplication happened and in that case update.
- if(nNumChnNew == vecChns.size())
+ if(pModDoc->ReArrangeChannels(channels) != CHANNELINDEX_INVALID)
{
pModDoc->SetModified();
pModDoc->UpdateAllViews(NULL, HINT_MODCHANNELS);
pModDoc->UpdateAllViews(NULL, HINT_MODTYPE);
SetCurrentPattern(m_nPattern);
}
-
+ EndWaitCursor();
}
void CViewPattern::OnRunScript()
-//--------------------------------
+//------------------------------
{
;
}
Modified: trunk/OpenMPT/mptrack/View_pat.h
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.h 2011-04-13 00:44:30 UTC (rev 850)
+++ trunk/OpenMPT/mptrack/View_pat.h 2011-04-13 13:44:49 UTC (rev 851)
@@ -315,8 +315,8 @@
afx_msg void OnTransposeOctUp();
afx_msg void OnTransposeOctDown();
afx_msg void OnSetSelInstrument();
- afx_msg void OnAddChannelFront();
- afx_msg void OnAddChannelAfter();
+ afx_msg void OnAddChannelFront() { AddChannelBefore(GetChanFromCursor(m_nMenuParam)); }
+ afx_msg void OnAddChannelAfter() { AddChannelBefore(GetChanFromCursor(m_nMenuParam) + 1); };
afx_msg void OnDuplicateChannel();
afx_msg void OnRemoveChannel();
afx_msg void OnRemoveChannelDialog();
@@ -406,6 +406,9 @@
// Play one pattern row and stop ("step mode")
void PatternStep(bool autoStep);
+ // Add a channel.
+ void AddChannelBefore(CHANNELINDEX nBefore);
+
public:
afx_msg void OnRButtonDblClk(UINT nFlags, CPoint point);
private:
Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.cpp 2011-04-13 00:44:30 UTC (rev 850)
+++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2011-04-13 13:44:49 UTC (rev 851)
@@ -570,7 +570,7 @@
wsprintf(label, "Channel %d", n + 1);
m_RemChansList.SetItemData(m_RemChansList.AddString(label), n);
- if (m_bChnMask[n]) m_RemChansList.SetSel(n);
+ if (!m_bKeepMask[n]) m_RemChansList.SetSel(n);
}
if (m_nRemove > 0) {
@@ -590,15 +590,15 @@
void CRemoveChannelsDlg::OnOK()
//-----------------------------
{
- memset(m_bChnMask, false, sizeof(m_bChnMask));
int nCount = m_RemChansList.GetSelCount();
CArray<int,int> aryListBoxSel;
aryListBoxSel.SetSize(nCount);
m_RemChansList.GetSelItems(nCount, aryListBoxSel.GetData());
- for (int n=0; n<nCount; n++)
+ m_bKeepMask.assign(m_nChannels, true);
+ for (int n = 0; n < nCount; n++)
{
- m_bChnMask[aryListBoxSel[n]] = true;
+ m_bKeepMask[aryListBoxSel[n]] = false;
}
if ((static_cast<UINT>(nCount) == m_nRemove && nCount > 0) || (m_nRemove == 0 && (m_pSndFile->GetNumChannels() >= nCount + m_pSndFile->GetModSpecifications().channelsMin)))
CDialog::OnOK();
Modified: trunk/OpenMPT/mptrack/dlg_misc.h
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.h 2011-04-13 00:44:30 UTC (rev 850)
+++ trunk/OpenMPT/mptrack/dlg_misc.h 2011-04-13 13:44:49 UTC (rev 851)
@@ -84,17 +84,17 @@
{
public:
CSoundFile *m_pSndFile;
- bool m_bChnMask[MAX_BASECHANNELS];
- UINT m_nChannels, m_nRemove;
+ vector<bool> m_bKeepMask;
+ CHANNELINDEX m_nChannels, m_nRemove;
CListBox m_RemChansList; //rewbs.removeChansDlgCleanup
bool m_ShowCancel;
public:
- CRemoveChannelsDlg(CSoundFile *pSndFile, UINT nChns, bool showCancel = true, CWnd *parent=NULL):CDialog(IDD_REMOVECHANNELS, parent)
+ CRemoveChannelsDlg(CSoundFile *pSndFile, CHANNELINDEX nChns, bool showCancel = true, CWnd *parent=NULL):CDialog(IDD_REMOVECHANNELS, parent)
{ m_pSndFile = pSndFile;
- m_nChannels = m_pSndFile->m_nChannels;
- m_nRemove = nChns;
- memset(m_bChnMask, false, sizeof(m_bChnMask));
+ m_nChannels = m_pSndFile->GetNumChannels();
+ m_nRemove = nChns;
+ m_bKeepMask.assign(m_nChannels, true);
m_ShowCancel = showCancel;
}
Modified: trunk/OpenMPT/mptrack/test/test.cpp
===================================================================
--- trunk/OpenMPT/mptrack/test/test.cpp 2011-04-13 00:44:30 UTC (rev 850)
+++ trunk/OpenMPT/mptrack/test/test.cpp 2011-04-13 13:44:49 UTC (rev 851)
@@ -239,16 +239,16 @@
CMainFrame* pMainFrm = CMainFrame::GetMainFrame();
if(pMainFrm == nullptr)
throw(std::runtime_error("pMainFrm is nullptr"));
- CModDoc* pModdoc = pMainFrm->GetActiveDoc();
- if(pModdoc == nullptr)
+ CModDoc* pModDoc = pMainFrm->GetActiveDoc();
+ if(pModDoc == nullptr)
throw(std::runtime_error("pModdoc is nullptr"));
- CSoundFile* pSndFile = pModdoc->GetSoundFile();
+ CSoundFile* pSndFile = pModDoc->GetSoundFile();
if(pSndFile == nullptr)
throw(std::runtime_error("pSndFile is nullptr"));
// Set maximum number of channels.
- pSndFile->ReArrangeChannels(std::vector<CHANNELINDEX>(ModSpecs::mptm.channelsMax , 0));
+ pModDoc->ReArrangeChannels(std::vector<CHANNELINDEX>(ModSpecs::mptm.channelsMax , 0));
pSndFile->Patterns.Remove(0);
pSndFile->Patterns.Insert(0, ModSpecs::mptm.patternRowsMin);
@@ -305,7 +305,7 @@
VERIFY_EQUAL( bPatternDataMatch, true);
}
- pModdoc->OnCloseDocument();
+ pModDoc->OnCloseDocument();
}
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2011-04-13 00:44:30 UTC (rev 850)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2011-04-13 13:44:49 UTC (rev 851)
@@ -1505,166 +1505,6 @@
}
-CHANNELINDEX CSoundFile::ReArrangeChannels(const vector<CHANNELINDEX>& newOrder)
-//------------------------------------------------------------------------------
-{
- //newOrder[i] tells which current channel should be placed to i:th position in
- //the new order, or if i is not an index of current channels, then new channel is
- //added to position i. If index of some current channel is missing from the
- //newOrder-vector, then the channel gets removed.
-
- const CHANNELINDEX nRemainingChannels = static_cast<CHANNELINDEX>(newOrder.size());
-
- if(nRemainingChannels > GetModSpecifications().channelsMax || nRemainingChannels < GetModSpecifications().channelsMin)
- {
- CString str;
- str.Format(GetStrI18N(_TEXT("Can't apply change: Number of channels should be within [%u,%u]")), GetModSpecifications().channelsMin, GetModSpecifications().channelsMax);
- CMainFrame::GetMainFrame()->MessageBox(str , "ReArrangeChannels", MB_OK | MB_ICONINFORMATION);
- return 0;
- }
-
- CModDoc *pModDoc = GetpModDoc();
- bool first = true;
- if(pModDoc != nullptr && nRemainingChannels != GetNumChannels())
- {
- // For now, changing number of channels can't be undone
- pModDoc->GetPatternUndo()->ClearUndo();
- }
-
- BEGIN_CRITICAL();
- for (PATTERNINDEX nPat = 0; nPat < Patterns.Size(); nPat++)
- {
- if (Patterns[nPat])
- {
- if(pModDoc != nullptr && nRemainingChannels == GetNumChannels())
- {
- pModDoc->GetPatternUndo()->PrepareUndo(nPat, 0, 0, GetNumChannels(), Patterns[nPat].GetNumRows(), !first);
- first = false;
- }
-
- MODCOMMAND *p = Patterns[nPat];
- MODCOMMAND *newp = CPattern::AllocatePattern(Patterns[nPat].GetNumRows(), nRemainingChannels);
- if (!newp)
- {
- END_CRITICAL();
- CMainFrame::GetMainFrame()->MessageBox("ERROR: Pattern allocation failed in ReArrangechannels(...)" , "ReArrangeChannels", MB_OK | MB_ICONINFORMATION);
- return 0;
- }
- MODCOMMAND *tmpsrc = p, *tmpdest = newp;
- for (ROWINDEX nRow = 0; nRow<Patterns[nPat].GetNumRows(); nRow++) //Scrolling rows
- {
- for (CHANNELINDEX nChn = 0; nChn < nRemainingChannels; nChn++, tmpdest++) //Scrolling channels.
- {
- if(newOrder[nChn] < m_nChannels) //Case: getting old channel to the new channel order.
- *tmpdest = tmpsrc[nRow*m_nChannels+newOrder[nChn]];
- else //Case: figure newOrder[k] is not the index of any current channel, so adding a new channel.
- *tmpdest = MODCOMMAND::Empty();
-
- }
- }
- Patterns[nPat] = newp;
- CPattern::FreePattern(p);
- }
- }
-
- MODCHANNELSETTINGS settings[MAX_BASECHANNELS];
- MODCHANNEL chns[MAX_BASECHANNELS];
- UINT recordStates[MAX_BASECHANNELS];
- bool chnMutePendings[MAX_BASECHANNELS];
-
- for(CHANNELINDEX nChn = 0; nChn < m_nChannels; nChn++)
- {
- settings[nChn] = ChnSettings[nChn];
- chns[nChn] = Chn[nChn];
- if(m_pModDoc)
- recordStates[nChn] = m_pModDoc->IsChannelRecord(nChn);
- chnMutePendings[nChn] = m_bChannelMuteTogglePending[nChn];
- }
-
- if(m_pModDoc)
- m_pModDoc->ReinitRecordState();
-
- for (CHANNELINDEX nChn = 0; nChn < nRemainingChannels; nChn++)
- {
- if(newOrder[nChn] < m_nChannels)
- {
- ChnSettings[nChn] = settings[newOrder[nChn]];
- Chn[nChn] = chns[newOrder[nChn]];
- if(m_pModDoc)
- {
- if(recordStates[newOrder[nChn]] == 1) m_pModDoc->Record1Channel(nChn, true);
- if(recordStates[newOrder[nChn]] == 2) m_pModDoc->Record2Channel(nChn, true);
- }
- m_bChannelMuteTogglePending[nChn] = chnMutePendings[newOrder[nChn]];
- }
- else
- {
- InitChannel(nChn);
- }
- }
- // Reset MOD panning (won't affect other module formats)
- SetupMODPanning();
-
- m_nChannels = nRemainingChannels;
-
- // Reset removed channels. Most notably, clear the channel name.
- for(CHANNELINDEX nChn = m_nChannels; nChn < MAX_BASECHANNELS; nChn++)
- {
- InitChannel(nChn);
- Chn[nChn].dwFlags |= CHN_MUTE;
- }
-
- END_CRITICAL();
-
- return static_cast<CHANNELINDEX>(m_nChannels);
-}
-
-bool CSoundFile::MoveChannel(UINT chnFrom, UINT chnTo)
-//----------------------------------------------------
-{
- //Implementation of move channel using ReArrangeChannels(...). So this function
- //only creates correct newOrder-vector used in the ReArrangeChannels(...).
- if(chnFrom == chnTo) return false;
- if(chnFrom >= m_nChannels || chnTo >= m_nChannels)
- {
- CString str = "Error: Bad move indexes in CSoundFile::MoveChannel(...)";
- CMainFrame::GetMainFrame()->MessageBox(str , "MoveChannel(...)", MB_OK | MB_ICONINFORMATION);
- return true;
- }
- vector<CHANNELINDEX> newOrder;
- //First creating new order identical to current order...
- for(CHANNELINDEX i = 0; i<GetNumChannels(); i++)
- {
- newOrder.push_back(i);
- }
- //...and then add the move channel effect.
- if(chnFrom < chnTo)
- {
- CHANNELINDEX temp = newOrder[chnFrom];
- for(UINT i = chnFrom; i<chnTo; i++)
- {
- newOrder[i] = newOrder[i+1];
- }
- newOrder[chnTo] = temp;
- }
- else //case chnFrom > chnTo(can't be equal, since it has been examined earlier.)
- {
- CHANNELINDEX temp = newOrder[chnFrom];
- for(UINT i = chnFrom; i>=chnTo+1; i--)
- {
- newOrder[i] = newOrder[i-1];
- }
- newOrder[chnTo] = temp;
- }
-
- if(newOrder.size() != ReArrangeChannels(newOrder))
- {
- CMainFrame::GetMainFrame()->MessageBox("BUG: Channel number changed in MoveChannel()" , "", MB_OK | MB_ICONINFORMATION);
- }
- return false;
-}
-
-
#ifndef NO_PACKING
UINT CSoundFile::PackSample(int &sample, int next)
//------------------------------------------------
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2011-04-13 00:44:30 UTC (rev 850)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2011-04-13 13:44:49 UTC (rev 851)
@@ -740,8 +740,6 @@
void CheckCPUUsage(UINT nCPU);
BOOL SetPatternName(PATTERNINDEX nPat, LPCSTR lpszName);
BOOL GetPatternName(PATTERNINDEX nPat, LPSTR lpszName, UINT cbSize=MAX_PATTERNNAME) const;
- CHANNELINDEX ReArrangeChannels(const vector<CHANNELINDEX>& fromToArray);
- bool MoveChannel(UINT chn_from, UINT chn_to);
void SetupITBidiMode();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-13 00:44:36
|
Revision: 850
http://modplug.svn.sourceforge.net/modplug/?rev=850&view=rev
Author: saga-games
Date: 2011-04-13 00:44:30 +0000 (Wed, 13 Apr 2011)
Log Message:
-----------
[Fix] Reverted an unintended behaviour change introduced in rev.848
Modified Paths:
--------------
trunk/OpenMPT/mptrack/View_pat.cpp
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2011-04-12 23:03:37 UTC (rev 849)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2011-04-13 00:44:30 UTC (rev 850)
@@ -1026,11 +1026,10 @@
CModDoc *pModDoc = GetDocument();
if (/*(m_bDragging) ||*/ (pModDoc == nullptr) || (pModDoc->GetSoundFile() == nullptr)) return;
SetFocus();
- m_nDragItem = GetDragItem(point, &m_rcDragItem);
+ m_nDropItem = m_nDragItem = GetDragItem(point, &m_rcDragItem);
m_bDragging = true;
m_bInItemRect = true;
m_bShiftDragging = false;
- m_nDropItem = 0;
SetCapture();
if ((point.x >= m_szHeader.cx) && (point.y <= m_szHeader.cy))
@@ -1165,8 +1164,8 @@
}
if ((!bItemSelected) || (!m_nDragItem)) return;
InvalidateRect(&m_rcDragItem, FALSE);
- const DWORD nItemNo = (m_nDragItem & DRAGITEM_VALUEMASK);
- const DWORD nTargetNo = (m_nDropItem != 0) ? (m_nDropItem & DRAGITEM_VALUEMASK) : nItemNo;
+ const CHANNELINDEX nItemNo = (m_nDragItem & DRAGITEM_VALUEMASK);
+ const CHANNELINDEX nTargetNo = (m_nDropItem != 0) ? (m_nDropItem & DRAGITEM_VALUEMASK) : CHANNELINDEX_INVALID;
switch(m_nDragItem & DRAGITEM_MASK)
{
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-12 23:03:47
|
Revision: 849
http://modplug.svn.sourceforge.net/modplug/?rev=849&view=rev
Author: saga-games
Date: 2011-04-12 23:03:37 +0000 (Tue, 12 Apr 2011)
Log Message:
-----------
[Mod] Improved DMF loader a bit more.
[Mod] Updated History.txt
Modified Paths:
--------------
trunk/OpenMPT/packageTemplate/History.txt
trunk/OpenMPT/soundlib/LOAD_DMF.CPP
Modified: trunk/OpenMPT/packageTemplate/History.txt
===================================================================
--- trunk/OpenMPT/packageTemplate/History.txt 2011-04-12 21:46:10 UTC (rev 848)
+++ trunk/OpenMPT/packageTemplate/History.txt 2011-04-12 23:03:37 UTC (rev 849)
@@ -10,6 +10,32 @@
(tx XYZ): thanks to XYZ for telling us about the bug / requesting the feature
+v1.19.02.00 (***** 2011, revision 848)
+--------------------------------------
+Pattern tab::Note properties
+ [New] <Jojo> Channels can now be moved by dragging their channel header. Holding Shift while doing so duplicates the channel
+ [Imp] <Jojo> Moving channels through the channel manager creates an undo point now.
+ [Fix] <Jojo> Axx is not limited to value 7F anymore in IT / S3M format.
+
+VST
+ [New] <Jojo> New menu entry in the plugin editor: Create instrument from plugin
+ [Fix] <Jojo> Fixed note handling in VST editor of plugins that actually don't support MIDI input (http://bugs.openmpt.org/view.php?id=102)
+
+Mod Conversion
+ [Imp] <Jojo> Improved conversion of Sxx (IT / S3M) and PC Notes.
+ [Fix] <Jojo> Sustain loop conversion didn't work
+
+IT
+ [Fix] <Jojo> Panning slides with both parameter nibbles set were not ignored in compatible mode.
+
+Other modules
+ [Imp] <Jojo> DMF Loader was rewritten completely and is a whole lot more accurate now.
+ [Fix] <Jojo> J2B Loader: Empty sample slots are now treated correct in new J2B (AM) files.
+
+Misc
+ [New] <Jojo> OpenMPT can now automatically check for updates (daily / weekly / monthly)
+ [Reg] <Jojo> Removed hidden INI flag to suppress warnings when encountering keymaps with unknown items. This option was introduced when faulty keymaps threw multiple message boxes, but now it's just one and it shouldn't be ignored...
+
v1.19.01.00 (April 2011, revision 836)
--------------------------------------
Pattern tab
@@ -33,7 +59,7 @@
[Reg] <Jojo> The "Position aware timer" option is gone. The position aware timer is now automatically used. It was optional in the first place because of some buggy code, which is now fixed.
Pattern tab::Note properties
- [Fix] <Jojo> The meaning of Q0x was displayed wrong for S3M / IT.
+ [Fix] <Jojo> The meaning of Q0x was displayed wrong for IT / S3M.
[Fix] <Jojo> Changing a value didn't create an undo point. (http://bugs.openmpt.org/view.php?id=56)
[Fix] <Jojo> Setting the PC note plugin didn't work.
@@ -71,7 +97,6 @@
VST
[New] <Jojo> Plugins can now request common file dialogs (file and directory selection).
- [New] <Jojo> New menu entry in the plugin editor: Create instrument from plugin
[Mod] <Jojo> When automatically inserting a new instrument from the VST editor, the bank and patch values are now not filled in anymore, so it is easier to change to another patch while editing.
[Mod] <Jojo> Various small improvements to support VST 2.4 plugins better.
[Fix] <Jojo> Speaker arrangement is now sent to the plugins upon initialization. This fixes Voxengo SPAN 2 (a VST 2.4 plugin). Does this break other multichannel plugins?
Modified: trunk/OpenMPT/soundlib/LOAD_DMF.CPP
===================================================================
--- trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2011-04-12 21:46:10 UTC (rev 848)
+++ trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2011-04-12 23:03:37 UTC (rev 849)
@@ -28,6 +28,7 @@
#define DMF_SMPD 0x44504D53
#define DMF_SMPJ 0x4A504D53
#define DMF_ENDE 0x45444E45
+#define DMF_SETT 0x9C219DE4
// Pattern flags - global track
#define DMFPAT_GLOBPACK 0x80 // Pack information for global track follows
@@ -150,7 +151,7 @@
val = max(1, val / 4);
const bool isFine = (val < 0x0F) || (internalTicks < 2);
if(!isFine)
- val = max(1, (val + 3) / (internalTicks - 1)); // no slides on first tick! +3 for rounding precision
+ val = max(1, (val + internalTicks - 2) / (internalTicks - 1)); // no slides on first tick! "+ internalTicks - 2" for rounding precision
if(up)
return (isFine ? 0x0F : 0x00) | (val << 4);
@@ -176,8 +177,9 @@
uint8 DMFdelay2MPT(uint8 val, const uint8 internalTicks)
//------------------------------------------------------
{
- const int newval = (int)val * (int)internalTicks / 255;
- return (uint8)CLAMP(newval, 0, 0x0F);
+ int newval = (int)val * (int)internalTicks / 255;
+ Limit(newval, 0, 15);
+ return (uint8)newval;
}
@@ -351,7 +353,7 @@
break;
}
}
- tempo = CLAMP(tempo, 32, 255);
+ Limit(tempo, 32, 255);
settings.internalTicks = (uint8)speed;
} else
{
@@ -359,7 +361,7 @@
}
}
- MODCOMMAND *m = pSndFile->Patterns[nPat].GetpModCommand(nRow, 1); // Reserve first channel for global effects
+ m = pSndFile->Patterns[nPat].GetpModCommand(nRow, 1); // Reserve first channel for global effects
for(CHANNELINDEX nChn = 1; nChn <= numChannels; nChn++, m++)
{
@@ -368,6 +370,7 @@
{
ASSERT_CAN_READ_PATTERN(1);
const uint8 channelInfo = lpStream[dwMemPos++];
+ ////////////////////////////////////////////////////////////////
// 0x80: Packing counter (if not present, counter stays at 0)
if((channelInfo & DMFPAT_COUNTER) != 0)
{
@@ -375,6 +378,7 @@
channelCounter[nChn] = lpStream[dwMemPos++];
}
+ ////////////////////////////////////////////////////////////////
// 0x40: Instrument
bool slideNote = true; // If there is no instrument number next to a note, the note is not retriggered!
if((channelInfo & DMFPAT_INSTR) != 0)
@@ -387,6 +391,7 @@
}
}
+ ////////////////////////////////////////////////////////////////
// 0x20: Note
if((channelInfo & DMFPAT_NOTE) != 0)
{
@@ -394,12 +399,13 @@
m->note = lpStream[dwMemPos++];
if(m->note >= 1 && m->note <= 108)
{
- m->note += 24;
+ m->note = CLAMP(m->note + 24, NOTE_MIN, NOTE_MAX);
settings.lastNote[nChn] = m->note;
} else if(m->note >= 129 && m->note <= 236)
{
// "Buffer notes" for portamento (and other effects?) that are actually not played, but just "queued"...
- settings.noteBuffer[nChn] = (m->note & 0x7F) + 24;
+ m->note = CLAMP((m->note & 0x7F) + 24, NOTE_MIN, NOTE_MAX);
+ settings.noteBuffer[nChn] = m->note;
m->note = NOTE_NONE;
} else if(m->note == 255)
{
@@ -422,6 +428,7 @@
uint8 effect1 = CMD_NONE, effect2 = CMD_NONE, effect3 = CMD_NONE;
uint8 effectParam1 = 0, effectParam2 = 0, effectParam3 = 0;
+ ////////////////////////////////////////////////////////////////
// 0x10: Volume
if((channelInfo & DMFPAT_VOLUME) != 0)
{
@@ -430,6 +437,7 @@
m->vol = (lpStream[dwMemPos++] + 3) / 4;
}
+ ////////////////////////////////////////////////////////////////
// 0x08: Instrument effect
if((channelInfo & DMFPAT_INSEFF) != 0)
{
@@ -499,6 +507,7 @@
}
}
+ ////////////////////////////////////////////////////////////////
// 0x04: Note effect
if((channelInfo & DMFPAT_NOTEEFF) != 0)
{
@@ -541,7 +550,7 @@
effect2 = CMD_TONEPORTAMENTO;
break;
case 7: // Scratch to Note (neat! but we don't have such an effect...)
- m->note = effectParam2 + 25;
+ m->note = CLAMP(effectParam2 + 25, NOTE_MIN, NOTE_MAX);
effect2 = CMD_TONEPORTAMENTO;
effectParam2 = 0xFF;
break;
@@ -578,6 +587,7 @@
}
}
+ ////////////////////////////////////////////////////////////////
// 0x02: Volume effect
if((channelInfo & DMFPAT_VOLEFF) != 0)
{
@@ -957,16 +967,16 @@
break;
case DMF_SMPJ: // "SMPJ" - Sample jump points (xtracker32 only)
+ case DMF_SETT: // "Unprintable ID" - those might be GUI settings and other related stuff
break;
-#if 0
+#ifdef DEBUG
default:
- // There is some (encrypted?) IFF chunk with a very weird ID at the end of many DMF files. What does it mean?
{
- char s[32];
+ char s[40];
const char *sig = (char *)&chunkheader.signature;
- wsprintf(s, "Unknown chunk ID %c%c%c%c at %d", sig[0], sig[1], sig[2], sig[3], dwMemPos - sizeof(DMF_IFFCHUNK));
- MessageBox(0, s, 0, 0);
+ wsprintf(s, "Unknown chunk ID %c%c%c%c at %d\n", sig[0], sig[1], sig[2], sig[3], dwMemPos - sizeof(DMF_IFFCHUNK));
+ if(GetpModDoc()) GetpModDoc()->AddToLog(s);
}
#endif
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-12 21:46:17
|
Revision: 848
http://modplug.svn.sourceforge.net/modplug/?rev=848&view=rev
Author: saga-games
Date: 2011-04-12 21:46:10 +0000 (Tue, 12 Apr 2011)
Log Message:
-----------
[New] The channel headers can now be dragged around to move channels. Holding shift while dragging duplicates the channel.
[Imp] Moving channels can now be undone.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Draw_pat.cpp
trunk/OpenMPT/mptrack/MainFrm.cpp
trunk/OpenMPT/mptrack/Mainfrm.h
trunk/OpenMPT/mptrack/View_pat.cpp
trunk/OpenMPT/mptrack/View_pat.h
trunk/OpenMPT/soundlib/Sndfile.cpp
Modified: trunk/OpenMPT/mptrack/Draw_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Draw_pat.cpp 2011-04-11 19:53:15 UTC (rev 847)
+++ trunk/OpenMPT/mptrack/Draw_pat.cpp 2011-04-12 21:46:10 UTC (rev 848)
@@ -314,7 +314,7 @@
//---------------------------------------------------------------------------
{
PCPATTERNFONT pfnt = GetCurrentPatternFont();
-
+
UINT xsrc = pfnt->nNoteX, ysrc = pfnt->nNoteY, dx = pfnt->nEltWidths[0];
if (!note)
{
@@ -471,6 +471,7 @@
rect.right = m_szHeader.cx;
DrawButtonRect(hdc, &rect, s, FALSE,
((m_bInItemRect) && ((m_nDragItem & DRAGITEM_MASK) == DRAGITEM_PATTERNHEADER)) ? TRUE : FALSE);
+
// Drawing Channel Headers
while (xpaint < rcClient.right)
{
@@ -482,7 +483,7 @@
const char *pszfmt = pSndFile->m_bChannelMuteTogglePending[ncolhdr]? "[Channel %d]" : "Channel %d";
// const char *pszfmt = pModDoc->IsChannelRecord(ncolhdr) ? "Channel %d " : "Channel %d";
// -! NEW_FEATURE#0012
- if ((pSndFile->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)) && ((BYTE)pSndFile->ChnSettings[ncolhdr].szName[0] >= 0x20))
+ if ((pSndFile->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)) && ((BYTE)pSndFile->ChnSettings[ncolhdr].szName[0] >= ' '))
pszfmt = pSndFile->m_bChannelMuteTogglePending[ncolhdr]?"%d: [%s]":"%d: %s";
else if (m_nDetailLevel < 2) pszfmt = pSndFile->m_bChannelMuteTogglePending[ncolhdr]?"[Ch%d]":"Ch%d";
else if (m_nDetailLevel < 3) pszfmt = pSndFile->m_bChannelMuteTogglePending[ncolhdr]?"[Chn %d]":"Chn %d";
@@ -491,12 +492,28 @@
// -> DESC="midi keyboard split"
// DrawButtonRect(hdc, &rect, s,
// (pSndFile->ChnSettings[ncolhdr].dwFlags & CHN_MUTE) ? TRUE : FALSE,
-// ((m_bInItemRect) && ((m_nDragItem & DRAGITEM_MASK) == DRAGITEM_CHNHEADER) && ((m_nDragItem & 0xFFFF) == ncolhdr)) ? TRUE : FALSE, DT_CENTER);
+// ((m_bInItemRect) && ((m_nDragItem & DRAGITEM_MASK) == DRAGITEM_CHNHEADER) && ((m_nDragItem & DRAGITEM_VALUEMASK) == ncolhdr)) ? TRUE : FALSE, DT_CENTER);
// rect.bottom = rect.top + COLHDR_HEIGHT;
DrawButtonRect(hdc, &rect, s,
(pSndFile->ChnSettings[ncolhdr].dwFlags & CHN_MUTE) ? TRUE : FALSE,
- ((m_bInItemRect) && ((m_nDragItem & DRAGITEM_MASK) == DRAGITEM_CHNHEADER) && ((m_nDragItem & 0xFFFF) == ncolhdr)) ? TRUE : FALSE,
+ ((m_bInItemRect) && ((m_nDragItem & DRAGITEM_MASK) == DRAGITEM_CHNHEADER) && ((m_nDragItem & DRAGITEM_VALUEMASK) == ncolhdr)) ? TRUE : FALSE,
pModDoc->IsChannelRecord(ncolhdr) ? DT_RIGHT : DT_CENTER);
+
+ // When dragging around channel headers, mark insertion position
+ if(m_bDragging && !m_bInItemRect
+ && (m_nDragItem & DRAGITEM_MASK) == DRAGITEM_CHNHEADER
+ && (m_nDropItem & DRAGITEM_MASK) == DRAGITEM_CHNHEADER
+ && (m_nDropItem & DRAGITEM_VALUEMASK) == ncolhdr)
+ {
+ RECT r;
+ r.top = rect.top;
+ r.bottom = rect.bottom;
+ // Drop position depends on whether hovered channel is left or right of dragged item.
+ r.left = ((m_nDropItem & DRAGITEM_VALUEMASK) < (m_nDragItem & DRAGITEM_VALUEMASK) || m_bShiftDragging) ? rect.left : rect.right - 3;
+ r.right = r.left + 2;
+ ::FillRect(hdc, &r, CMainFrame::brushText);
+ }
+
rect.bottom = rect.top + COLHDR_HEIGHT;
CRect insRect;
@@ -543,8 +560,9 @@
wsprintf(s, "---");
}
DrawButtonRect(hdc, &rect, s, FALSE,
- ((m_bInItemRect) && ((m_nDragItem & DRAGITEM_MASK) == DRAGITEM_PLUGNAME) && ((m_nDragItem & 0xFFFF) == ncolhdr)) ? TRUE : FALSE, DT_CENTER);
+ ((m_bInItemRect) && ((m_nDragItem & DRAGITEM_MASK) == DRAGITEM_PLUGNAME) && ((m_nDragItem & DRAGITEM_VALUEMASK) == ncolhdr)) ? TRUE : FALSE, DT_CENTER);
}
+
} else break;
ncolhdr++;
xpaint += nColumnWidth;
Modified: trunk/OpenMPT/mptrack/MainFrm.cpp
===================================================================
--- trunk/OpenMPT/mptrack/MainFrm.cpp 2011-04-11 19:53:15 UTC (rev 847)
+++ trunk/OpenMPT/mptrack/MainFrm.cpp 2011-04-12 21:46:10 UTC (rev 848)
@@ -229,6 +229,7 @@
HBRUSH CMainFrame::brushGray = NULL;
HBRUSH CMainFrame::brushBlack = NULL;
HBRUSH CMainFrame::brushWhite = NULL;
+HBRUSH CMainFrame::brushText = NULL;
//CBrush *CMainFrame::pbrushBlack = NULL;//rewbs.envRowGrid
//CBrush *CMainFrame::pbrushWhite = NULL;//rewbs.envRowGrid
@@ -809,6 +810,7 @@
if (m_hGUIFont == NULL) m_hGUIFont = (HFONT)GetStockObject(ANSI_VAR_FONT);
brushBlack = (HBRUSH)::GetStockObject(BLACK_BRUSH);
brushWhite = (HBRUSH)::GetStockObject(WHITE_BRUSH);
+ brushText = ::CreateSolidBrush(GetSysColor(COLOR_BTNTEXT));
brushGray = ::CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
penLightGray = ::CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNHIGHLIGHT));
penDarkGray = ::CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW));
Modified: trunk/OpenMPT/mptrack/Mainfrm.h
===================================================================
--- trunk/OpenMPT/mptrack/Mainfrm.h 2011-04-11 19:53:15 UTC (rev 847)
+++ trunk/OpenMPT/mptrack/Mainfrm.h 2011-04-12 21:46:10 UTC (rev 848)
@@ -442,7 +442,7 @@
// GDI
static HICON m_hIcon;
static HFONT m_hGUIFont, m_hFixedFont, m_hLargeFixedFont;
- static HBRUSH brushGray, brushBlack, brushWhite, brushHighLight, brushHighLightRed, brushWindow, brushYellow;
+ static HBRUSH brushGray, brushBlack, brushWhite, brushText, brushHighLight, brushHighLightRed, brushWindow, brushYellow;
// static CBrush *pbrushBlack, *pbrushWhite;
static HPEN penBlack, penDarkGray, penLightGray, penWhite, penHalfDarkGray, penSample, penEnvelope, penEnvelopeHighlight, penSeparator, penScratch, penGray00, penGray33, penGray40, penGray55, penGray80, penGray99, penGraycc, penGrayff;
static HCURSOR curDragging, curNoDrop, curArrow, curNoDrop2, curVSplit;
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2011-04-11 19:53:15 UTC (rev 847)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2011-04-12 21:46:10 UTC (rev 848)
@@ -471,7 +471,7 @@
GetClientRect(&rcClient);
xofs = GetXScrollPos();
yofs = GetYScrollPos();
- rect.SetRect(m_szHeader.cx, 0, m_szHeader.cx + GetColumnWidth() - 2, m_szHeader.cy);
+ rect.SetRect(m_szHeader.cx, 0, m_szHeader.cx + GetColumnWidth() /*- 2*/, m_szHeader.cy);
plugRect.SetRect(m_szHeader.cx, m_szHeader.cy-PLUGNAME_HEIGHT, m_szHeader.cx + GetColumnWidth() - 2, m_szHeader.cy); //rewbs.patPlugNames
pSndFile = pModDoc->GetSoundFile();
const UINT nmax = pSndFile->GetNumChannels();
@@ -1029,6 +1029,9 @@
m_nDragItem = GetDragItem(point, &m_rcDragItem);
m_bDragging = true;
m_bInItemRect = true;
+ m_bShiftDragging = false;
+ m_nDropItem = 0;
+
SetCapture();
if ((point.x >= m_szHeader.cx) && (point.y <= m_szHeader.cy))
{
@@ -1121,8 +1124,12 @@
//-------------------------------------------------------
{
CModDoc *pModDoc = GetDocument();
- const bool bItemSelected = m_bInItemRect;
+
+ const bool bItemSelected = m_bInItemRect || ((m_nDragItem & DRAGITEM_MASK) == DRAGITEM_CHNHEADER);
if (/*(!m_bDragging) ||*/ (!pModDoc)) return;
+
+ CSoundFile *pSndFile = pModDoc->GetSoundFile();
+
m_bDragging = false;
m_bInItemRect = false;
ReleaseCapture();
@@ -1158,31 +1165,82 @@
}
if ((!bItemSelected) || (!m_nDragItem)) return;
InvalidateRect(&m_rcDragItem, FALSE);
- DWORD nItemNo = m_nDragItem & 0xFFFF;
+ const DWORD nItemNo = (m_nDragItem & DRAGITEM_VALUEMASK);
+ const DWORD nTargetNo = (m_nDropItem != 0) ? (m_nDropItem & DRAGITEM_VALUEMASK) : nItemNo;
+
switch(m_nDragItem & DRAGITEM_MASK)
{
case DRAGITEM_CHNHEADER:
- if (nFlags & MK_SHIFT) {
- if (nItemNo < MAX_CHANNELS) {
- pModDoc->Record1Channel(nItemNo);
- InvalidateChannelsHeaders();
+ if(nItemNo == nTargetNo)
+ {
+ // Just clicked a channel header...
+
+ if (nFlags & MK_SHIFT)
+ {
+ if (nItemNo < MAX_BASECHANNELS)
+ {
+ pModDoc->Record1Channel(nItemNo);
+ InvalidateChannelsHeaders();
+ }
}
- }
- else if (!(nFlags&MK_CONTROL))
+ else if (!(nFlags & MK_CONTROL))
+ {
+ pModDoc->MuteChannel(nItemNo, !pModDoc->IsChannelMuted(nItemNo));
+ pModDoc->UpdateAllViews(this, HINT_MODCHANNELS | ((nItemNo / CHANNELS_IN_TAB) << HINT_SHIFT_CHNTAB));
+ }
+ } else if(nTargetNo < pSndFile->GetNumChannels())
{
- pModDoc->MuteChannel(nItemNo, !pModDoc->IsChannelMuted(nItemNo));
- pModDoc->UpdateAllViews(this, HINT_MODCHANNELS | ((nItemNo / CHANNELS_IN_TAB) << HINT_SHIFT_CHNTAB));
+ // Dragged to other channel header => move or copy channel
+
+ InvalidateRect(&m_rcDropItem, FALSE);
+
+ const bool duplicate = (nFlags & MK_SHIFT) ? true : false;
+ vector<CHANNELINDEX> channels(pSndFile->GetNumChannels() + (duplicate ? 1 : 0), 0);
+ CHANNELINDEX i = 0;
+ bool modified = duplicate;
+
+ for(CHANNELINDEX nChn = 0; nChn < pSndFile->GetNumChannels(); nChn++)
+ {
+ if(nChn == nTargetNo)
+ {
+ channels[nChn] = nItemNo;
+ }
+ else
+ {
+ if(i == nItemNo && !duplicate) // Don't want that source channel twice if we're just moving
+ {
+ i++;
+ }
+ channels[nChn] = i++;
+ }
+ if(channels[nChn] != nChn)
+ {
+ modified = true;
+ }
+ }
+ if(modified && pSndFile->ReArrangeChannels(channels) != 0)
+ {
+ if(duplicate)
+ {
+ pModDoc->UpdateAllViews(this, HINT_MODCHANNELS);
+ pModDoc->UpdateAllViews(this, HINT_MODTYPE);
+ SetCurrentPattern(m_nPattern);
+ }
+ InvalidatePattern();
+ pModDoc->SetModified();
+ }
}
break;
case DRAGITEM_PATTERNHEADER:
OnPatternProperties();
break;
case DRAGITEM_PLUGNAME: //rewbs.patPlugNames
- if (nItemNo < MAX_CHANNELS) {
+ if (nItemNo < MAX_BASECHANNELS)
TogglePluginEditor(nItemNo);
- }
break;
}
+
+ m_nDropItem = 0;
}
@@ -1319,15 +1377,18 @@
//CSoundFile *pSndFile = pModDoc->GetSoundFile();
m_nDragItem = GetDragItem(point, &m_rcDragItem);
- DWORD nItemNo = m_nDragItem & 0xFFFF;
- switch(m_nDragItem & DRAGITEM_MASK) {
- case DRAGITEM_CHNHEADER:
- if (nFlags & MK_SHIFT) {
- if (nItemNo < MAX_CHANNELS) {
- pModDoc->Record2Channel(nItemNo);
- InvalidateChannelsHeaders();
- }
+ DWORD nItemNo = m_nDragItem & DRAGITEM_VALUEMASK;
+ switch(m_nDragItem & DRAGITEM_MASK)
+ {
+ case DRAGITEM_CHNHEADER:
+ if (nFlags & MK_SHIFT)
+ {
+ if (nItemNo < MAX_BASECHANNELS)
+ {
+ pModDoc->Record2Channel(nItemNo);
+ InvalidateChannelsHeaders();
}
+ }
break;
}
@@ -1335,21 +1396,35 @@
}
-void CViewPattern::OnMouseMove(UINT, CPoint point)
-//------------------------------------------------
+void CViewPattern::OnMouseMove(UINT nFlags, CPoint point)
+//-------------------------------------------------------
{
if (!m_bDragging) return;
+
if (m_nDragItem)
{
- DWORD nItem = GetDragItem(point, NULL);
- bool b = (nItem == m_nDragItem) ? true : false;
- if (b != m_bInItemRect)
+ const CRect oldDropRect = m_rcDropItem;
+ const DWORD oldDropItem = m_nDropItem;
+
+ m_bShiftDragging = (nFlags & MK_SHIFT) ? true : false;
+ m_nDropItem = GetDragItem(point, &m_rcDropItem);
+
+ const bool b = (m_nDropItem == m_nDragItem) ? true : false;
+ const bool dragChannel = (m_nDragItem & DRAGITEM_MASK) == DRAGITEM_CHNHEADER;
+
+ if (b != m_bInItemRect || (m_nDropItem != oldDropItem && dragChannel))
{
m_bInItemRect = b;
InvalidateRect(&m_rcDragItem, FALSE);
+
+ // Dragging around channel headers? Update move indicator...
+ if((m_nDropItem & DRAGITEM_MASK) == DRAGITEM_CHNHEADER) InvalidateRect(&m_rcDropItem, FALSE);
+ if((oldDropItem & DRAGITEM_MASK) == DRAGITEM_CHNHEADER) InvalidateRect(&oldDropRect, FALSE);
+
UpdateWindow();
}
}
+
if ((m_dwStatus & PATSTATUS_SELECTROW) /*&& (point.x < m_szHeader.cx)*/ && (point.y > m_szHeader.cy))
{
// Mark row number => mark whole row (continue)
@@ -2716,7 +2791,6 @@
if(nNumChnNew == vecChns.size())
{
pModDoc->SetModified();
- pModDoc->GetPatternUndo()->ClearUndo();
pModDoc->UpdateAllViews(NULL, HINT_MODCHANNELS);
pModDoc->UpdateAllViews(NULL, HINT_MODTYPE);
SetCurrentPattern(m_nPattern);
Modified: trunk/OpenMPT/mptrack/View_pat.h
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.h 2011-04-11 19:53:15 UTC (rev 847)
+++ trunk/OpenMPT/mptrack/View_pat.h 2011-04-12 21:46:10 UTC (rev 848)
@@ -9,6 +9,7 @@
class COpenGLEditor;
// Drag & Drop info
+#define DRAGITEM_VALUEMASK 0x00FFFF
#define DRAGITEM_MASK 0xFF0000
#define DRAGITEM_CHNHEADER 0x010000
#define DRAGITEM_PATTERNHEADER 0x020000
@@ -102,9 +103,14 @@
UINT m_nPattern, m_nRow, m_nMidRow, m_nPlayPat, m_nPlayRow, m_nSpacing, m_nAccelChar, m_nLastPlayedRow, m_nLastPlayedOrder;
int m_nXScroll, m_nYScroll;
- DWORD m_nDragItem, m_nMenuParam, m_nDetailLevel;
- bool m_bDragging, m_bInItemRect, m_bContinueSearch, m_bWholePatternFitsOnScreen;
- RECT m_rcDragItem;
+ DWORD m_nMenuParam, m_nDetailLevel;
+
+ DWORD m_nDragItem; // Currently dragged item
+ DWORD m_nDropItem; // Currently hovered item during dragondrop
+ bool m_bDragging, m_bInItemRect, m_bShiftDragging;
+ RECT m_rcDragItem, m_rcDropItem;
+
+ bool m_bContinueSearch, m_bWholePatternFitsOnScreen;
DWORD m_dwStatus, m_dwCursor;
DWORD m_dwBeginSel, m_dwEndSel; // Upper-left / Lower-right corners of selection
DWORD m_dwStartSel, m_dwDragPos; // Point where selection was started
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2011-04-11 19:53:15 UTC (rev 847)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2011-04-12 21:46:10 UTC (rev 848)
@@ -1523,11 +1523,25 @@
return 0;
}
+ CModDoc *pModDoc = GetpModDoc();
+ bool first = true;
+ if(pModDoc != nullptr && nRemainingChannels != GetNumChannels())
+ {
+ // For now, changing number of channels can't be undone
+ pModDoc->GetPatternUndo()->ClearUndo();
+ }
+
BEGIN_CRITICAL();
for (PATTERNINDEX nPat = 0; nPat < Patterns.Size(); nPat++)
{
if (Patterns[nPat])
{
+ if(pModDoc != nullptr && nRemainingChannels == GetNumChannels())
+ {
+ pModDoc->GetPatternUndo()->PrepareUndo(nPat, 0, 0, GetNumChannels(), Patterns[nPat].GetNumRows(), !first);
+ first = false;
+ }
+
MODCOMMAND *p = Patterns[nPat];
MODCOMMAND *newp = CPattern::AllocatePattern(Patterns[nPat].GetNumRows(), nRemainingChannels);
if (!newp)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-11 19:53:21
|
Revision: 847
http://modplug.svn.sourceforge.net/modplug/?rev=847&view=rev
Author: saga-games
Date: 2011-04-11 19:53:15 +0000 (Mon, 11 Apr 2011)
Log Message:
-----------
This was supposed to be commited as well.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Sndfile.cpp
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2011-04-11 19:50:20 UTC (rev 846)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2011-04-11 19:53:15 UTC (rev 847)
@@ -66,7 +66,7 @@
// External decompressors
extern void AMSUnpack(const char *psrc, UINT inputlen, char *pdest, UINT dmax, char packcharacter);
extern WORD MDLReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n);
-extern int DMFUnpack(LPBYTE psample, LPBYTE ibuf, LPBYTE ibufmax, UINT maxlen);
+extern int DMFUnpack(LPBYTE psample, uint8 *ibuf, uint8 *ibufmax, UINT maxlen);
extern DWORD ITReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n);
extern void ITUnpack8Bit(LPSTR pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215);
extern void ITUnpack16Bit(LPSTR pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215);
@@ -2288,7 +2288,7 @@
{
UINT maxlen = pSmp->nLength;
if (pSmp->uFlags & CHN_16BIT) maxlen <<= 1;
- LPBYTE ibuf = (LPBYTE)lpMemFile, ibufmax = (LPBYTE)(lpMemFile+dwMemLength);
+ uint8 *ibuf = (uint8 *)lpMemFile, *ibufmax = (uint8 *)(lpMemFile + dwMemLength);
len = DMFUnpack((LPBYTE)pSmp->pSample, ibuf, ibufmax, maxlen);
}
break;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-11 19:50:27
|
Revision: 846
http://modplug.svn.sourceforge.net/modplug/?rev=846&view=rev
Author: saga-games
Date: 2011-04-11 19:50:20 +0000 (Mon, 11 Apr 2011)
Log Message:
-----------
[Imp] Rewrote DMF loader completely for higher accuracy.
[Mod] OpenMPT: Version is now 1.19.01.02
Modified Paths:
--------------
trunk/OpenMPT/mptrack/version.h
trunk/OpenMPT/soundlib/LOAD_DMF.CPP
Modified: trunk/OpenMPT/mptrack/version.h
===================================================================
--- trunk/OpenMPT/mptrack/version.h 2011-04-11 16:44:07 UTC (rev 845)
+++ trunk/OpenMPT/mptrack/version.h 2011-04-11 19:50:20 UTC (rev 846)
@@ -15,7 +15,7 @@
#define VER_MAJORMAJOR 1
#define VER_MAJOR 19
#define VER_MINOR 01
-#define VER_MINORMINOR 01
+#define VER_MINORMINOR 02
//Creates version number from version parts that appears in version string.
//For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of
Modified: trunk/OpenMPT/soundlib/LOAD_DMF.CPP
===================================================================
--- trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2011-04-11 16:44:07 UTC (rev 845)
+++ trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2011-04-11 19:50:20 UTC (rev 846)
@@ -1,589 +1,1046 @@
/*
- * This source code is public domain.
+ * load_dmf.cpp
+ * ------------
+ * Purpose: Load DMF modules (X-Tracker by D-LUSiON).
+ * Notes : If it wasn't already outdated when the tracker was released, this would be a rather interesting
+ * and in some parts even sophisticated format - effect columns are separated by effect type, an easy to
+ * understand BPM tempo mode, effect durations are always divided into a 256th row, vibrato effects are
+ * specified by period length and the same 8-Bit granularity is used for both volume and panning.
+ * Unluckily, this format does not offer any envelopes or multi-sample instruments, and bidi sample loops
+ * are missing as well, so it was already well behind FT2 and IT back then.
+ * Authors: Johannes Schultz (mostly based on DMF.TXT, DMF_EFFC.TXT, trial and error and some invaluable hints by Zatzen)
*
- * Copied to OpenMPT from libmodplug.
- *
- * Authors: Olivier Lapicque <oli...@jp...>
- * OpenMPT dev(s) (miscellaneous modifications)
-*/
+ */
-///////////////////////////////////////////////////////
-// DMF DELUSION DIGITAL MUSIC FILEFORMAT (X-Tracker) //
-///////////////////////////////////////////////////////
+
#include "stdafx.h"
#include "Loaders.h"
#ifdef MODPLUG_TRACKER
#include "../mptrack/Moddoc.h"
#endif // MODPLUG_TRACKER
-//#define DMFLOG
+// 32-bit chunk identifiers
+#define DMF_DDMF 0x464D4444
+#define DMF_CMSG 0x47534D43
+#define DMF_SEQU 0x55514553
+#define DMF_PATT 0x54544150
+#define DMF_SMPI 0x49504D53
+#define DMF_SMPD 0x44504D53
+#define DMF_SMPJ 0x4A504D53
+#define DMF_ENDE 0x45444E45
-#pragma warning(disable:4244) //"conversion from 'type1' to 'type2', possible loss of data"
+// Pattern flags - global track
+#define DMFPAT_GLOBPACK 0x80 // Pack information for global track follows
+#define DMFPAT_GLOBMASK 0x3F // Mask for global effects
+// Pattern flags - note tracks
+#define DMFPAT_COUNTER 0x80 // Pack information for current channel follows
+#define DMFPAT_INSTR 0x40 // Instrument number present
+#define DMFPAT_NOTE 0x20 // Note present
+#define DMFPAT_VOLUME 0x10 // Volume present
+#define DMFPAT_INSEFF 0x08 // Instrument effect present
+#define DMFPAT_NOTEEFF 0x04 // Note effect present
+#define DMFPAT_VOLEFF 0x02 // Volume effect stored
+// Sample flags
+#define DMFSMP_LOOP 0x01
+#define DMFSMP_16BIT 0x02
+#define DMFSMP_COMPMASK 0x0C
+#define DMFSMP_COMP1 0x04 // Compression type 1
+#define DMFSMP_COMP2 0x08 // Compression type 2 (unused)
+#define DMFSMP_COMP3 0x0C // Compression type 3 (dito)
+#define DMFSMP_LIBRARY 0x80 // Sample is stored in a library
+
#pragma pack(1)
-typedef struct DMFHEADER
+// DMF header
+struct DMFHEADER
{
- DWORD id; // "DDMF" = 0x464d4444
- BYTE version; // 4
- CHAR trackername[8]; // "XTRACKER"
- CHAR songname[30];
- CHAR composer[20];
- BYTE date[3];
-} DMFHEADER;
+ uint32 signature; // "DDMF"
+ uint8 version; // 1 - 7 are beta versions, 8 is the official thing, 10 is xtracker32
+ char tracker[8]; // "XTRACKER"
+ char songname[30];
+ char composer[20];
+ uint8 creationDay;
+ uint8 creationMonth;
+ uint8 creationYear;
+};
-typedef struct DMFINFO
+struct DMF_IFFCHUNK
{
- DWORD id; // "INFO"
- DWORD infosize;
-} DMFINFO;
+ uint32 signature; // 4-letter identifier
+ uint32 chunksize; // chunk size without header
+};
-typedef struct DMFSEQU
+// Order list
+struct DMFCHUNK_SEQUENCE
{
- DWORD id; // "SEQU"
- DWORD seqsize;
- WORD loopstart;
- WORD loopend;
- WORD sequ[2];
-} DMFSEQU;
+ uint16 loopStart;
+ uint16 loopEnd;
+ // order list follows here ...
+};
-typedef struct DMFPATT
+// Pattern header (global)
+struct DMFCHUNK_PATTERNS
{
- DWORD id; // "PATT"
- DWORD patsize;
- WORD numpat; // 1-1024
- BYTE tracks;
- BYTE firstpatinfo;
-} DMFPATT;
+ uint16 numPatterns; // 1..1024 patterns
+ uint8 numTracks; // 1..32 channels
+};
-typedef struct DMFTRACK
+// Pattern header (for each pattern)
+struct DMFCHUNK_PATTERNHEADER
{
- BYTE tracks;
- BYTE beat; // [hi|lo] -> hi=ticks per beat, lo=beats per measure
- WORD ticks; // max 512
- DWORD jmpsize;
-} DMFTRACK;
+ uint8 numTracks; // 1..32 channels
+ uint8 beat; // [hi|lo] -> hi = rows per beat, lo = reserved
+ uint16 numRows;
+ uint32 patternLength;
+ // patttern data follows here ...
+};
-typedef struct DMFSMPI
+// Sample header
+struct DMFCHUNK_SAMPLEHEADER
{
- DWORD id;
- DWORD size;
- BYTE samples;
-} DMFSMPI;
+ uint32 length;
+ uint32 loopStart;
+ uint32 loopEnd;
+ uint16 c3freq; // 1000..45000hz
+ uint8 volume; // 0 = ignore
+ uint8 flags;
+};
-typedef struct DMFSAMPLE
+// Sample header tail (between head and tail, there might be the library name of the sample, depending on the DMF version)
+struct DMFCHUNK_SAMPLEHEADERTAIL
{
- DWORD len;
- DWORD loopstart;
- DWORD loopend;
- WORD c3speed;
- BYTE volume;
- BYTE flags;
-} DMFSAMPLE;
+ uint16 filler;
+ uint32 crc32;
+};
#pragma pack()
+// Pattern translation memory
+struct DMF_PATTERNSETTINGS
+{
+ uint8 beat; // Rows per beat
+ uint8 tempoTicks; // Tick mode param
+ uint8 tempoBPM; // BPM mode param
+ bool realBPMmode; // true = BPM mode
+ uint8 internalTicks; // Ticks per row in final pattern
+ vector<bool> playDir; // Sample play direction of each channel... false = forward (default)
+ vector<MODCOMMAND::NOTE> noteBuffer; // Note buffer
+ vector<MODCOMMAND::NOTE> lastNote; // Last played note on channel
+};
-#ifdef DMFLOG
-extern void Log(LPCSTR s, ...);
-#endif
-
-// Convert portamento value (not very accurate, to say the least)
-uint8 DMFporta2MPT(uint8 val)
-//---------------------------
+// Convert portamento value (not very accurate due to X-Tracker's higher granularity, to say the least)
+uint8 DMFporta2MPT(uint8 val, const uint8 internalTicks, const bool hasFine)
+//--------------------------------------------------------------------------
{
- if(val <= 0x0F)
+ if(val == 0)
+ return 0;
+ else if((val <= 0x0F || internalTicks < 2) && hasFine)
return (val | 0xF0);
else
- return (val / 4);
+ return max(1, (val / (internalTicks - 1))); // no porta on first tick!
}
-bool CSoundFile::ReadDMF(const BYTE *lpStream, const DWORD dwMemLength)
+
+// Convert portamento / volume slide value (not very accurate due to X-Tracker's higher granularity, to say the least)
+uint8 DMFslide2MPT(uint8 val, const uint8 internalTicks, const bool up)
//---------------------------------------------------------------------
{
- const DMFHEADER *pfh = (DMFHEADER *)lpStream;
- DMFINFO *psi;
- DMFSEQU *sequ;
- DWORD dwMemPos;
- BYTE infobyte[32];
- BYTE smplflags[MAX_SAMPLES];
+ val = max(1, val / 4);
+ const bool isFine = (val < 0x0F) || (internalTicks < 2);
+ if(!isFine)
+ val = max(1, (val + 3) / (internalTicks - 1)); // no slides on first tick! +3 for rounding precision
- if ((!lpStream) || (dwMemLength < 1024)) return false;
- if ((pfh->id != 0x464d4444) || (!pfh->version) || (pfh->version & 0xF0)) return false;
- dwMemPos = 66;
- memcpy(m_szNames[0], pfh->songname, 30);
- SpaceToNullStringFixed<30>(m_szNames[0]);
- m_nType = MOD_TYPE_DMF;
- m_dwSongFlags = SONG_LINEARSLIDES | SONG_ITCOMPATGXX | SONG_ITOLDEFFECTS;
- m_nChannels = 0;
-#ifdef DMFLOG
- Log("DMF version %d: \"%s\": %d bytes (0x%04X)\n", pfh->version, m_szNames[0], dwMemLength, dwMemLength);
-#endif
+ if(up)
+ return (isFine ? 0x0F : 0x00) | (val << 4);
+ else
+ return (isFine ? 0xF0 : 0x00) | (val & 0x0F);
-#ifdef MODPLUG_TRACKER
- if(GetpModDoc() != nullptr)
+}
+
+
+// Calculate tremor on/off param
+uint8 DMFtremor2MPT(uint8 val, const uint8 internalTicks)
+//-------------------------------------------------------
+{
+ uint8 ontime = (val >> 4);
+ uint8 offtime = (val & 0x0F);
+ ontime = CLAMP(ontime * internalTicks / 15, 1, 15);
+ offtime = CLAMP(offtime * internalTicks / 15, 1, 15);
+ return (ontime << 4) | offtime;
+}
+
+
+// Calculate delay parameter for note cuts / delays
+uint8 DMFdelay2MPT(uint8 val, const uint8 internalTicks)
+//------------------------------------------------------
+{
+ const int newval = (int)val * (int)internalTicks / 255;
+ return (uint8)CLAMP(newval, 0, 0x0F);
+}
+
+
+// Convert vibrato-style command parameters
+uint8 DMFvibrato2MPT(uint8 val, const uint8 internalTicks)
+//--------------------------------------------------------
+{
+ // MPT: 1 vibrato period == 64 ticks... we have internalTicks ticks per row.
+ // X-Tracker: Period length specified in rows!
+ const int periodInTicks = max(1, (val >> 4)) * internalTicks;
+ const uint8 matchingPeriod = (uint8)CLAMP((128 / periodInTicks), 1, 15);
+ return (matchingPeriod << 4) | max(1, (val & 0x0F));
+}
+
+
+PATTERNINDEX ConvertDMFPattern(const LPCBYTE lpStream, const DWORD dwMemLength, DMF_PATTERNSETTINGS &settings, CSoundFile *pSndFile)
+//----------------------------------------------------------------------------------------------------------------------------------
+{
+ #define ASSERT_CAN_READ_PATTERN(x) ASSERT_CAN_READ_PROTOTYPE(dwMemPos, dwMemLength, x, return nPat);
+
+ DWORD dwMemPos = 0;
+
+ // ASSERT_CAN_READ_PATTERN(sizeof(DMFCHUNK_PATTERNHEADER)); -- already done in main loop
+ DMFCHUNK_PATTERNHEADER *patHead = (DMFCHUNK_PATTERNHEADER *)(lpStream + dwMemPos);
+ dwMemPos += sizeof(DMFCHUNK_PATTERNHEADER);
+
+ const ROWINDEX numRows = CLAMP(LittleEndianW(patHead->numRows), 1, MAX_PATTERN_ROWS);
+ const PATTERNINDEX nPat = pSndFile->Patterns.Insert(numRows);
+ if(nPat == PATTERNINDEX_INVALID)
{
- FileHistory mptHistory;
- MemsetZero(mptHistory);
- mptHistory.loadDate.tm_mday = CLAMP(pfh->date[0], 0, 31);
- mptHistory.loadDate.tm_mon = CLAMP(pfh->date[1], 1, 12) - 1;
- mptHistory.loadDate.tm_year = pfh->date[2];
- GetpModDoc()->GetFileHistory()->clear();
- GetpModDoc()->GetFileHistory()->push_back(mptHistory);
+ return nPat;
}
-#endif // MODPLUG_TRACKER
- while (dwMemPos + 7 < dwMemLength)
+ MODCOMMAND *m = pSndFile->Patterns[nPat];
+ const CHANNELINDEX numChannels = min(pSndFile->GetNumChannels(), patHead->numTracks);
+
+ // When breaking to a pattern with less channels that the previous pattern,
+ // all voices in the now unused channels are killed:
+ for(CHANNELINDEX nChn = numChannels + 1; nChn < pSndFile->GetNumChannels(); nChn++)
{
- DWORD id = *((LPDWORD)(lpStream+dwMemPos));
+ m[nChn].note = NOTE_NOTECUT;
+ }
- switch(id)
+ // Initialize tempo stuff
+ settings.beat = (patHead->beat >> 4);
+ bool tempoChange = settings.realBPMmode;
+ uint8 writeDelay = 0;
+
+ // Counters for channel packing (including global track)
+ vector<uint8> channelCounter(numChannels + 1, 0);
+
+ for(ROWINDEX nRow = 0; nRow < numRows; nRow++)
+ {
+ // Global track info counter reached 0 => read global track data
+ if(channelCounter[0] == 0)
{
- // "INFO"
- case 0x4f464e49:
- // "CMSG"
- case 0x47534d43:
- psi = (DMFINFO *)(lpStream+dwMemPos);
- if (id == 0x47534d43) dwMemPos++;
- if ((psi->infosize > dwMemLength) || (psi->infosize + dwMemPos + 8 > dwMemLength)) goto dmfexit;
- if (psi->infosize >= 8)
+ ASSERT_CAN_READ_PATTERN(1);
+ uint8 globalInfo = lpStream[dwMemPos++];
+ // 0x80: Packing counter (if not present, counter stays at 0)
+ if((globalInfo & DMFPAT_GLOBPACK) != 0)
{
- ReadFixedLineLengthMessage(lpStream + dwMemPos + 8, psi->infosize - 1, 40, 0);
+ ASSERT_CAN_READ_PATTERN(1);
+ channelCounter[0] = lpStream[dwMemPos++];
}
- dwMemPos += psi->infosize + 8 - 1;
- break;
- // "SEQU"
- case 0x55514553:
- sequ = (DMFSEQU *)(lpStream+dwMemPos);
- if ((sequ->seqsize >= dwMemLength) || (dwMemPos + sequ->seqsize + 12 > dwMemLength)) goto dmfexit;
+ globalInfo &= DMFPAT_GLOBMASK;
+
+ uint8 globalData = 0;
+ if(globalInfo != 0)
{
- 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 - 2; i++) Order[i] = (PATTERNINDEX)sequ->sequ[i];
+ ASSERT_CAN_READ_PATTERN(1);
+ globalData = lpStream[dwMemPos++];
}
- dwMemPos += sequ->seqsize + 8;
- break;
- // "PATT"
- case 0x54544150:
- if (!m_nChannels)
+ switch(globalInfo)
{
- DMFPATT *patt = (DMFPATT *)(lpStream+dwMemPos);
- UINT numpat;
- DWORD dwPos = dwMemPos + 11;
- if ((patt->patsize >= dwMemLength) || (dwMemPos + patt->patsize + 8 > dwMemLength)) goto dmfexit;
- numpat = patt->numpat;
- if (numpat > MAX_PATTERNS) numpat = MAX_PATTERNS;
+ case 1: // Set Tick Frame Speed
+ settings.realBPMmode = false;
+ settings.tempoTicks = max(1, globalData); // Tempo in 1/4 rows per second
+ settings.tempoBPM = 0; // Automatically updated by X-Tracker
+ tempoChange = true;
+ break;
+ case 2: // Set BPM Speed (real BPM mode)
+ if(globalData) // DATA = 0 doesn't do anything
+ {
+ settings.realBPMmode = true;
+ settings.tempoBPM = globalData; // Tempo in real BPM (depends on rows per beat)
+ if(settings.beat != 0)
+ {
+ settings.tempoTicks = (globalData * settings.beat * 15); // Automatically updated by X-Tracker
+ }
+ tempoChange = true;
+ }
+ break;
+ case 3: // Set Beat
+ settings.beat = (globalData >> 4);
+ if(settings.beat != 0)
+ {
+ // Tempo changes only if we're in real BPM mode
+ tempoChange = settings.realBPMmode;
+ } else
+ {
+ // If beat is 0, change to tick speed mode, but keep current tempo
+ settings.realBPMmode = false;
+ }
+ break;
+ case 4: // Tick Delay
+ writeDelay = globalData;
+ break;
+ case 5: // Set External Flag
+ break;
+ case 6: // Slide Speed Up
+ if(globalData > 0)
+ {
+ uint8 &tempoData = (settings.realBPMmode) ? settings.tempoBPM : settings.tempoTicks;
+ if(tempoData < 256 - globalData)
+ {
+ tempoData += globalData;
+ } else
+ {
+ tempoData = 255;
+ }
+ tempoChange = true;
+ }
+ break;
+ case 7: // Slide Speed Down
+ if(globalData > 0)
+ {
+ uint8 &tempoData = (settings.realBPMmode) ? settings.tempoBPM : settings.tempoTicks;
+ if(tempoData > 1 + globalData)
+ {
+ tempoData -= globalData;
+ } else
+ {
+ tempoData = 1;
+ }
+ tempoChange = true;
+ }
+ break;
+ }
+ } else
+ {
+ channelCounter[0]--;
+ }
- m_nChannels = patt->tracks;
- if (m_nChannels < patt->firstpatinfo) m_nChannels = patt->firstpatinfo;
- if (m_nChannels > 32) m_nChannels = 32;
- if (m_nChannels < 1) m_nChannels = 1;
+ // These will eventually be written to the pattern
+ int speed = 0, tempo = 0;
- for (UINT npat=0; npat<numpat; npat++)
+ if(tempoChange)
+ {
+ // Can't do anything if we're in BPM mode and there's no rows per beat set...
+ if(!settings.realBPMmode || settings.beat)
+ {
+ // My approach to convert X-Tracker's "tick speed" (1/4 rows per second):
+ // Tempo * 6 / Speed = Beats per Minute
+ // => Tempo * 6 / (Speed * 60) = Beats per Second
+ // => Tempo * 24 / (Speed * 60) = Rows per Second (4 rows per beat at tempo 6)
+ // => Tempo = 60 * Rows per Second * Speed / 24
+ // For some reason, using settings.tempoTicks + 1 gives more accurate results than just settings.tempoTicks... (same problem in the old libmodplug DMF loader)
+ // Original unoptimized formula:
+ //const int tickspeed = (tempoRealBPMmode) ? max(1, (tempoData * beat * 4) / 60) : tempoData;
+ const int tickspeed = (settings.realBPMmode) ? max(1, settings.tempoBPM * settings.beat * 2) : ((settings.tempoTicks + 1) * 30);
+ // Try to find matching speed - try higher speeds first, so that effects like arpeggio and tremor work better.
+ for(speed = 255; speed > 1; speed--)
{
- DMFTRACK *pt = (DMFTRACK *)(lpStream+dwPos);
- #ifdef DMFLOG
- Log("Pattern #%d: %d tracks, %d rows\n", npat, pt->tracks, pt->ticks);
- #endif
- UINT tracks = pt->tracks;
- if (tracks > 32) tracks = 32;
- UINT ticks = pt->ticks;
- if (ticks > MAX_PATTERN_ROWS) ticks = MAX_PATTERN_ROWS;
- if (ticks < 1) ticks = 1;
- dwPos += 8;
- if ((pt->jmpsize >= dwMemLength) || (dwPos + pt->jmpsize + 4 >= dwMemLength)) break;
- if(Patterns.Insert(npat, ticks)) goto dmfexit;
- MODCOMMAND *m = Patterns[npat];
+ // Original unoptimized formula:
+ // tempo = 30 * tickspeed * speed / 48;
+ tempo = tickspeed * speed / 48;
+ if(tempo >= 32 && tempo <= 255)
+ {
+ break;
+ }
+ }
+ tempo = CLAMP(tempo, 32, 255);
+ settings.internalTicks = (uint8)speed;
+ } else
+ {
+ tempoChange = false;
+ }
+ }
- // If pattern "width" changes, leftover voices are killed:
- for(CHANNELINDEX nChn = tracks; nChn < m_nChannels; nChn++)
+ MODCOMMAND *m = pSndFile->Patterns[nPat].GetpModCommand(nRow, 1); // Reserve first channel for global effects
+
+ for(CHANNELINDEX nChn = 1; nChn <= numChannels; nChn++, m++)
+ {
+ // Track info counter reached 0 => read track data
+ if(channelCounter[nChn] == 0)
+ {
+ ASSERT_CAN_READ_PATTERN(1);
+ const uint8 channelInfo = lpStream[dwMemPos++];
+ // 0x80: Packing counter (if not present, counter stays at 0)
+ if((channelInfo & DMFPAT_COUNTER) != 0)
+ {
+ ASSERT_CAN_READ_PATTERN(1);
+ channelCounter[nChn] = lpStream[dwMemPos++];
+ }
+
+ // 0x40: Instrument
+ bool slideNote = true; // If there is no instrument number next to a note, the note is not retriggered!
+ if((channelInfo & DMFPAT_INSTR) != 0)
+ {
+ ASSERT_CAN_READ_PATTERN(1);
+ m->instr = lpStream[dwMemPos++];
+ if(m->instr != 0)
{
- m[nChn].note = NOTE_NOTECUT;
+ slideNote = false;
}
+ }
- DWORD d = dwPos;
- dwPos += pt->jmpsize;
- UINT ttype = 1;
- UINT tempo = 125;
- UINT glbinfobyte = 0;
- UINT pbeat = (pt->beat & 0xf0) ? pt->beat>>4 : 8;
- BOOL tempochange = (pt->beat & 0xf0) ? TRUE : FALSE;
- MemsetZero(infobyte);
- for (UINT row=0; row<ticks; row++)
+ // 0x20: Note
+ if((channelInfo & DMFPAT_NOTE) != 0)
+ {
+ ASSERT_CAN_READ_PATTERN(1);
+ m->note = lpStream[dwMemPos++];
+ if(m->note >= 1 && m->note <= 108)
{
- MODCOMMAND *p = &m[row * m_nChannels];
- // Parse track global effects
- if (!glbinfobyte)
+ m->note += 24;
+ settings.lastNote[nChn] = m->note;
+ } else if(m->note >= 129 && m->note <= 236)
+ {
+ // "Buffer notes" for portamento (and other effects?) that are actually not played, but just "queued"...
+ settings.noteBuffer[nChn] = (m->note & 0x7F) + 24;
+ m->note = NOTE_NONE;
+ } else if(m->note == 255)
+ {
+ m->note = NOTE_NOTECUT;
+ }
+ }
+
+ // If there's just an instrument number, but no note, retrigger sample.
+ if(m->note == NOTE_NONE && NOTE_IS_VALID(m->note) && m->instr > 0)
+ {
+ m->note = settings.lastNote[nChn];
+ m->instr = 0;
+ }
+
+ if(m->note != NOTE_NONE && NOTE_IS_VALID(m->note))
+ {
+ settings.playDir[nChn] = false;
+ }
+
+ uint8 effect1 = CMD_NONE, effect2 = CMD_NONE, effect3 = CMD_NONE;
+ uint8 effectParam1 = 0, effectParam2 = 0, effectParam3 = 0;
+
+ // 0x10: Volume
+ if((channelInfo & DMFPAT_VOLUME) != 0)
+ {
+ ASSERT_CAN_READ_PATTERN(1);
+ m->volcmd = VOLCMD_VOLUME;
+ m->vol = (lpStream[dwMemPos++] + 3) / 4;
+ }
+
+ // 0x08: Instrument effect
+ if((channelInfo & DMFPAT_INSEFF) != 0)
+ {
+ ASSERT_CAN_READ_PATTERN(2);
+ effect1 = lpStream[dwMemPos++];
+ effectParam1 = lpStream[dwMemPos++];
+
+ switch(effect1)
+ {
+ case 1: // Stop Sample
+ m->note = NOTE_NOTECUT;
+ effect1 = CMD_NONE;
+ break;
+ case 2: // Stop Sample Loop
+ m->note = NOTE_KEYOFF;
+ effect1 = CMD_NONE;
+ break;
+ case 3: // Instrument Volume Override (aka "Restart")
+ m->note = settings.lastNote[nChn];
+ settings.playDir[nChn] = false;
+ effect1 = CMD_NONE;
+ break;
+ case 4: // Sample Delay
+ effectParam1 = DMFdelay2MPT(effectParam1, settings.internalTicks);
+ if(effectParam1)
{
- BYTE info = lpStream[d++];
- BYTE infoval = 0;
- if ((info & 0x80) && (d < dwPos)) glbinfobyte = lpStream[d++];
- info &= 0x7f;
- if ((info) && (d < dwPos)) infoval = lpStream[d++];
- switch(info)
- {
- case 1: ttype = 0; tempo = infoval; tempochange = TRUE; break;
- case 2: ttype = 1; tempo = infoval; tempochange = TRUE; break;
- case 3: pbeat = infoval>>4; tempochange = ttype; break;
- #ifdef DMFLOG
- default: if (info) Log("GLB: %02X.%02X\n", info, infoval);
- #endif
- }
+ effect1 = CMD_S3MCMDEX;
+ effectParam1 = 0xD0 | (effectParam1);
} else
{
- glbinfobyte--;
+ effect1 = CMD_NONE;
}
- // Parse channels
- for (UINT i=0; i<tracks; i++) if (!infobyte[i])
+ if(m->note == NOTE_NONE)
{
- MODCOMMAND cmd = MODCOMMAND::Empty();
- BYTE info = lpStream[d++];
- if (info & 0x80) infobyte[i] = lpStream[d++];
- // Instrument
- if (info & 0x40)
- {
- cmd.instr = lpStream[d++];
- }
- // Note
- if (info & 0x20)
- {
- cmd.note = lpStream[d++];
- if (cmd.note >= 1 && cmd.note <= 108)
- {
- cmd.note += 24;
- } else if (cmd.note >= 129 && cmd.note <= 236)
- {
- // "ghost notes" for portamento that are actually not played... how the hell should we treat them?!
- cmd.note = (cmd.note & 0x7F) + 24;
- } else if (cmd.note == 255)
- {
- cmd.note = NOTE_NOTECUT;
- }
- }
- // Volume
- if (info & 0x10)
- {
- cmd.volcmd = VOLCMD_VOLUME;
- cmd.vol = (lpStream[d++]+3)>>2;
- }
- // Effect 1 - Instrument
- if (info & 0x08)
- {
- BYTE efx = lpStream[d++];
- BYTE eval = lpStream[d++];
- switch(efx)
- {
- // 1: Key Off
- case 1: if (!cmd.note) cmd.note = NOTE_NOTECUT; break;
- // 2: Stop Sample Loop
- case 2: if (!cmd.note) cmd.note = NOTE_KEYOFF; break;
- // 4: Sample Delay, in 1/256th rows
- case 4: if (eval&0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xD0; } break;
- // 5: Retrig, in 1/256th rows
- case 5: if (eval&0xe0) { cmd.command = CMD_RETRIG; cmd.param = (eval>>5); } break;
- // 6: Offset
- case 6: cmd.command = CMD_OFFSET; cmd.param = eval; break;
- // 10: Tekkno Invert
- case 10: cmd.command = CMD_S3MCMDEX; cmd.param = 0x9F; break;
- #ifdef DMFLOG
- default: Log("FX1: %02X.%02X\n", efx, eval);
- #endif
- }
- }
- // Effect 2 - Note
- if (info & 0x04)
- {
- BYTE efx = lpStream[d++];
- BYTE eval = lpStream[d++];
- switch(efx)
- {
- // 1: Finetune
- case 1: if (eval&0xf0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>4)|0x20; } break;
- // 2: Note Delay
- case 2: if (eval&0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xD0; } break;
- // 3: Arpeggio
- case 3: if (eval) { cmd.command = CMD_ARPEGGIO; cmd.param = eval; } break;
- // 4: Portamento Up
- case 4: cmd.command = CMD_PORTAMENTOUP; cmd.param = DMFporta2MPT(eval); break;
- // 5: Portamento Down
- case 5: cmd.command = CMD_PORTAMENTODOWN; cmd.param = DMFporta2MPT(eval); break;
- // 6: Tone Portamento
- case 6: cmd.command = CMD_TONEPORTAMENTO; cmd.param = DMFporta2MPT(eval); break;
- // 8: Vibrato Sine
- // 9: Vibrato Triangle
- // 10: Vibrato Square
- case 8:
- case 9:
- case 10:
- cmd.command = CMD_VIBRATO;
- cmd.param = (0xF0 - (eval & 0xF0)) | ((eval & 0x0F) / 2);
- break;
- // 12: Note cut, in 1/256th rows
- case 12: if (eval & 0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xc0; }
- else if (!cmd.note) { cmd.note = NOTE_NOTECUT; } break;
- #ifdef DMFLOG
- default: Log("FX2: %02X.%02X\n", efx, eval);
- #endif
- }
- }
- // Effect 3 - Volume
- if (info & 0x02)
- {
- BYTE efx = lpStream[d++];
- BYTE eval = lpStream[d++];
- switch(efx)
- {
- // 1: Vol Slide Up
- case 1: if (eval == 0xff) break;
- eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
- cmd.command = CMD_VOLUMESLIDE; cmd.param = eval<<4; break;
- // 2: Vol Slide Down
- case 2: if (eval == 0xff) break;
- eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
- cmd.command = CMD_VOLUMESLIDE; cmd.param = eval; break;
- // 3: Tremor
- case 3:
- cmd.command = CMD_TREMOR; cmd.param = eval;
- break;
- // 4: Tremolo Sine
- // 5: Tremolo Triangle
- // 6: Tremolo Square
- case 4:
- case 5:
- case 6:
- cmd.command = CMD_TREMOLO;
- cmd.param = (0xF0 - (eval & 0xF0)) | ((eval & 0x0F) / 2);
- break;
- // 7: Set Pan
- case 7: if (!cmd.volcmd) { cmd.volcmd = VOLCMD_PANNING; cmd.vol = (eval+3)>>2; }
- else { cmd.command = CMD_PANNING8; cmd.param = eval; } break;
- // 8: Pan Slide Left
- case 8: eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
- cmd.command = CMD_PANNINGSLIDE; cmd.param = eval << 4; break;
- // 9: Pan Slide Right
- case 9: eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
- cmd.command = CMD_PANNINGSLIDE; cmd.param = eval; break;
- #ifdef DMFLOG
- default: Log("FX3: %02X.%02X\n", efx, eval);
- #endif
- }
- }
+ m->note = settings.lastNote[nChn];
+ settings.playDir[nChn] = false;
+ }
+ break;
+ case 5: // Tremolo Retrig Sample (who invented those stupid effect names?)
+ effectParam1 = max(1, DMFdelay2MPT(effectParam1, settings.internalTicks));
+ effect1 = CMD_RETRIG;
+ settings.playDir[nChn] = false;
+ break;
+ case 6: // Offset
+ case 7: // Offset + 64k
+ case 8: // Offset + 128k
+ case 9: // Offset + 192k
+ // Put high offset on previous row
+ if(nRow > 0)
+ {
+ pSndFile->TryWriteEffect(nPat, nRow - 1, CMD_S3MCMDEX, (0xA0 | (effect1 - 6)), false, nChn, false, weTryPreviousRow);
+ }
+ effect1 = CMD_OFFSET;
+ settings.playDir[nChn] = false;
+ break;
+ case 10: // Invert Sample play direction ("Tekkno Invert")
+ effect1 = CMD_S3MCMDEX;
+ if(settings.playDir[nChn] == false)
+ effectParam1 = 0x9F;
+ else
+ effectParam1 = 0x9E;
+ settings.playDir[nChn] = !settings.playDir[nChn];
+ break;
+ default:
+ effect1 = CMD_NONE;
+ break;
+ }
+ }
- // Note without instrument == just reset pitch, do not retrigger
- if(cmd.instr == 0 && cmd.note != NOTE_NONE && NOTE_IS_VALID(cmd.note) && cmd.command != CMD_TONEPORTAMENTO)
- {
- if(cmd.volcmd == VOLCMD_NONE)
- {
- cmd.volcmd = VOLCMD_TONEPORTAMENTO;
- cmd.vol = 9;
- } else
- {
- cmd.command = CMD_TONEPORTAMENTO;
- cmd.param = 0xFF;
- }
- }
+ // 0x04: Note effect
+ if((channelInfo & DMFPAT_NOTEEFF) != 0)
+ {
+ ASSERT_CAN_READ_PATTERN(2);
+ effect2 = lpStream[dwMemPos++];
+ effectParam2 = lpStream[dwMemPos++];
- // Store effect
- if (i < m_nChannels) p[i] = cmd;
- if (d > dwPos)
- {
- #ifdef DMFLOG
- Log("Unexpected EOP: row=%d\n", row);
- #endif
- break;
- }
+ switch(effect2)
+ {
+ case 1: // Note Finetune
+ effect2 = (effectParam2 < 128) ? CMD_PORTAMENTOUP : CMD_PORTAMENTODOWN;
+ if(effectParam2 > 128) effectParam2 = 255 - effectParam2 + 1;
+ effectParam2 = 0xF0 | min(0x0F, effectParam2); // Well, this is not too accurate...
+ break;
+ case 2: // Note Delay (wtf is the difference to Sample Delay?)
+ effectParam2 = DMFdelay2MPT(effectParam2, settings.internalTicks);
+ if(effectParam2)
+ {
+ effect2 = CMD_S3MCMDEX;
+ effectParam2 = 0xD0 | (effectParam2);
} else
{
- infobyte[i]--;
+ effect2 = CMD_NONE;
}
-
- // Find free channel for tempo change
- if (tempochange)
+ break;
+ case 3: // Arpeggio
+ effect2 = CMD_ARPEGGIO;
+ break;
+ case 4: // Portamento Up
+ case 5: // Portamento Down
+ effectParam2 = DMFporta2MPT(effectParam2, settings.internalTicks, true);
+ effect2 = (effect2 == 4) ? CMD_PORTAMENTOUP : CMD_PORTAMENTODOWN;
+ break;
+ case 6: // Portamento to Note
+ if(m->note == NOTE_NONE)
{
- tempochange = FALSE;
- UINT speed=6, modtempo=tempo;
- UINT rpm = ((ttype) && (pbeat)) ? tempo*pbeat : (tempo+1)*15;
- for (speed=30; speed>1; speed--)
- {
- modtempo = rpm*speed/24;
- if (modtempo <= 200) break;
- if ((speed < 6) && (modtempo < 256)) break;
- }
- #ifdef DMFLOG
- Log("Tempo change: ttype=%d pbeat=%d tempo=%3d -> speed=%d tempo=%d\n",
- ttype, pbeat, tempo, speed, modtempo);
- #endif
- for (UINT ich=0; ich<m_nChannels; ich++) if (!p[ich].command)
- {
- if (speed)
- {
- p[ich].command = CMD_SPEED;
- p[ich].param = (BYTE)speed;
- speed = 0;
- } else
- if ((modtempo >= 32) && (modtempo < 256))
- {
- p[ich].command = CMD_TEMPO;
- p[ich].param = (BYTE)modtempo;
- modtempo = 0;
- } else
- {
- break;
- }
- }
+ m->note = settings.noteBuffer[nChn];
}
- if (d >= dwPos) break;
+ effectParam2 = DMFporta2MPT(effectParam2, settings.internalTicks, false);
+ effect2 = CMD_TONEPORTAMENTO;
+ break;
+ case 7: // Scratch to Note (neat! but we don't have such an effect...)
+ m->note = effectParam2 + 25;
+ effect2 = CMD_TONEPORTAMENTO;
+ effectParam2 = 0xFF;
+ break;
+ case 8: // Vibrato Sine
+ case 9: // Vibrato Triangle (ramp down should be close enough)
+ case 10: // Vibrato Square
+ // Put vibrato type on previous row
+ if(nRow > 0)
+ {
+ pSndFile->TryWriteEffect(nPat, nRow - 1, CMD_S3MCMDEX, (0x30 | (effect2 - 8)), false, nChn, false, weTryPreviousRow);
+ }
+ effect2 = CMD_VIBRATO;
+ effectParam2 = DMFvibrato2MPT(effectParam2, settings.internalTicks);
+ break;
+ case 11: // Note Tremolo
+ effectParam2 = DMFtremor2MPT(effectParam2, settings.internalTicks);
+ effect2 = CMD_TREMOR;
+ break;
+ case 12: // Note Cut
+ effectParam2 = DMFdelay2MPT(effectParam2, settings.internalTicks);
+ if(effectParam2)
+ {
+ effect2 = CMD_S3MCMDEX;
+ effectParam2 = 0xC0 | (effectParam2);
+ } else
+ {
+ effect2 = CMD_NONE;
+ m->note = NOTE_NOTECUT;
+ }
+ break;
+ default:
+ effect2 = CMD_NONE;
+ break;
}
- #ifdef DMFLOG
- Log(" %d/%d bytes remaining\n", dwPos-d, pt->jmpsize);
- #endif
- if (dwPos + 8 >= dwMemLength) break;
}
- dwMemPos += patt->patsize + 8;
- }
- break;
- // "SMPI": Sample Info
- case 0x49504d53:
- {
- DMFSMPI *pds = (DMFSMPI *)(lpStream+dwMemPos);
- if (pds->size <= dwMemLength - dwMemPos)
+ // 0x02: Volume effect
+ if((channelInfo & DMFPAT_VOLEFF) != 0)
{
- DWORD dwPos = dwMemPos + 9;
- m_nSamples = pds->samples;
- if (m_nSamples >= MAX_SAMPLES) m_nSamples = MAX_SAMPLES-1;
- for (UINT iSmp=1; iSmp<=m_nSamples; iSmp++)
+ ASSERT_CAN_READ_PATTERN(2);
+ effect3 = lpStream[dwMemPos++];
+ effectParam3 = lpStream[dwMemPos++];
+
+ switch(effect3)
{
- UINT namelen = lpStream[dwPos];
- smplflags[iSmp] = 0;
- if (dwPos+namelen+1+sizeof(DMFSAMPLE) > dwMemPos+pds->size+8) break;
- if (namelen)
+ case 1: // Volume Slide Up
+ case 2: // Volume Slide Down
+ effectParam3 = DMFslide2MPT(effectParam3, settings.internalTicks, (effect3 == 1));
+ effect3 = CMD_VOLUMESLIDE;
+ break;
+ case 3: // Volume Tremolo (actually this is Tremor)
+ effectParam3 = DMFtremor2MPT(effectParam3, settings.internalTicks);
+ effect3 = CMD_TREMOR;
+ break;
+ case 4: // Tremolo Sine
+ case 5: // Tremolo Triangle (ramp down should be close enough)
+ case 6: // Tremolo Square
+ // Put tremolo type on previous row
+ if(nRow > 0)
{
- UINT rlen = (namelen < 32) ? namelen : 31;
- memcpy(m_szNames[iSmp], lpStream+dwPos+1, rlen);
- SpaceToNullStringFixed(m_szNames[iSmp], rlen);
+ pSndFile->TryWriteEffect(nPat, nRow - 1, CMD_S3MCMDEX, (0x40 | (effect3 - 4)), false, nChn, false, weTryPreviousRow);
}
- dwPos += namelen + 1;
- DMFSAMPLE *psh = (DMFSAMPLE *)(lpStream+dwPos);
- MODSAMPLE *psmp = &Samples[iSmp];
- psmp->nLength = psh->len;
- psmp->nSustainStart = psh->loopstart;
- psmp->nSustainEnd = psh->loopend;
- psmp->nC5Speed = psh->c3speed;
- psmp->nGlobalVol = 64;
- psmp->nVolume = (psh->volume) ? ((WORD)psh->volume)+1 : (WORD)256;
- psmp->uFlags = (psh->flags & 2) ? CHN_16BIT : 0;
- if (psmp->uFlags & CHN_16BIT) psmp->nLength >>= 1;
- if (psh->flags & 1) psmp->uFlags |= CHN_SUSTAINLOOP;
- smplflags[iSmp] = psh->flags;
- dwPos += (pfh->version < 8) ? 22 : 30;
- #ifdef DMFLOG
- Log("SMPI %d/%d: len=%d flags=0x%02X\n", iSmp, m_nSamples, psmp->nLength, psh->flags);
- #endif
+ effect3 = CMD_TREMOLO;
+ effectParam3 = DMFvibrato2MPT(effectParam3, settings.internalTicks);
+ break;
+ case 7: // Set Balance
+ effect3 = CMD_PANNING8;
+ break;
+ case 8: // Slide Balance Left
+ case 9: // Slide Balance Right
+ effectParam3 = DMFslide2MPT(effectParam3, settings.internalTicks, (effect3 == 8));
+ effect3 = CMD_PANNINGSLIDE;
+ break;
+ case 10: // Balance Vibrato Left/Right (always sine modulated)
+ effect3 = CMD_PANBRELLO;
+ effectParam3 = DMFvibrato2MPT(effectParam3, settings.internalTicks);
+ break;
+ default:
+ effect3 = CMD_NONE;
+ break;
}
}
- dwMemPos += pds->size + 8;
+
+ // I guess this is close enough to "not retriggering the note"
+ if(slideNote && m->note != NOTE_NONE && NOTE_IS_VALID(m->note))
+ {
+ if(effect2 == CMD_NONE)
+ {
+ effect2 = CMD_TONEPORTAMENTO;
+ effectParam2 = 0xFF;
+ } else if(effect3 == CMD_NONE && effect2 != CMD_TONEPORTAMENTO) // Tone portamentos normally go in effect #2
+ {
+ effect3 = CMD_TONEPORTAMENTO;
+ effectParam3 = 0xFF;
+ }
+ }
+ // If one of the effects is unused, temporarily put volume commands in there
+ if(m->volcmd == VOLCMD_VOLUME)
+ {
+ if(effect2 == CMD_NONE)
+ {
+ effect2 = CMD_VOLUME;
+ effectParam2 = m->vol;
+ m->volcmd = VOLCMD_NONE;
+ } else if(effect3 == CMD_NONE)
+ {
+ effect3 = CMD_VOLUME;
+ effectParam3 = m->vol;
+ m->volcmd = VOLCMD_NONE;
+ }
+ }
+
+ // Do that dance.
+ // Maybe I should quit rewriting this everywhere and make a generic version :P
+ int n;
+ for (n = 0; n < 4; n++)
+ {
+ if(CSoundFile::ConvertVolEffect(&effect2, &effectParam2, (n >> 1) ? true : false))
+ {
+ n = 5;
+ break;
+ }
+ std::swap(effect2, effect3);
+ std::swap(effectParam2, effectParam3);
+ }
+ if (n < 5)
+ {
+ if (CSoundFile::GetEffectWeight((MODCOMMAND::COMMAND)effect2) > CSoundFile::GetEffectWeight((MODCOMMAND::COMMAND)effect3))
+ {
+ std::swap(effect2, effect3);
+ std::swap(effectParam2, effectParam3);
+ }
+ effect2 = CMD_NONE;
+ }
+ if (!effect2)
+ effectParam2 = 0;
+ if (!effect3)
+ effectParam3 = 0;
+
+ if(m->volcmd == VOLCMD_NONE && effect2 != VOLCMD_NONE)
+ {
+ m->volcmd = effect2;
+ m->vol = effectParam2;
+ }
+ // Prefer instrument effects over any other effects
+ if(effect1 != CMD_NONE)
+ {
+ m->command = effect1;
+ m->param = effectParam1;
+ } else if(effect3 != CMD_NONE)
+ {
+ m->command = effect3;
+ m->param = effectParam3;
+ }
+
+ } else
+ {
+ channelCounter[nChn]--;
}
+ } // End for all channels
+
+ // Now we can try to write tempo information.
+ if(tempoChange)
+ {
+ tempoChange = false;
+ pSndFile->TryWriteEffect(nPat, nRow, CMD_TEMPO, (BYTE)tempo, false, 0, false, weTryNextRow);
+ pSndFile->TryWriteEffect(nPat, nRow, CMD_SPEED, (BYTE)speed, false, CHANNELINDEX_INVALID, false, weTryNextRow);
+ }
+ // Try to put delay effects somewhere as well
+ if(writeDelay & 0xF0)
+ {
+ pSndFile->TryWriteEffect(nPat, nRow, CMD_S3MCMDEX, 0xE0 | (writeDelay >> 4), false, CHANNELINDEX_INVALID, true, weIgnore);
+ }
+ if(writeDelay & 0x0F)
+ {
+ const uint8 param = (writeDelay & 0x0F) * settings.internalTicks / 15;
+ pSndFile->TryWriteEffect(nPat, nRow, CMD_S3MCMDEX, 0x60 | CLAMP(param, 1, 15), false, CHANNELINDEX_INVALID, true, weIgnore);
+ }
+ writeDelay = 0;
+ } // End for all rows
+
+ return nPat;
+
+ #undef ASSERT_CAN_READ_PATTERN
+
+}
+
+
+DWORD ConvertDMFSample(const SAMPLEINDEX nSmp, const LPCBYTE lpStream, const DWORD dwMemLength, const bool isV8, uint8 &sampleFlags, CSoundFile *pSndFile)
+//--------------------------------------------------------------------------------------------------------------------------------------------------------
+{
+ #define ASSERT_CAN_READ_SAMPLE(x) ASSERT_CAN_READ_PROTOTYPE(dwMemPos, dwMemLength, x, return 0);
+
+ DWORD dwMemPos = 0;
+
+ ASSERT_CAN_READ_SAMPLE(1);
+ const size_t lenName = lpStream[dwMemPos++];
+ STATIC_ASSERT(MAX_SAMPLENAME > 30);
+ const size_t lenNameImport = min(30, lenName);
+ ASSERT_CAN_READ_SAMPLE(lenName);
+ memcpy(pSndFile->m_szNames[nSmp], lpStream + dwMemPos, lenNameImport);
+ SpaceToNullStringFixed(pSndFile->m_szNames[nSmp], lenNameImport);
+ dwMemPos += lenName;
+
+ ASSERT_CAN_READ_SAMPLE(sizeof(DMFCHUNK_SAMPLEHEADER));
+ DMFCHUNK_SAMPLEHEADER *smpHead = (DMFCHUNK_SAMPLEHEADER *)(lpStream + dwMemPos);
+ dwMemPos += sizeof(DMFCHUNK_SAMPLEHEADER);
+
+ MODSAMPLE *pSmp = &pSndFile->Samples[nSmp];
+ MemsetZero(*pSmp);
+ pSmp->nLength = min(MAX_SAMPLE_LENGTH, LittleEndian(smpHead->length));
+ pSmp->nSustainEnd = min(pSmp->nLength, LittleEndian(smpHead->loopEnd));
+ pSmp->nSustainStart = min(pSmp->nSustainEnd, LittleEndian(smpHead->loopStart));
+ if(pSmp->nSustainEnd > 0)
+ {
+ pSmp->nSustainEnd--;
+ }
+
+ pSmp->nC5Speed = LittleEndianW(smpHead->c3freq);
+ pSmp->nGlobalVol = 64;
+ if(smpHead->volume)
+ {
+ pSmp->nVolume = smpHead->volume + 1;
+ } else
+ {
+ pSmp->nVolume = 256;
+ }
+ sampleFlags = smpHead->flags;
+ pSmp->uFlags = 0;
+ if((sampleFlags & DMFSMP_LOOP) != 0 && pSmp->nSustainEnd > pSmp->nSustainStart)
+ {
+ pSmp->uFlags |= CHN_SUSTAINLOOP;
+ }
+ if((sampleFlags & DMFSMP_16BIT) != 0)
+ {
+ pSmp->uFlags |= CHN_16BIT;
+ pSmp->nLength /= 2;
+ pSmp->nSustainStart /= 2;
+ pSmp->nSustainEnd /= 2;
+ }
+
+ if(isV8)
+ {
+ // Read library name in version 8 files
+ ASSERT_CAN_READ_SAMPLE(8);
+ memcpy(pSmp->filename, lpStream + dwMemPos, 8);
+ SpaceToNullStringFixed<8>(pSmp->filename);
+ dwMemPos += 8;
+ }
+
+ ASSERT_CAN_READ_SAMPLE(sizeof(DMFCHUNK_SAMPLEHEADERTAIL));
+ // We don't care for the checksum of the sample data...
+ dwMemPos += sizeof(DMFCHUNK_SAMPLEHEADERTAIL);
+
+ return dwMemPos;
+
+ #undef ASSERT_CAN_READ_SAMPLE
+
+}
+
+
+bool CSoundFile::ReadDMF(const BYTE *lpStream, const DWORD dwMemLength)
+//---------------------------------------------------------------------
+{
+ #define ASSERT_CAN_READ_CHUNK(x) ASSERT_CAN_READ_PROTOTYPE(dwMemPos, dwChunkEnd, x, break);
+
+ DWORD dwMemPos = 0;
+
+ ASSERT_CAN_READ(sizeof(DMFHEADER));
+ DMFHEADER *pHeader = (DMFHEADER *)lpStream;
+ if(pHeader->signature != LittleEndian(DMF_DDMF) || !pHeader->version || pHeader->version > 10)
+ {
+ return false;
+ }
+ dwMemPos += sizeof(DMFHEADER);
+
+ memcpy(m_szNames[0], pHeader->songname, 30);
+ SpaceToNullStringFixed<30>(m_szNames[0]);
+ m_nChannels = 0;
+
+#ifdef MODPLUG_TRACKER
+ if(GetpModDoc() != nullptr)
+ {
+ FileHistory mptHistory;
+ MemsetZero(mptHistory);
+ mptHistory.loadDate.tm_mday = CLAMP(pHeader->creationDay, 0, 31);
+ mptHistory.loadDate.tm_mon = CLAMP(pHeader->creationMonth, 1, 12) - 1;
+ mptHistory.loadDate.tm_year = pHeader->creationYear;
+ GetpModDoc()->GetFileHistory()->clear();
+ GetpModDoc()->GetFileHistory()->push_back(mptHistory);
+ }
+#endif // MODPLUG_TRACKER
+
+ vector<uint8> sampleFlags;
+ vector<DWORD> patternOffset;
+ vector<DWORD> patternLength;
+
+ ORDERINDEX loopStart = 0, loopEnd = ORDERINDEX_INVALID;
+
+ // go through all chunks now
+ while(dwMemPos < dwMemLength)
+ {
+ // Special case: Last 4 bytes should be "ENDE", without a size field (WTF)
+ ASSERT_CAN_READ(4);
+ if(LittleEndian(*(uint32 *)(lpStream + dwMemPos)) == DMF_ENDE)
+ {
break;
+ }
- // "SMPD": Sample Data
- case 0x44504d53:
+ ASSERT_CAN_READ(sizeof(DMF_IFFCHUNK));
+ DMF_IFFCHUNK chunkheader = *(DMF_IFFCHUNK *)(lpStream + dwMemPos);
+ dwMemPos += sizeof(DMF_IFFCHUNK);
+
+ chunkheader.signature = LittleEndian(chunkheader.signature);
+ chunkheader.chunksize = LittleEndian(chunkheader.chunksize);
+ ASSERT_CAN_READ(chunkheader.chunksize);
+
+ const DWORD dwChunkEnd = dwMemPos + chunkheader.chunksize;
+
+ switch(chunkheader.signature)
+ {
+ case DMF_CMSG: // "CMSG" - Song message
+ ASSERT_CAN_READ_CHUNK(1);
+ dwMemPos++; // filler byte
+ ReadFixedLineLengthMessage(lpStream + dwMemPos, chunkheader.chunksize - 1, 40, 0);
+ break;
+
+ case DMF_SEQU: // "SEQU" - Order list
{
- DWORD dwPos = dwMemPos + 8;
- UINT ismpd = 0;
- for (UINT iSmp=1; iSmp<=m_nSamples; iSmp++)
+ ASSERT_CAN_READ_CHUNK(sizeof(DMFCHUNK_SEQUENCE));
+ DMFCHUNK_SEQUENCE *seqHead = (DMFCHUNK_SEQUENCE *)(lpStream + dwMemPos);
+ dwMemPos += sizeof(DMFCHUNK_SEQUENCE);
+
+ loopStart = LittleEndianW(seqHead->loopStart);
+ loopEnd = LittleEndianW(seqHead->loopEnd);
+ const ORDERINDEX numOrders = (ORDERINDEX)min(MAX_ORDERS, (chunkheader.chunksize - sizeof(DMFCHUNK_SEQUENCE)) / 2);
+ Order.resize(numOrders, Order.GetInvalidPatIndex());
+
+ for(ORDERINDEX i = 0; i < numOrders; i++, dwMemPos += 2)
{
- ismpd++;
- DWORD pksize;
- if (dwPos + 4 >= dwMemLength)
+ uint16 orderItem = *(uint16 *)(lpStream + dwMemPos);
+ Order[i] = (PATTERNINDEX)LittleEndianW(orderItem);
+ }
+ }
+ break;
+
+ case DMF_PATT: // "PATT" - Pattern data
+ if(m_nChannels == 0)
+ {
+ ASSERT_CAN_READ_CHUNK(sizeof(DMFCHUNK_PATTERNS));
+ DMFCHUNK_PATTERNS *patInfo = (DMFCHUNK_PATTERNS *)(lpStream + dwMemPos);
+ dwMemPos += sizeof(DMFCHUNK_PATTERNS);
+ m_nChannels = CLAMP(patInfo->numTracks, 1, 32) + 1; // + 1 for global track (used for tempo stuff)
+
+ const PATTERNINDEX numPats = min(MAX_PATTERNS, LittleEndianW(patInfo->numPatterns));
+ patternOffset.assign(numPats, 0);
+ patternLength.assign(numPats, 0);
+
+ for(PATTERNINDEX nPat = 0; nPat < numPats; nPat++)
+ {
+ ASSERT_CAN_READ_CHUNK(sizeof(DMFCHUNK_PATTERNHEADER));
+ DMFCHUNK_PATTERNHEADER *patHead = (DMFCHUNK_PATTERNHEADER *)(lpStream + dwMemPos);
+
+ patternOffset[nPat] = dwMemPos;
+ patternLength[nPat] = sizeof(DMFCHUNK_PATTERNHEADER) + LittleEndian(patHead->patternLength);
+
+ ASSERT_CAN_READ_CHUNK(patternLength[nPat]);
+ dwMemPos += patternLength[nPat];
+ }
+ }
+ break;
+
+ case DMF_SMPI: // "SMPI" - Sample headers
+ if(m_nSamples == 0)
+ {
+ ASSERT_CAN_READ_CHUNK(1);
+ m_nSamples = (SAMPLEINDEX)min(MAX_SAMPLES - 1, lpStream[dwMemPos]);
+ dwMemPos++;
+
+ sampleFlags.assign(m_nSamples, 0);
+ for(SAMPLEINDEX nSmp = 0; nSmp < m_nSamples; nSmp++)
+ {
+ const DWORD bytesRead = ConvertDMFSample(nSmp + 1, lpStream + dwMemPos, dwChunkEnd - dwMemPos, (pHeader->version >= 8), sampleFlags[nSmp], this);
+ if(bytesRead == 0)
{
- #ifdef DMFLOG
- Log("Unexpected EOF at sample %d/%d! (pos=%d)\n", iSmp, m_nSamples, dwPos);
- #endif
break;
}
- pksize = *((LPDWORD)(lpStream+dwPos));
- #ifdef DMFLOG
- Log("sample %d: pos=0x%X pksize=%d ", iSmp, dwPos, pksize);
- Log("len=%d flags=0x%X [%08X]\n", Samples[iSmp].nLength, smplflags[ismpd], *((LPDWORD)(lpStream+dwPos+4)));
- #endif
- dwPos += 4;
- if (pksize > dwMemLength - dwPos)
+ dwMemPos += bytesRead;
+ }
+
+ }
+ break;
+
+ case DMF_SMPD: // "SMPD" - Sample data
+ for(SAMPLEINDEX nSmp = 1; nSmp <= m_nSamples; nSmp++)
+ {
+ ASSERT_CAN_READ_CHUNK(4);
+ const uint32 length = LittleEndian(*(uint32 *)(lpStream + dwMemPos));
+ dwMemPos += 4;
+ ASSERT_CAN_READ_CHUNK(length);
+
+ if(length > 0)
+ {
+ UINT flags = (Samples[nSmp].uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S;
+ if((sampleFlags[nSmp - 1] & DMFSMP_COMPMASK) == DMFSMP_COMP1)
{
- #ifdef DMFLOG
- Log("WARNING: pksize=%d, but only %d bytes left\n", pksize, dwMemLength-dwPos);
- #endif
- pksize = dwMemLength - dwPos;
+ flags = (Samples[nSmp].uFlags & CHN_16BIT) ? RS_DMF16 : RS_DMF8;
}
- if ((pksize) && (iSmp <= m_nSamples))
- {
- UINT flags = (Samples[iSmp].uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S;
- if (smplflags[ismpd] & 4) flags = (Samples[iSmp].uFlags & CHN_16BIT) ? RS_DMF16 : RS_DMF8;
- ReadSample(&Samples[iSmp], flags, (LPSTR)(lpStream+dwPos), pksize);
- }
- dwPos += pksize;
+ ReadSample(&Samples[nSmp], flags, (LPCSTR)(lpStream + dwMemPos), length);
+ dwMemPos += length;
}
- dwMemPos = dwPos;
}
break;
- // "ENDE": end of file
- case 0x45444e45:
- goto dmfexit;
-
- // Unrecognized id, or "ENDE" field
+ case DMF_SMPJ: // "SMPJ" - Sample jump points (xtracker32 only)
+ break;
+
+#if 0
default:
- dwMemPos += 4;
- break;
+ // There is some (encrypted?) IFF chunk with a very weird ID at the end of many DMF files. What does it mean?
+ {
+ char s[32];
+ const char *sig = (char *)&chunkheader.signature;
+ wsprintf(s, "Unknown chunk ID %c%c%c%c at %d", sig[0], sig[1], sig[2], sig[3], dwMemPos - sizeof(DMF_IFFCHUNK));
+ MessageBox(0, s, 0, 0);
+ }
+#endif
}
+
+ dwMemPos = dwChunkEnd;
}
-dmfexit:
- if (!m_nChannels)
+
+ if(!patternOffset.empty())
{
- if (!m_nSamples)
+ DMF_PATTERNSETTINGS settings;
+ settings.beat = 0;
+ settings.tempoTicks = 32;
+ settings.tempoBPM = 120;
+ settings.realBPMmode = false;
+ settings.internalTicks = 6;
+ settings.playDir.assign(GetNumChannels(), false);
+ settings.noteBuffer.assign(GetNumChannels(), NOTE_NONE);
+ settings.lastNote.assign(GetNumChannels(), NOTE_NONE);
+
+ for(ORDERINDEX nOrd = 0; nOrd < Order.GetLength(); nOrd++)
{
- m_nType = MOD_TYPE_NONE;
- return false;
+ // Create one pattern for each order item, as the same pattern can be played with different settings
+ PATTERNINDEX nPat = Order[nOrd];
+ if(nPat < patternOffset.size() && patternOffset[nPat] != 0)
+ {
+ nPat = ConvertDMFPattern(lpStream + patternOffset[nPat], patternLength[nPat], settings, this);
+ Order[nOrd] = nPat;
+ // Loop end?
+ if(nPat != PATTERNINDEX_INVALID && nOrd == loopEnd && (loopStart > 0 || nOrd < Order.GetLength() - 1))
+ {
+ TryWriteEffect(nPat, Patterns[nPat].GetNumRows() - 1, CMD_POSITIONJUMP, (BYTE)loopStart, false, CHANNELINDEX_INVALID, false, weTryPreviousRow);
+ }
+ }
}
- m_nChannels = 4;
}
+
+ m_nType = MOD_TYPE_DMF;
+ m_dwSongFlags = SONG_LINEARSLIDES | SONG_ITCOMPATGXX; // this will be converted to IT format by MPT. SONG_ITOLDEFFECTS is not set because of tremor.
+ SetModFlag(MSF_COMPATIBLE_PLAY, true);
+ m_nDefaultSpeed = 6;
+ m_nDefaultTempo = 120;
+ m_nDefaultGlobalVolume = 256;
+ m_nSamplePreAmp = m_nVSTiVolume = 48;
+
return true;
+
+ #undef ASSERT_CAN_READ_CHUNK
}
///////////////////////////////////////////////////////////////////////
-// DMF Compression
+// DMF Compression (from libmodplug)
-#pragma pack(1)
-
typedef struct DMF_HNODE
{
- short int left, right;
- BYTE value;
+ int16 left, right;
+ uint8 value;
} DMF_HNODE;
typedef struct DMF_HTREE
{
- LPBYTE ibuf, ibufmax;
- DWORD bitbuf;
- UINT bitnum;
- UINT lastnode, nodecount;
+ uint8 *ibuf, *ibufmax;
+ uint32 bitbuf;
+ int bitnum;
+ int lastnode, nodecount;
DMF_HNODE nodes[256];
} DMF_HTREE;
-#pragma pack()
-
// DMF Huffman ReadBits
BYTE DMFReadBits(DMF_HTREE *tree, UINT nbits)
//-------------------------------------------
{
- BYTE x = 0, bitv = 1;
+ uint8 x = 0, bitv = 1;
while (nbits--)
{
if (tree->bitnum)
@@ -608,8 +1065,8 @@
void DMFNewNode(DMF_HTREE *tree)
//------------------------------
{
- BYTE isleft, isright;
- UINT actnode;
+ uint8 isleft, isright;
+ int actnode;
actnode = tree->nodecount;
if (actnode > 255) return;
@@ -622,7 +1079,7 @@
tree->lastnode = tree->nodecount;
if (isleft)
{
- tree->nodes[actnode].left = tree->lastnode;
+ tree->nodes[actnode].left = (int16)tree->lastnode;
DMFNewNode(tree);
} else
{
@@ -631,7 +1088,7 @@
tree->lastnode = tree->nodecount;
if (isright)
{
- tree->nodes[actnode].right = tree->lastnode;
+ tree->nodes[actnode].right = (int16)tree->lastnode;
DMFNewNode(tree);
} else
{
@@ -640,19 +1097,20 @@
}
-int DMFUnpack(LPBYTE psample, LPBYTE ibuf, LPBYTE ibufmax, UINT maxlen)
-//----------------------------------------------------------------------
+int DMFUnpack(LPBYTE psample, uint8 *ibuf, uint8 *ibufmax, UINT maxlen)
+//---------------------------------------------------------------------
{
DMF_HTREE tree;
- UINT actnode;
- BYTE value, sign, delta = 0;
+ int actnode;
+ uint8 value, sign, delta = 0;
MemsetZero(tree);
tree.ibuf = ibuf;
tree.ibufmax = ibufmax;
DMFNewNode(&tree);
value = 0;
- for (UINT i=0; i<maxlen; i++)
+
+ for (int i = 0; i < maxlen; i++)
{
actnode = 0;
sign = DMFReadBits(&tree, 1);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-11 16:44:14
|
Revision: 845
http://modplug.svn.sourceforge.net/modplug/?rev=845&view=rev
Author: saga-games
Date: 2011-04-11 16:44:07 +0000 (Mon, 11 Apr 2011)
Log Message:
-----------
[Ref] TryWriteEffect can now also try to write an effect on a previous row if there's no space left on the current row
[Fix] MPT hack detector: It was possible that the log said "no hacks found" if only invalid pattern commands were found.
[Fix] IT Compatibility: Panning slides with both parameter nibbles set were not ignored.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/MPTHacks.cpp
trunk/OpenMPT/mptrack/ModConvert.cpp
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Snd_fx.cpp
trunk/OpenMPT/soundlib/Sndfile.h
trunk/OpenMPT/soundlib/modcommand.cpp
Modified: trunk/OpenMPT/mptrack/MPTHacks.cpp
===================================================================
--- trunk/OpenMPT/mptrack/MPTHacks.cpp 2011-04-09 17:16:43 UTC (rev 844)
+++ trunk/OpenMPT/mptrack/MPTHacks.cpp 2011-04-11 16:44:07 UTC (rev 845)
@@ -157,7 +157,10 @@
foundHere = false;
m_SndFile.Patterns.ForEachModCommand(FixHackedPatterns(originalSpecs, m_SndFile.GetType(), autofix, &foundHere));
if(foundHere)
+ {
AddToLog("Found invalid pattern commands\n");
+ foundHacks = true;
+ }
// Check for pattern names
foundHere = false;
Modified: trunk/OpenMPT/mptrack/ModConvert.cpp
===================================================================
--- trunk/OpenMPT/mptrack/ModConvert.cpp 2011-04-09 17:16:43 UTC (rev 844)
+++ trunk/OpenMPT/mptrack/ModConvert.cpp 2011-04-11 16:44:07 UTC (rev 845)
@@ -141,7 +141,7 @@
// try to save short patterns by inserting a pattern break.
if(m_SndFile.Patterns[nPat].GetNumRows() < 64)
{
- m_SndFile.TryWriteEffect(nPat, m_SndFile.Patterns[nPat].GetNumRows() - 1, CMD_PATTERNBREAK, 0, false, CHANNELINDEX_INVALID, false, true);
+ m_SndFile.TryWriteEffect(nPat, m_SndFile.Patterns[nPat].GetNumRows() - 1, CMD_PATTERNBREAK, 0, false, CHANNELINDEX_INVALID, false, weTryNextRow);
}
m_SndFile.Patterns[nPat].Resize(64, false);
CHANGEMODTYPE_WARNING(wResizedPatterns);
@@ -246,7 +246,7 @@
}
if(addBreak)
{
- m_SndFile.TryWriteEffect(nPat, m_SndFile.Patterns[nPat].GetNumRows() - 1, CMD_PATTERNBREAK, 0, false, CHANNELINDEX_INVALID, false, false);
+ m_SndFile.TryWriteEffect(nPat, m_SndFile.Patterns[nPat].GetNumRows() - 1, CMD_PATTERNBREAK, 0, false, CHANNELINDEX_INVALID, false, weIgnore);
}
}
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2011-04-09 17:16:43 UTC (rev 844)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2011-04-11 16:44:07 UTC (rev 845)
@@ -1282,7 +1282,7 @@
GetLengthType length = m_SndFile.GetLength(eNoAdjust);
if(length.endOrder != ORDERINDEX_INVALID && length.endRow != ROWINDEX_INVALID)
{
- result = m_SndFile.TryWriteEffect(m_SndFile.Order[length.endOrder], length.endRow, CMD_POSITIONJUMP, m_SndFile.m_nRestartPos, false, CHANNELINDEX_INVALID, false, true);
+ result = m_SndFile.TryWriteEffect(m_SndFile.Order[length.endOrder], length.endRow, CMD_POSITIONJUMP, m_SndFile.m_nRestartPos, false, CHANNELINDEX_INVALID, false, weTryNextRow);
}
m_SndFile.m_nRestartPos = 0;
return result;
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2011-04-09 17:16:43 UTC (rev 844)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2011-04-11 16:44:07 UTC (rev 845)
@@ -775,14 +775,14 @@
for(CHANNELINDEX nChn = 0; nChn < m_nChannels; nChn++)
{
if(subsongs[i].channelSurround[nChn] == true)
- TryWriteEffect(startPattern, 0, CMD_S3MCMDEX, 0x91, false, nChn, false, true);
+ TryWriteEffect(startPattern, 0, CMD_S3MCMDEX, 0x91, false, nChn, false, weTryNextRow);
else
- TryWriteEffect(startPattern, 0, CMD_PANNING8, subsongs[i].channelPanning[nChn], false, nChn, false, true);
+ TryWriteEffect(startPattern, 0, CMD_PANNING8, subsongs[i].channelPanning[nChn], false, nChn, false, weTryNextRow);
}
}
// 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);
+ TryWriteEffect(startPattern, 0, CMD_SPEED, subsongs[i].defaultSpeed, false, CHANNELINDEX_INVALID, false, weTryNextRow);
+ TryWriteEffect(startPattern, 0, CMD_TEMPO, subsongs[i].defaultTempo, false, CHANNELINDEX_INVALID, false, weTryNextRow);
// don't write channel volume for now, as it's always set to 100% anyway
@@ -800,7 +800,7 @@
break;
}
}
- TryWriteEffect(endPattern, lastRow, CMD_POSITIONJUMP, (BYTE)subsongs[i].restartPos, false, CHANNELINDEX_INVALID, false, true);
+ TryWriteEffect(endPattern, lastRow, CMD_POSITIONJUMP, (BYTE)subsongs[i].restartPos, false, CHANNELINDEX_INVALID, false, weTryNextRow);
}
}
}
@@ -1194,7 +1194,7 @@
}
// Pattern break for short patterns (so saving the modules as S3M won't break it)
if(phdr->numRows != 64)
- TryWriteEffect(nPat, phdr->numRows - 1, CMD_PATTERNBREAK, 0, false, CHANNELINDEX_INVALID, false, false);
+ TryWriteEffect(nPat, phdr->numRows - 1, CMD_PATTERNBREAK, 0, false, CHANNELINDEX_INVALID, false, weTryNextRow);
dwMemPos = dwNextPattern;
if(dwMemPos > dwPatEndPos) break;
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-04-09 17:16:43 UTC (rev 844)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-04-11 16:44:07 UTC (rev 845)
@@ -2643,8 +2643,15 @@
{
if (!(m_dwSongFlags & SONG_FIRSTTICK))
{
- if (param & 0x0F) nPanSlide = (int)((param & 0x0F) << 2);
- else nPanSlide = -(int)((param & 0xF0) >> 2);
+ if (param & 0x0F)
+ {
+ if(!IsCompatibleMode(TRK_IMPULSETRACKER) || (param & 0xF0) == 0)
+ nPanSlide = (int)((param & 0x0F) << 2);
+ } else
+ {
+ if(!IsCompatibleMode(TRK_IMPULSETRACKER) || (param & 0x0F) == 0)
+ nPanSlide = -(int)((param & 0xF0) >> 2);
+ }
}
}
} else
@@ -2654,13 +2661,11 @@
// IT compatibility: Ignore slide commands with both nibbles set.
if (param & 0x0F)
{
- if(!IsCompatibleMode(TRK_IMPULSETRACKER) || (param & 0xF0) == 0)
- nPanSlide = -(int)((param & 0x0F) << 2);
+ nPanSlide = -(int)((param & 0x0F) << 2);
}
else
{
- if(!IsCompatibleMode(TRK_IMPULSETRACKER) || (param & 0x0F) == 0)
- nPanSlide = (int)((param & 0xF0) >> 2);
+ nPanSlide = (int)((param & 0xF0) >> 2);
}
// XM compatibility: FT2's panning slide is not as deep
if(IsCompatibleMode(TRK_FASTTRACKER2))
@@ -3157,7 +3162,7 @@
pChn->m_nPlugParamValueStep = (float)((int)dwParam - pChn->m_nPlugInitialParamValue) / (float)m_nMusicSpeed;
}
//update param on all ticks
- pChn->nCutOff = (BYTE) (pChn->m_nPlugInitialParamValue + (m_nTickCount + 1 ) *pChn->m_nPlugParamValueStep + 0.5);
+ pChn->nCutOff = (BYTE) (pChn->m_nPlugInitialParamValue + (m_nTickCount + 1) * pChn->m_nPlugParamValueStep + 0.5);
}
pChn->nRestoreCutoffOnNewNote = 0;
}
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2011-04-09 17:16:43 UTC (rev 844)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2011-04-11 16:44:07 UTC (rev 845)
@@ -511,6 +511,15 @@
};
+// Row advance mode for TryWriteEffect()
+enum writeEffectAllowRowChange
+{
+ weIgnore, // If effect can't be written, abort.
+ weTryNextRow, // If effect can't be written, try next row.
+ weTryPreviousRow, // If effect can't be written, try previous row.
+};
+
+
//Note: These are bit indeces. MSF <-> Mod(Specific)Flag.
//If changing these, ChangeModTypeTo() might need modification.
const BYTE MSF_COMPATIBLE_PLAY = 0; //IT/MPT/XM
@@ -922,7 +931,7 @@
UINT GetNumTicksOnCurrentRow() { return m_nMusicSpeed * (m_nPatternDelay + 1) + m_nFrameDelay; };
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);
+ bool TryWriteEffect(PATTERNINDEX nPat, ROWINDEX nRow, BYTE nEffect, BYTE nParam, bool bIsVolumeEffect, CHANNELINDEX nChn = CHANNELINDEX_INVALID, bool bAllowMultipleEffects = true, writeEffectAllowRowChange allowRowChange = weIgnore, bool bRetry = true);
// Read/Write sample functions
char GetDeltaValue(char prev, UINT n) const { return (char)(prev + CompressionTable[n & 0x0F]); }
Modified: trunk/OpenMPT/soundlib/modcommand.cpp
===================================================================
--- trunk/OpenMPT/soundlib/modcommand.cpp 2011-04-09 17:16:43 UTC (rev 844)
+++ trunk/OpenMPT/soundlib/modcommand.cpp 2011-04-11 16:44:07 UTC (rev 845)
@@ -674,12 +674,12 @@
bIsVolumeEffect - Indicates whether the given effect is a volume column 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). Useful for f.e. tempo effects.
- bAllowNextRow - Indicates whether it is allowed to use the next row if there's no space for the effect
+ allowRowChange - Indicates whether it is allowed to use the next or previous 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)
NOTE: Effect remapping is only implemented for a few basic effects.
*/
-bool CSoundFile::TryWriteEffect(PATTERNINDEX nPat, ROWINDEX nRow, BYTE nEffect, BYTE nParam, bool bIsVolumeEffect, CHANNELINDEX nChn, bool bAllowMultipleEffects, bool bAllowNextRow, bool bRetry)
-//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+bool CSoundFile::TryWriteEffect(PATTERNINDEX nPat, ROWINDEX nRow, BYTE nEffect, BYTE nParam, bool bIsVolumeEffect, CHANNELINDEX nChn, bool bAllowMultipleEffects, writeEffectAllowRowChange allowRowChange, bool bRetry)
+//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{
// First, reject invalid parameters.
if(!Patterns.IsValidIndex(nPat) || nRow >= Patterns[nPat].GetNumRows() || (nChn >= GetNumChannels() && nChn != CHANNELINDEX_INVALID))
@@ -810,14 +810,17 @@
}
if(nNewEffect != CMD_NONE)
{
- if(TryWriteEffect(nPat, nRow, nNewEffect, nParam, !bIsVolumeEffect, nChn, bAllowMultipleEffects, bAllowNextRow, false) == true) return true;
+ if(TryWriteEffect(nPat, nRow, nNewEffect, nParam, !bIsVolumeEffect, nChn, bAllowMultipleEffects, allowRowChange, 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()))
+ if(allowRowChange == weTryNextRow && (nRow + 1 < Patterns[nPat].GetNumRows()))
{
- return TryWriteEffect(nPat, nRow + 1, nEffect, nParam, bIsVolumeEffect, nChn, bAllowMultipleEffects, bAllowNextRow, bRetry);
+ return TryWriteEffect(nPat, nRow + 1, nEffect, nParam, bIsVolumeEffect, nChn, bAllowMultipleEffects, allowRowChange, bRetry);
+ } else if(allowRowChange == weTryPreviousRow && (nRow > 0))
+ {
+ return TryWriteEffect(nPat, nRow - 1, nEffect, nParam, bIsVolumeEffect, nChn, bAllowMultipleEffects, allowRowChange, bRetry);
}
return false;
@@ -859,7 +862,7 @@
{
// hack for people who can't type F twice :)
*e = VOLCMD_TONEPORTAMENTO;
- *p = 0xFF;
+ *p = 9;
return true;
}
for (uint8 n = 0; n < 10; n++)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-09 17:16:50
|
Revision: 844
http://modplug.svn.sourceforge.net/modplug/?rev=844&view=rev
Author: saga-games
Date: 2011-04-09 17:16:43 +0000 (Sat, 09 Apr 2011)
Log Message:
-----------
[Imp] DMF Loader: Some more small improvements (fake support for vibrato / tremolo / tremor)
[Fix] VST Editor: Fixed note handling with plugins that actually don't support MIDI input (http://bugs.openmpt.org/view.php?id=102)
[Fix] Mod Conversion: Sustain loop conversion was all wrong + some minor fixes
Modified Paths:
--------------
trunk/OpenMPT/mptrack/AbstractVstEditor.cpp
trunk/OpenMPT/mptrack/ModConvert.cpp
trunk/OpenMPT/soundlib/LOAD_DMF.CPP
trunk/OpenMPT/soundlib/Snd_defs.h
Modified: trunk/OpenMPT/mptrack/AbstractVstEditor.cpp
===================================================================
--- trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2011-04-08 22:25:07 UTC (rev 843)
+++ trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2011-04-09 17:16:43 UTC (rev 844)
@@ -383,7 +383,9 @@
}
} else
{
- return true;
+ // used to return true but that doesn't make sense to me.
+ // if this is true, random (sample) channels will be retriggered when pressing notes in the editor...
+ return false;
}
}
Modified: trunk/OpenMPT/mptrack/ModConvert.cpp
===================================================================
--- trunk/OpenMPT/mptrack/ModConvert.cpp 2011-04-08 22:25:07 UTC (rev 843)
+++ trunk/OpenMPT/mptrack/ModConvert.cpp 2011-04-09 17:16:43 UTC (rev 844)
@@ -53,7 +53,7 @@
// shorten instrument envelope if necessary (for mod conversion)
const UINT iEnvMax = pSndFile->GetModSpecifications().envelopePointsMax;
- #define TRIMENV(nPat) if(nPat > iEnvMax) { nPat = iEnvMax; CHANGEMODTYPE_WARNING(wTrimmedEnvelopes); }
+ #define TRIMENV(iEnvLen) if(iEnvLen > iEnvMax) { iEnvLen = iEnvMax; CHANGEMODTYPE_WARNING(wTrimmedEnvelopes); }
TRIMENV(mptEnv->nNodes);
TRIMENV(mptEnv->nLoopStart);
@@ -62,9 +62,11 @@
TRIMENV(mptEnv->nSustainEnd);
if(mptEnv->nReleaseNode != ENV_RELEASE_NODE_UNSET)
{
- TRIMENV(mptEnv->nReleaseNode);
- if(!pSndFile->GetModSpecifications().hasReleaseNode)
+ if(pSndFile->GetModSpecifications().hasReleaseNode)
{
+ TRIMENV(mptEnv->nReleaseNode);
+ } else
+ {
mptEnv->nReleaseNode = ENV_RELEASE_NODE_UNSET;
CHANGEMODTYPE_WARNING(wReleaseNode);
}
@@ -117,7 +119,7 @@
nResizedPatterns++;
}
- if(((m_SndFile.m_nInstruments) || (nResizedPatterns)) && (nNewType & (MOD_TYPE_MOD|MOD_TYPE_S3M)))
+ if((m_SndFile.GetNumInstruments() || nResizedPatterns) && (nNewType & (MOD_TYPE_MOD|MOD_TYPE_S3M)))
{
if(::MessageBox(NULL,
"This operation will convert all instruments to samples,\n"
@@ -145,7 +147,7 @@
CHANGEMODTYPE_WARNING(wResizedPatterns);
}
- // Removing all instrument headers
+ // Removing all instrument headers from channels
for(CHANNELINDEX nChn = 0; nChn < MAX_CHANNELS; nChn++)
{
m_SndFile.Chn[nChn].pModInstrument = nullptr;
@@ -253,8 +255,14 @@
// Do some sample conversion
- for(SAMPLEINDEX nSmp = 1; nSmp <= m_SndFile.m_nSamples; nSmp++)
+ for(SAMPLEINDEX nSmp = 1; nSmp <= m_SndFile.GetNumSamples(); nSmp++)
{
+ // Too many samples? Only 31 samples allowed in MOD format...
+ if(newTypeIsMOD && nSmp > 31 && m_SndFile.Samples[nSmp].nLength > 0)
+ {
+ CHANGEMODTYPE_WARNING(wMOD31Samples);
+ }
+
// No Bidi / Sustain loops / Autovibrato for MOD/S3M
if(newTypeIsMOD || newTypeIsS3M)
{
@@ -265,20 +273,17 @@
CHANGEMODTYPE_WARNING(wSampleBidiLoops);
}
- // Sustain loops
- if(m_SndFile.Samples[nSmp].nSustainStart || m_SndFile.Samples[nSmp].nSustainEnd)
+ // Sustain loops - convert to normal loops
+ if((m_SndFile.Samples[nSmp].uFlags & CHN_SUSTAINLOOP) != 0)
{
- // We can at least try to convert sustain loops to normal loops
- if(m_SndFile.Samples[nSmp].nLoopEnd == 0)
- {
- m_SndFile.Samples[nSmp].nSustainStart = m_SndFile.Samples[nSmp].nLoopStart;
- m_SndFile.Samples[nSmp].nSustainEnd = m_SndFile.Samples[nSmp].nLoopEnd;
- m_SndFile.Samples[nSmp].uFlags |= CHN_LOOP;
- }
- m_SndFile.Samples[nSmp].nSustainStart = m_SndFile.Samples[nSmp].nSustainEnd = 0;
- m_SndFile.Samples[nSmp].uFlags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN);
+ // We probably overwrite a normal loop here, but since sustain loops are evaluated before normal loops, this is just correct.
+ m_SndFile.Samples[nSmp].nLoopStart = m_SndFile.Samples[nSmp].nSustainStart;
+ m_SndFile.Samples[nSmp].nLoopEnd = m_SndFile.Samples[nSmp].nSustainEnd;
+ m_SndFile.Samples[nSmp].uFlags |= CHN_LOOP;
CHANGEMODTYPE_WARNING(wSampleSustainLoops);
}
+ m_SndFile.Samples[nSmp].nSustainStart = m_SndFile.Samples[nSmp].nSustainEnd = 0;
+ m_SndFile.Samples[nSmp].uFlags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN);
// Autovibrato
if(m_SndFile.Samples[nSmp].nVibDepth || m_SndFile.Samples[nSmp].nVibRate || m_SndFile.Samples[nSmp].nVibSweep)
@@ -323,10 +328,10 @@
}
}
- // Convert IT/MPT to XM (instruments)
- if(oldTypeIsIT_MPT && newTypeIsXM)
+ for(INSTRUMENTINDEX nIns = 1; nIns <= m_SndFile.GetNumInstruments(); nIns++)
{
- for(INSTRUMENTINDEX nIns = 1; nIns <= m_SndFile.GetNumInstruments(); nIns++)
+ // Convert IT/MPT to XM (fix instruments)
+ if(oldTypeIsIT_MPT && newTypeIsXM)
{
MODINSTRUMENT *pIns = m_SndFile.Instruments[nIns];
if (pIns)
@@ -358,12 +363,8 @@
pIns->nIFR &= 0x7F;
}
}
- }
-
- // Instrument tunings
- if(oldTypeIsMPT)
- {
- for(INSTRUMENTINDEX nIns = 1; nIns <= m_SndFile.GetNumInstruments(); nIns++)
+ // Convert MPT to anything - remove instrument tunings
+ if(oldTypeIsMPT)
{
if(m_SndFile.Instruments[nIns] != nullptr && m_SndFile.Instruments[nIns]->pTuning != nullptr)
{
@@ -382,12 +383,6 @@
m_SndFile.m_nSamplePreAmp = 48;
m_SndFile.m_nVSTiVolume = 48;
CHANGEMODTYPE_WARNING(wMODGlobalVars);
-
- // Too many samples?
- if(m_SndFile.m_nSamples > 31)
- {
- CHANGEMODTYPE_WARNING(wMOD31Samples);
- }
}
// Is the "restart position" value allowed in this format?
Modified: trunk/OpenMPT/soundlib/LOAD_DMF.CPP
===================================================================
--- trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2011-04-08 22:25:07 UTC (rev 843)
+++ trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2011-04-09 17:16:43 UTC (rev 844)
@@ -213,10 +213,10 @@
UINT glbinfobyte = 0;
UINT pbeat = (pt->beat & 0xf0) ? pt->beat>>4 : 8;
BOOL tempochange = (pt->beat & 0xf0) ? TRUE : FALSE;
- memset(infobyte, 0, sizeof(infobyte));
+ MemsetZero(infobyte);
for (UINT row=0; row<ticks; row++)
{
- MODCOMMAND *p = &m[row*m_nChannels];
+ MODCOMMAND *p = &m[row * m_nChannels];
// Parse track global effects
if (!glbinfobyte)
{
@@ -259,7 +259,7 @@
} else if (cmd.note >= 129 && cmd.note <= 236)
{
// "ghost notes" for portamento that are actually not played... how the hell should we treat them?!
- cmd.note += 24;
+ cmd.note = (cmd.note & 0x7F) + 24;
} else if (cmd.note == 255)
{
cmd.note = NOTE_NOTECUT;
@@ -314,8 +314,15 @@
case 5: cmd.command = CMD_PORTAMENTODOWN; cmd.param = DMFporta2MPT(eval); break;
// 6: Tone Portamento
case 6: cmd.command = CMD_TONEPORTAMENTO; cmd.param = DMFporta2MPT(eval); break;
- // 8: Vibrato
- case 8: cmd.command = CMD_VIBRATO; cmd.param = eval; break;
+ // 8: Vibrato Sine
+ // 9: Vibrato Triangle
+ // 10: Vibrato Square
+ case 8:
+ case 9:
+ case 10:
+ cmd.command = CMD_VIBRATO;
+ cmd.param = (0xF0 - (eval & 0xF0)) | ((eval & 0x0F) / 2);
+ break;
// 12: Note cut, in 1/256th rows
case 12: if (eval & 0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xc0; }
else if (!cmd.note) { cmd.note = NOTE_NOTECUT; } break;
@@ -339,6 +346,19 @@
case 2: if (eval == 0xff) break;
eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
cmd.command = CMD_VOLUMESLIDE; cmd.param = eval; break;
+ // 3: Tremor
+ case 3:
+ cmd.command = CMD_TREMOR; cmd.param = eval;
+ break;
+ // 4: Tremolo Sine
+ // 5: Tremolo Triangle
+ // 6: Tremolo Square
+ case 4:
+ case 5:
+ case 6:
+ cmd.command = CMD_TREMOLO;
+ cmd.param = (0xF0 - (eval & 0xF0)) | ((eval & 0x0F) / 2);
+ break;
// 7: Set Pan
case 7: if (!cmd.volcmd) { cmd.volcmd = VOLCMD_PANNING; cmd.vol = (eval+3)>>2; }
else { cmd.command = CMD_PANNING8; cmd.param = eval; } break;
@@ -627,7 +647,7 @@
UINT actnode;
BYTE value, sign, delta = 0;
- memset(&tree, 0, sizeof(tree));
+ MemsetZero(tree);
tree.ibuf = ibuf;
tree.ibufmax = ibufmax;
DMFNewNode(&tree);
Modified: trunk/OpenMPT/soundlib/Snd_defs.h
===================================================================
--- trunk/OpenMPT/soundlib/Snd_defs.h 2011-04-08 22:25:07 UTC (rev 843)
+++ trunk/OpenMPT/soundlib/Snd_defs.h 2011-04-09 17:16:43 UTC (rev 844)
@@ -375,6 +375,7 @@
// Release node defines
#define ENV_RELEASE_NODE_UNSET 0xFF
#define NOT_YET_RELEASED (-1)
+STATIC_ASSERT(ENV_RELEASE_NODE_UNSET > MAX_ENVPOINTS);
enum {
@@ -411,8 +412,8 @@
// MIDI Macros
#define MACRO_MASK 0x7F5F7F5F
-#define MACRO_INTERNAL 0x30463046 // internal macro, low 7 bits (f.e. cutoff, resonance, low plugin params)
-#define MACRO_INTERNALEX 0x31463046 // internal macro, high 7 bits (high plugin params)
+#define MACRO_INTERNAL 0x30463046 // internal macro (F0F0), controls lower 8 bits (f.e. cutoff, resonance, low plugin params)
+#define MACRO_INTERNALEX 0x31463046 // internal extended macro (F0F1), controls higher 8 bits (high plugin params)
// Vibrato Types
#define VIB_SINE 0
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-08 22:25:14
|
Revision: 843
http://modplug.svn.sourceforge.net/modplug/?rev=843&view=rev
Author: saga-games
Date: 2011-04-08 22:25:07 +0000 (Fri, 08 Apr 2011)
Log Message:
-----------
[Fix] J2B Loader: Empty sample slots are now treated correct in new J2B (AM) files).
[Fix] DMF Loader: Many many improvements to portamento, pattersn with variable number of tracks and other effects.
[Mod] OpenMPT: Version is now 1.19.01.01
Modified Paths:
--------------
trunk/OpenMPT/mptrack/version.h
trunk/OpenMPT/soundlib/LOAD_DMF.CPP
trunk/OpenMPT/soundlib/load_j2b.cpp
Modified: trunk/OpenMPT/mptrack/version.h
===================================================================
--- trunk/OpenMPT/mptrack/version.h 2011-04-08 22:23:19 UTC (rev 842)
+++ trunk/OpenMPT/mptrack/version.h 2011-04-08 22:25:07 UTC (rev 843)
@@ -15,7 +15,7 @@
#define VER_MAJORMAJOR 1
#define VER_MAJOR 19
#define VER_MINOR 01
-#define VER_MINORMINOR 00
+#define VER_MINORMINOR 01
//Creates version number from version parts that appears in version string.
//For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of
Modified: trunk/OpenMPT/soundlib/LOAD_DMF.CPP
===================================================================
--- trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2011-04-08 22:23:19 UTC (rev 842)
+++ trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2011-04-08 22:25:07 UTC (rev 843)
@@ -12,6 +12,9 @@
///////////////////////////////////////////////////////
#include "stdafx.h"
#include "Loaders.h"
+#ifdef MODPLUG_TRACKER
+#include "../mptrack/Moddoc.h"
+#endif // MODPLUG_TRACKER
//#define DMFLOG
@@ -86,6 +89,16 @@
#endif
+// Convert portamento value (not very accurate, to say the least)
+uint8 DMFporta2MPT(uint8 val)
+//---------------------------
+{
+ if(val <= 0x0F)
+ return (val | 0xF0);
+ else
+ return (val / 4);
+}
+
bool CSoundFile::ReadDMF(const BYTE *lpStream, const DWORD dwMemLength)
//---------------------------------------------------------------------
{
@@ -102,10 +115,25 @@
memcpy(m_szNames[0], pfh->songname, 30);
SpaceToNullStringFixed<30>(m_szNames[0]);
m_nType = MOD_TYPE_DMF;
+ m_dwSongFlags = SONG_LINEARSLIDES | SONG_ITCOMPATGXX | SONG_ITOLDEFFECTS;
m_nChannels = 0;
#ifdef DMFLOG
Log("DMF version %d: \"%s\": %d bytes (0x%04X)\n", pfh->version, m_szNames[0], dwMemLength, dwMemLength);
#endif
+
+#ifdef MODPLUG_TRACKER
+ if(GetpModDoc() != nullptr)
+ {
+ FileHistory mptHistory;
+ MemsetZero(mptHistory);
+ mptHistory.loadDate.tm_mday = CLAMP(pfh->date[0], 0, 31);
+ mptHistory.loadDate.tm_mon = CLAMP(pfh->date[1], 1, 12) - 1;
+ mptHistory.loadDate.tm_year = pfh->date[2];
+ GetpModDoc()->GetFileHistory()->clear();
+ GetpModDoc()->GetFileHistory()->push_back(mptHistory);
+ }
+#endif // MODPLUG_TRACKER
+
while (dwMemPos + 7 < dwMemLength)
{
DWORD id = *((LPDWORD)(lpStream+dwMemPos));
@@ -135,7 +163,7 @@
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] = (PATTERNINDEX)sequ->sequ[i];
+ for (UINT i = 0; i < nseq - 2; i++) Order[i] = (PATTERNINDEX)sequ->sequ[i];
}
dwMemPos += sequ->seqsize + 8;
break;
@@ -150,10 +178,12 @@
if ((patt->patsize >= dwMemLength) || (dwMemPos + patt->patsize + 8 > dwMemLength)) goto dmfexit;
numpat = patt->numpat;
if (numpat > MAX_PATTERNS) numpat = MAX_PATTERNS;
+
m_nChannels = patt->tracks;
if (m_nChannels < patt->firstpatinfo) m_nChannels = patt->firstpatinfo;
if (m_nChannels > 32) m_nChannels = 32;
if (m_nChannels < 1) m_nChannels = 1;
+
for (UINT npat=0; npat<numpat; npat++)
{
DMFTRACK *pt = (DMFTRACK *)(lpStream+dwPos);
@@ -163,13 +193,19 @@
UINT tracks = pt->tracks;
if (tracks > 32) tracks = 32;
UINT ticks = pt->ticks;
- if (ticks > 256) ticks = 256;
- if (ticks < 16) ticks = 16;
+ if (ticks > MAX_PATTERN_ROWS) ticks = MAX_PATTERN_ROWS;
+ if (ticks < 1) ticks = 1;
dwPos += 8;
if ((pt->jmpsize >= dwMemLength) || (dwPos + pt->jmpsize + 4 >= dwMemLength)) break;
if(Patterns.Insert(npat, ticks)) goto dmfexit;
MODCOMMAND *m = Patterns[npat];
+ // If pattern "width" changes, leftover voices are killed:
+ for(CHANNELINDEX nChn = tracks; nChn < m_nChannels; nChn++)
+ {
+ m[nChn].note = NOTE_NOTECUT;
+ }
+
DWORD d = dwPos;
dwPos += pt->jmpsize;
UINT ttype = 1;
@@ -217,8 +253,17 @@
if (info & 0x20)
{
cmd.note = lpStream[d++];
- if ((cmd.note) && (cmd.note < 0xfe)) cmd.note &= 0x7f;
- if ((cmd.note) && (cmd.note < 128)) cmd.note += 24;
+ if (cmd.note >= 1 && cmd.note <= 108)
+ {
+ cmd.note += 24;
+ } else if (cmd.note >= 129 && cmd.note <= 236)
+ {
+ // "ghost notes" for portamento that are actually not played... how the hell should we treat them?!
+ cmd.note += 24;
+ } else if (cmd.note == 255)
+ {
+ cmd.note = NOTE_NOTECUT;
+ }
}
// Volume
if (info & 0x10)
@@ -226,7 +271,7 @@
cmd.volcmd = VOLCMD_VOLUME;
cmd.vol = (lpStream[d++]+3)>>2;
}
- // Effect 1
+ // Effect 1 - Instrument
if (info & 0x08)
{
BYTE efx = lpStream[d++];
@@ -234,20 +279,23 @@
switch(efx)
{
// 1: Key Off
- case 1: if (!cmd.note) cmd.note = 0xFE; break;
- // 2: Set Loop
- // 4: Sample Delay
+ case 1: if (!cmd.note) cmd.note = NOTE_NOTECUT; break;
+ // 2: Stop Sample Loop
+ case 2: if (!cmd.note) cmd.note = NOTE_KEYOFF; break;
+ // 4: Sample Delay, in 1/256th rows
case 4: if (eval&0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xD0; } break;
- // 5: Retrig
+ // 5: Retrig, in 1/256th rows
case 5: if (eval&0xe0) { cmd.command = CMD_RETRIG; cmd.param = (eval>>5); } break;
// 6: Offset
case 6: cmd.command = CMD_OFFSET; cmd.param = eval; break;
+ // 10: Tekkno Invert
+ case 10: cmd.command = CMD_S3MCMDEX; cmd.param = 0x9F; break;
#ifdef DMFLOG
default: Log("FX1: %02X.%02X\n", efx, eval);
#endif
}
}
- // Effect 2
+ // Effect 2 - Note
if (info & 0x04)
{
BYTE efx = lpStream[d++];
@@ -261,22 +309,22 @@
// 3: Arpeggio
case 3: if (eval) { cmd.command = CMD_ARPEGGIO; cmd.param = eval; } break;
// 4: Portamento Up
- case 4: cmd.command = CMD_PORTAMENTOUP; cmd.param = (eval >= 0xe0) ? 0xdf : eval; break;
+ case 4: cmd.command = CMD_PORTAMENTOUP; cmd.param = DMFporta2MPT(eval); break;
// 5: Portamento Down
- case 5: cmd.command = CMD_PORTAMENTODOWN; cmd.param = (eval >= 0xe0) ? 0xdf : eval; break;
+ case 5: cmd.command = CMD_PORTAMENTODOWN; cmd.param = DMFporta2MPT(eval); break;
// 6: Tone Portamento
- case 6: cmd.command = CMD_TONEPORTAMENTO; cmd.param = eval; break;
+ case 6: cmd.command = CMD_TONEPORTAMENTO; cmd.param = DMFporta2MPT(eval); break;
// 8: Vibrato
case 8: cmd.command = CMD_VIBRATO; cmd.param = eval; break;
- // 12: Note cut
+ // 12: Note cut, in 1/256th rows
case 12: if (eval & 0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xc0; }
- else if (!cmd.note) { cmd.note = 0xfe; } break;
+ else if (!cmd.note) { cmd.note = NOTE_NOTECUT; } break;
#ifdef DMFLOG
default: Log("FX2: %02X.%02X\n", efx, eval);
#endif
}
}
- // Effect 3
+ // Effect 3 - Volume
if (info & 0x02)
{
BYTE efx = lpStream[d++];
@@ -296,7 +344,7 @@
else { cmd.command = CMD_PANNING8; cmd.param = eval; } break;
// 8: Pan Slide Left
case 8: eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
- cmd.command = CMD_PANNINGSLIDE; cmd.param = eval<<4; break;
+ cmd.command = CMD_PANNINGSLIDE; cmd.param = eval << 4; break;
// 9: Pan Slide Right
case 9: eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
cmd.command = CMD_PANNINGSLIDE; cmd.param = eval; break;
@@ -305,6 +353,21 @@
#endif
}
}
+
+ // Note without instrument == just reset pitch, do not retrigger
+ if(cmd.instr == 0 && cmd.note != NOTE_NONE && NOTE_IS_VALID(cmd.note) && cmd.command != CMD_TONEPORTAMENTO)
+ {
+ if(cmd.volcmd == VOLCMD_NONE)
+ {
+ cmd.volcmd = VOLCMD_TONEPORTAMENTO;
+ cmd.vol = 9;
+ } else
+ {
+ cmd.command = CMD_TONEPORTAMENTO;
+ cmd.param = 0xFF;
+ }
+ }
+
// Store effect
if (i < m_nChannels) p[i] = cmd;
if (d > dwPos)
@@ -389,14 +452,14 @@
DMFSAMPLE *psh = (DMFSAMPLE *)(lpStream+dwPos);
MODSAMPLE *psmp = &Samples[iSmp];
psmp->nLength = psh->len;
- psmp->nLoopStart = psh->loopstart;
- psmp->nLoopEnd = psh->loopend;
+ psmp->nSustainStart = psh->loopstart;
+ psmp->nSustainEnd = psh->loopend;
psmp->nC5Speed = psh->c3speed;
psmp->nGlobalVol = 64;
psmp->nVolume = (psh->volume) ? ((WORD)psh->volume)+1 : (WORD)256;
psmp->uFlags = (psh->flags & 2) ? CHN_16BIT : 0;
if (psmp->uFlags & CHN_16BIT) psmp->nLength >>= 1;
- if (psh->flags & 1) psmp->uFlags |= CHN_LOOP;
+ if (psh->flags & 1) psmp->uFlags |= CHN_SUSTAINLOOP;
smplflags[iSmp] = psh->flags;
dwPos += (pfh->version < 8) ? 22 : 30;
#ifdef DMFLOG
Modified: trunk/OpenMPT/soundlib/load_j2b.cpp
===================================================================
--- trunk/OpenMPT/soundlib/load_j2b.cpp 2011-04-08 22:23:19 UTC (rev 842)
+++ trunk/OpenMPT/soundlib/load_j2b.cpp 2011-04-08 22:25:07 UTC (rev 843)
@@ -35,6 +35,9 @@
#define AMCHUNKID_AI__ 0x20204941
#define AMCHUNKID_AS__ 0x20205341
+// Header flags
+#define AMHEAD_LINEAR 0x01
+
// Envelope flags
#define AMENV_ENABLED 0x01
#define AMENV_SUSTAIN 0x02
@@ -78,7 +81,7 @@
uint8 channels;
uint8 speed;
uint8 tempo;
- uint32 unknown; // 0x16078035 if original file was MOD, 0xC50100FF for everything else?
+ uint32 unknown; // 0x16078035 if original file was MOD, 0xC50100FF for everything else? it's 0xFF00FFFF in Carrotus.j2b (AMFF version)
uint8 globalvolume;
};
@@ -489,7 +492,7 @@
memcpy(m_szNames[0], mainchunk->songname, 32);
SpaceToNullStringFixed<31>(m_szNames[0]);
m_dwSongFlags = SONG_ITOLDEFFECTS | SONG_ITCOMPATGXX;
- if(!(mainchunk->flags & 0x01)) m_dwSongFlags |= SONG_LINEARSLIDES;
+ if(!(mainchunk->flags & AMHEAD_LINEAR)) m_dwSongFlags |= SONG_LINEARSLIDES;
if(mainchunk->channels < 1) return false;
m_nChannels = min(mainchunk->channels, MAX_BASECHANNELS);
m_nDefaultSpeed = mainchunk->speed;
@@ -497,7 +500,7 @@
m_nDefaultGlobalVolume = mainchunk->globalvolume << 1;
m_nSamplePreAmp = m_nVSTiVolume = 48;
m_nType = MOD_TYPE_J2B;
- ASSERT(LittleEndian(mainchunk->unknown) == 0xFF0001C5 || LittleEndian(mainchunk->unknown) == 0x35800716);
+ ASSERT(LittleEndian(mainchunk->unknown) == 0xFF0001C5 || LittleEndian(mainchunk->unknown) == 0x35800716 || LittleEndian(mainchunk->unknown) == 0xFF00FFFF);
// It seems like there's no way to differentiate between
// Muted and Surround channels (they're all 0xA0) - might
@@ -688,6 +691,11 @@
const size_t nTotalSmps = LittleEndianW(instheader->numsamples);
+ if(nTotalSmps == 0)
+ {
+ MemsetZero(pIns->Keyboard);
+ }
+
DWORD dwChunkPos;
// read sample sub-chunks (RIFF nesting ftw)
@@ -705,15 +713,16 @@
if(LittleEndian(*(uint32 *)(lpStream + dwChunkPos)) != AMCHUNKID_AS__) break;
dwChunkPos += 4;
+ // Moved this stuff here (was below the next ASSERT_CAN_READ_CHUNK) because of instrument 12 in Carrotus.j2b
+ if(m_nSamples + 1 >= MAX_SAMPLES)
+ break;
+ const SAMPLEINDEX nSmp = ++m_nSamples;
+
ASSERT_CAN_READ_CHUNK(sizeof(AMCHUNK_SAMPLE));
const AMCHUNK_SAMPLE *smpchunk = (AMCHUNK_SAMPLE *)(lpStream + dwChunkPos);
if(smpchunk->signature != AMCHUNKID_SAMP) break; // SAMP
- if(m_nSamples + 1 >= MAX_SAMPLES)
- break;
- const SAMPLEINDEX nSmp = ++m_nSamples;
-
MemsetZero(Samples[nSmp]);
memcpy(m_szNames[nSmp], smpchunk->name, 32);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-08 22:23:26
|
Revision: 842
http://modplug.svn.sourceforge.net/modplug/?rev=842&view=rev
Author: saga-games
Date: 2011-04-08 22:23:19 +0000 (Fri, 08 Apr 2011)
Log Message:
-----------
[Reg] Removed hidden INI flag to suppress warnings when encountering keymaps with unknown items. This option made sense when such files threw multiple message boxes, but now it's just one and it shouldn't be ignored...
[Fix] Note Properties: Axx is not limited to value 7F anymore for IT/S3M.
[Imp] Mod Conversion: Improved of Sxx (IT/S3M) and PC Notes.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/CommandSet.cpp
trunk/OpenMPT/mptrack/CommandSet.h
trunk/OpenMPT/mptrack/InputHandler.cpp
trunk/OpenMPT/mptrack/Moddoc.cpp
trunk/OpenMPT/soundlib/modcommand.cpp
Modified: trunk/OpenMPT/mptrack/CommandSet.cpp
===================================================================
--- trunk/OpenMPT/mptrack/CommandSet.cpp 2011-04-05 13:03:17 UTC (rev 841)
+++ trunk/OpenMPT/mptrack/CommandSet.cpp 2011-04-08 22:23:19 UTC (rev 842)
@@ -16,8 +16,6 @@
#endif
-bool CCommandSet::s_bShowErrorOnUnknownKeybinding = true;
-
CCommandSet::CCommandSet(void)
{
// Which keybinding rules to enforce?
@@ -1579,7 +1577,7 @@
l++;
}
- if(s_bShowErrorOnUnknownKeybinding && !errText.IsEmpty())
+ if(!errText.IsEmpty())
{
CString err;
err.Format("The following problems have been encountered while trying to load the key binding file %s:\n", szFilename);
Modified: trunk/OpenMPT/mptrack/CommandSet.h
===================================================================
--- trunk/OpenMPT/mptrack/CommandSet.h 2011-04-05 13:03:17 UTC (rev 841)
+++ trunk/OpenMPT/mptrack/CommandSet.h 2011-04-08 22:23:19 UTC (rev 842)
@@ -1166,7 +1166,6 @@
bool enforceRule[kNumRules];
public:
- static bool s_bShowErrorOnUnknownKeybinding;
CCommandSet(void);
~CCommandSet(void);
Modified: trunk/OpenMPT/mptrack/InputHandler.cpp
===================================================================
--- trunk/OpenMPT/mptrack/InputHandler.cpp 2011-04-05 13:03:17 UTC (rev 841)
+++ trunk/OpenMPT/mptrack/InputHandler.cpp 2011-04-08 22:23:19 UTC (rev 842)
@@ -21,7 +21,6 @@
//Init CommandSet and Load defaults
activeCommandSet = new CCommandSet();
- CCommandSet::s_bShowErrorOnUnknownKeybinding = (CMainFrame::GetMainFrame()->GetPrivateProfileLong("Misc", "ShowErrorOnUnknownKeybinding", 1, theApp.GetConfigFileName()) != 0);
CString sDefaultPath = CString(theApp.GetConfigPath()) + TEXT("Keybindings.mkb");
if (sDefaultPath.GetLength() > MAX_PATH - 1)
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2011-04-05 13:03:17 UTC (rev 841)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2011-04-08 22:23:19 UTC (rev 842)
@@ -2432,7 +2432,7 @@
break;
case CMD_SPEED:
nmin = 1;
- nmax = 0x7F;
+ nmax = 0xFF;
if (nType & MOD_TYPE_MOD) nmax = 0x20; else
if (nType & MOD_TYPE_XM) nmax = 0x1F;
break;
@@ -3074,7 +3074,7 @@
case VOLCMD_PANNING:
*prangeMax = 64;
- if (m_SndFile.m_nType & MOD_TYPE_XM)
+ if (m_SndFile.GetType() & MOD_TYPE_XM)
{
*prangeMin = 2; // 0*4+2
*prangeMax = 62; // 15*4+2
@@ -3082,7 +3082,7 @@
break;
default:
- *prangeMax = (m_SndFile.m_nType & MOD_TYPE_XM) ? 15 : 9;
+ *prangeMax = (m_SndFile.GetType() & MOD_TYPE_XM) ? 15 : 9;
}
}
return (gVolCmdInfo[ndx].dwFormats & m_SndFile.m_nType) ? TRUE : FALSE;
@@ -3166,6 +3166,7 @@
}
+
enmParameteredMacroType CModDoc::GetMacroType(CString value)
//----------------------------------------------------------
{
Modified: trunk/OpenMPT/soundlib/modcommand.cpp
===================================================================
--- trunk/OpenMPT/soundlib/modcommand.cpp 2011-04-05 13:03:17 UTC (rev 841)
+++ trunk/OpenMPT/soundlib/modcommand.cpp 2011-04-08 22:23:19 UTC (rev 842)
@@ -51,10 +51,10 @@
case 0x40: m->param = (m->param & 0x0F) | 0x70; break;
case 0x50:
case 0x60:
- case 0x70: if(((m->param & 0xF0) == 0x70) && ((m->param & 0x0F) > 0x0A)) { m->command = CMD_NONE; break; } // no pitch env in XM format
case 0x90:
case 0xA0: m->command = CMD_XFINEPORTAUPDOWN; break;
case 0xB0: m->param = (m->param & 0x0F) | 0x60; break;
+ case 0x70: m->command = CMD_NONE; // No NNA / envelope control in MOD/XM format
// rest are the same
}
}
@@ -106,8 +106,18 @@
{
if(m->IsPcNote())
{
+ MODCOMMAND::COMMAND newcommand = (m->note == NOTE_PC) ? CMD_MIDI : CMD_SMOOTHMIDI;
+ if(!GetModSpecifications(nNewType).HasCommand(newcommand))
+ {
+ newcommand = CMD_MIDI; // assuming that this was CMD_SMOOTHMIDI
+ }
+ if(!GetModSpecifications(nNewType).HasCommand(newcommand))
+ {
+ newcommand = CMD_NONE;
+ }
+
m->param = (BYTE)(min(MODCOMMAND::maxColumnValue, m->GetValueEffectCol()) * 0x7F / MODCOMMAND::maxColumnValue);
- m->command = (m->note == NOTE_PC) ? CMD_MIDI : CMD_SMOOTHMIDI; // might be removed later
+ m->command = newcommand; // might be removed later
m->volcmd = VOLCMD_NONE;
m->note = NOTE_NONE;
m->instr = 0;
@@ -298,11 +308,21 @@
switch(m->command)
{
case CMD_S3MCMDEX:
- if(m->param == 0x91)
+ switch(m->param & 0xF0)
{
- // surround remap (this is the "official" command)
- m->command = CMD_PANNING8;
- m->param = 0xA4;
+ case 0x70: m->command = CMD_NONE; break; // No NNA / envelope control in S3M format
+ case 0x90:
+ if(m->param == 0x91)
+ {
+ // surround remap (this is the "official" command)
+ m->command = CMD_PANNING8;
+ m->param = 0xA4;
+ } else if(m->param == 0x90)
+ {
+ m->command = CMD_PANNING8;
+ m->param = 0x40;
+ }
+ break;
}
break;
case CMD_SMOOTHMIDI:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-05 13:03:27
|
Revision: 841
http://modplug.svn.sourceforge.net/modplug/?rev=841&view=rev
Author: saga-games
Date: 2011-04-05 13:03:17 +0000 (Tue, 05 Apr 2011)
Log Message:
-----------
[Mod] Update Check: On first run, a hint is shown so people don't have to wonder what their firewall is doing.
[Mod] Colour Setup: Changed order of channel separator colours.
Modified Paths:
--------------
trunk/OpenMPT/installer/install.iss
trunk/OpenMPT/mptrack/MainFrm.cpp
trunk/OpenMPT/mptrack/Moptions.cpp
trunk/OpenMPT/mptrack/UpdateCheck.cpp
trunk/OpenMPT/mptrack/UpdateCheck.h
Modified: trunk/OpenMPT/installer/install.iss
===================================================================
--- trunk/OpenMPT/installer/install.iss 2011-04-03 21:35:05 UTC (rev 840)
+++ trunk/OpenMPT/installer/install.iss 2011-04-05 13:03:17 UTC (rev 841)
@@ -238,6 +238,10 @@
if(not IsTaskSelected('update_c')) then
begin
SetIniString('Update', 'UpdateCheckPeriod', '0', INIFile);
+ end else
+ begin
+ SetIniString('Update', 'UpdateCheckPeriod', '7', INIFile);
+ //SetIniString('Update', 'LastUpdateCheck', GetDateTimeString('yyyy-mm-dd hh:nn', #0, #0), INIFile);
end;
// Scan for pre-installed VST plugins
Modified: trunk/OpenMPT/mptrack/MainFrm.cpp
===================================================================
--- trunk/OpenMPT/mptrack/MainFrm.cpp 2011-04-03 21:35:05 UTC (rev 840)
+++ trunk/OpenMPT/mptrack/MainFrm.cpp 2011-04-05 13:03:17 UTC (rev 841)
@@ -419,7 +419,8 @@
(
outTime,
GetPrivateProfileInt("Update", "UpdateCheckPeriod", CUpdateCheck::GetUpdateCheckPeriod(), iniFile),
- GetPrivateProfileCString("Update", "UpdateURL", CUpdateCheck::GetUpdateURL(), iniFile)
+ GetPrivateProfileCString("Update", "UpdateURL", CUpdateCheck::GetUpdateURL(), iniFile),
+ GetPrivateProfileInt("Update", "ShowUpdateHint", CUpdateCheck::GetShowUpdateHint() ? 1 : 0, iniFile) ? true : false
);
}
@@ -1021,8 +1022,9 @@
outDate.Format("%04d-%02d-%02d %02d:%02d", lastUpdate->tm_year + 1900, lastUpdate->tm_mon + 1, lastUpdate->tm_mday, lastUpdate->tm_hour, lastUpdate->tm_min);
}
WritePrivateProfileString("Update", "LastUpdateCheck", outDate, iniFile);
- WritePrivateProfileDWord("Update", "UpdateCheckPeriod", CUpdateCheck::GetUpdateCheckPeriod(), iniFile);
+ WritePrivateProfileLong("Update", "UpdateCheckPeriod", CUpdateCheck::GetUpdateCheckPeriod(), iniFile);
WritePrivateProfileString("Update", "UpdateURL", CUpdateCheck::GetUpdateURL(), iniFile);
+ WritePrivateProfileLong("Update", "ShowUpdateHint", CUpdateCheck::GetShowUpdateHint() ? 1 : 0, iniFile);
}
CHAR s[16];
Modified: trunk/OpenMPT/mptrack/Moptions.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moptions.cpp 2011-04-03 21:35:05 UTC (rev 840)
+++ trunk/OpenMPT/mptrack/Moptions.cpp 2011-04-05 13:03:17 UTC (rev 841)
@@ -29,14 +29,13 @@
{"Note Highlight", 0, MODCOLOR_NOTE, MODCOLOR_INSTRUMENT, MODCOLOR_VOLUME, "Note:", "Instrument:", "Volume:"},
{"Effect Highlight",0, MODCOLOR_PANNING, MODCOLOR_PITCH, MODCOLOR_GLOBALS, "Panning Effects:", "Pitch Effects:", "Global Effects:"},
{"Invalid Commands",0, MODCOLOR_DODGY_COMMANDS, 0, 0, "Invalid Note:", NULL, NULL},
- {"Channel Separator",0, MODCOLOR_SEPSHADOW, MODCOLOR_SEPFACE, MODCOLOR_SEPHILITE, "Shadow:", "Face:", "Highlight:"},
+ {"Channel Separator",0, MODCOLOR_SEPHILITE, MODCOLOR_SEPFACE, MODCOLOR_SEPSHADOW, "Highlight:", "Face:", "Shadow:"},
{"Next/Prev Pattern",0, MODCOLOR_BLENDCOLOR, 0, 0, "Blend color:", NULL, NULL},
{"Sample Editor", 1, MODCOLOR_SAMPLE, 0, 0, "Sample Data:", NULL, NULL},
{"Instrument Editor",2, MODCOLOR_ENVELOPES, 0, 0, "Envelopes:", NULL, NULL},
{"VU-Meters", 0, MODCOLOR_VUMETER_HI, MODCOLOR_VUMETER_MED, MODCOLOR_VUMETER_LO, "Hi:", "Med:", "Lo:"}
};
-#define NUMCOLORDEFS (sizeof(gColorDefs)/sizeof(MPTCOLORDEF))
#define PREVIEWBMP_WIDTH 88
#define PREVIEWBMP_HEIGHT 39
@@ -85,7 +84,7 @@
CPropertyPage::OnInitDialog();
m_pPreviewDib = LoadDib(MAKEINTRESOURCE(IDB_COLORSETUP));
memcpy(CustomColors, CMainFrame::rgbCustomColors, sizeof(CustomColors));
- for (UINT i=0; i<NUMCOLORDEFS; i++)
+ for (UINT i = 0; i < CountOf(gColorDefs); i++)
{
m_ComboItem.SetItemData(m_ComboItem.AddString(gColorDefs[i].pszName), i);
}
Modified: trunk/OpenMPT/mptrack/UpdateCheck.cpp
===================================================================
--- trunk/OpenMPT/mptrack/UpdateCheck.cpp 2011-04-03 21:35:05 UTC (rev 840)
+++ trunk/OpenMPT/mptrack/UpdateCheck.cpp 2011-04-05 13:03:17 UTC (rev 841)
@@ -21,6 +21,7 @@
time_t CUpdateCheck::lastUpdateCheck = 0;
int CUpdateCheck::updateCheckPeriod = 7;
CString CUpdateCheck::updateBaseURL = "http://update.openmpt.org/check/%s";
+bool CUpdateCheck::showUpdateHint = true;
CUpdateCheck::CUpdateCheck(const bool autoUpdate)
@@ -73,7 +74,22 @@
caller->Terminate();
return 0;
}
+
+ // Never ran update checks before, so we notify the user of automatic update checks.
+ if(CUpdateCheck::showUpdateHint)
+ {
+ CString msg;
+ msg.Format("OpenMPT would like to check for updates now, proceed?\n\nNote: In the future, OpenMPT will check for updates every %d days. If you do not want this, you can disable update checks in the setup.", CUpdateCheck::updateCheckPeriod);
+ if(::MessageBox(0, msg, "OpenMPT Internet Update", MB_YESNO | MB_ICONQUESTION) == IDNO)
+ {
+ CUpdateCheck::showUpdateHint = false;
+ caller->Terminate();
+ return 0;
+ }
+
+ }
}
+ CUpdateCheck::showUpdateHint = false;
const CString userAgent = CString("OpenMPT ") + MptVersion::str;
CString updateURL;
@@ -123,9 +139,10 @@
// Download data.
CString resultData = "";
char *downloadBuffer = new char[DOWNLOAD_BUFFER_SIZE];
- DWORD availableSize = 0, bytesRead = 0;
+ DWORD availableSize, bytesRead;
do
{
+ // Query number of available bytes to download
if(InternetQueryDataAvailable(caller->connectionHandle, &availableSize, 0, NULL) == FALSE)
{
caller->Die("Error while downloading update information data:\n", GetLastError());
@@ -133,12 +150,15 @@
LimitMax(availableSize, (DWORD)DOWNLOAD_BUFFER_SIZE);
+ // Put downloaded bytes into our buffer
if(InternetReadFile(caller->connectionHandle, downloadBuffer, availableSize, &bytesRead) == FALSE)
{
caller->Die("Error while downloading update information data:\n", GetLastError());
}
resultData.Append(downloadBuffer, availableSize);
+ Sleep(1);
+
} while(bytesRead != 0);
delete[] downloadBuffer;
@@ -302,7 +322,7 @@
CString updateURL;
GetDlgItemText(IDC_EDIT1, updateURL);
- CUpdateCheck::SetUpdateSettings(CUpdateCheck::GetLastUpdateCheck(), updateCheckPeriod, updateURL);
+ CUpdateCheck::SetUpdateSettings(CUpdateCheck::GetLastUpdateCheck(), updateCheckPeriod, updateURL, CUpdateCheck::GetShowUpdateHint());
CPropertyPage::OnOK();
}
@@ -319,7 +339,6 @@
void CUpdateSetupDlg::OnCheckNow()
//--------------------------------
{
- CUpdateCheck *updateCheck = CUpdateCheck::Create(false);
- updateCheck->DoUpdateCheck();
+ CMainFrame::GetMainFrame()->PostMessage(WM_COMMAND, ID_INTERNETUPDATE);
}
Modified: trunk/OpenMPT/mptrack/UpdateCheck.h
===================================================================
--- trunk/OpenMPT/mptrack/UpdateCheck.h 2011-04-03 21:35:05 UTC (rev 840)
+++ trunk/OpenMPT/mptrack/UpdateCheck.h 2011-04-05 13:03:17 UTC (rev 841)
@@ -34,7 +34,9 @@
static time_t GetLastUpdateCheck() { return lastUpdateCheck; };
static int GetUpdateCheckPeriod() { return updateCheckPeriod; };
static CString GetUpdateURL() { return updateBaseURL; };
- static void SetUpdateSettings(time_t last, int period, CString url) { lastUpdateCheck = last; updateCheckPeriod = period; updateBaseURL = url; };
+ static bool GetShowUpdateHint() { return showUpdateHint; };
+ static void SetUpdateSettings(time_t last, int period, CString url, bool showHint)
+ { lastUpdateCheck = last; updateCheckPeriod = period; updateBaseURL = url; showUpdateHint = showHint; };
protected:
@@ -42,6 +44,7 @@
static time_t lastUpdateCheck; // Time of last successful update check
static int updateCheckPeriod; // Check for updates every x days
static CString updateBaseURL; // URL where the version check should be made.
+ static bool showUpdateHint; // Show hint on first automatic update
bool isAutoUpdate; // Are we running an automatic update check?
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-03 21:35:12
|
Revision: 840
http://modplug.svn.sourceforge.net/modplug/?rev=840&view=rev
Author: saga-games
Date: 2011-04-03 21:35:05 +0000 (Sun, 03 Apr 2011)
Log Message:
-----------
[New] The update checker is back, this time not using WinHTTP but WinINet and with much cleaner code and a proper configuration page.
[New] ... Actually I forgot to commit mptrack.rc in revision 836, so there is no "Create instrument from plugin" command in OpenMPT 1.19.01.00. :-( Consider this to be my april fool's joke, even if it wasn't meant to be. :-P
Revision Links:
--------------
http://modplug.svn.sourceforge.net/modplug/?rev=836&view=rev
Modified Paths:
--------------
trunk/OpenMPT/installer/install.iss
trunk/OpenMPT/mptrack/MainFrm.cpp
trunk/OpenMPT/mptrack/Mainfrm.h
trunk/OpenMPT/mptrack/Moptions.h
trunk/OpenMPT/mptrack/Mptrack.cpp
trunk/OpenMPT/mptrack/Mptrack.h
trunk/OpenMPT/mptrack/mptrack.rc
trunk/OpenMPT/mptrack/mptrack.vcproj
trunk/OpenMPT/mptrack/mptrack_08.vcproj
trunk/OpenMPT/mptrack/resource.h
Added Paths:
-----------
trunk/OpenMPT/mptrack/UpdateCheck.cpp
trunk/OpenMPT/mptrack/UpdateCheck.h
Modified: trunk/OpenMPT/installer/install.iss
===================================================================
--- trunk/OpenMPT/installer/install.iss 2011-04-01 15:43:38 UTC (rev 839)
+++ trunk/OpenMPT/installer/install.iss 2011-04-03 21:35:05 UTC (rev 840)
@@ -45,6 +45,7 @@
#ifdef DOWNLOAD_MO3
Name: downloadmo3; Description: Download unmo3 (library needed for reading MO3 files, recommended); Check: not IsUNMO3Installed; GroupDescription: Options:
#endif
+Name: update_c; Description: Automatically check for updates; GroupDescription: Options:
Name: portable; Description: Portable mode (use program folder for storing settings, no registry changes); GroupDescription: Options:; Flags: unchecked
Name: vst_scan; Description: Scan for previously installed VST plugins; GroupDescription: Options:; Flags: unchecked
; file associations - put this below all other [tasks]!
@@ -233,6 +234,12 @@
SetIniString('Paths', 'Key_Config_File', keyboardFilepath, INIFile);
end;
+ // Update check
+ if(not IsTaskSelected('update_c')) then
+ begin
+ SetIniString('Update', 'UpdateCheckPeriod', '0', INIFile);
+ end;
+
// Scan for pre-installed VST plugins
if(IsTaskSelected('vst_scan')) then
begin
Modified: trunk/OpenMPT/mptrack/MainFrm.cpp
===================================================================
--- trunk/OpenMPT/mptrack/MainFrm.cpp 2011-04-01 15:43:38 UTC (rev 839)
+++ trunk/OpenMPT/mptrack/MainFrm.cpp 2011-04-03 21:35:05 UTC (rev 840)
@@ -24,6 +24,7 @@
#include <direct.h>
#include "version.h"
#include "ctrl_pat.h"
+#include "UpdateCheck.h"
#ifdef _DEBUG
#define new DEBUG_NEW
@@ -106,6 +107,7 @@
ON_MESSAGE(WM_MOD_INVALIDATEPATTERNS, OnInvalidatePatterns)
ON_MESSAGE(WM_MOD_SPECIALKEY, OnSpecialKey)
ON_MESSAGE(WM_MOD_KEYCOMMAND, OnCustomKeyMsg) //rewbs.customKeys
+ ON_COMMAND(ID_INTERNETUPDATE, OnInternetUpdate)
//}}AFX_MSG_MAP
ON_WM_INITMENU()
ON_WM_KILLFOCUS() //rewbs.fix3116
@@ -141,7 +143,7 @@
HHOOK CMainFrame::ghKbdHook = NULL;
CString CMainFrame::gcsPreviousVersion = "";
CString CMainFrame::gcsInstallGUID = "";
-int CMainFrame::gnCheckForUpdates = 1;
+
DWORD CMainFrame::gnHotKeyMask = 0;
// Audio Setup
//rewbs.resamplerConf
@@ -384,7 +386,6 @@
vIniVersion = MptVersion::ToNum(gcsPreviousVersion);
gcsInstallGUID = GetPrivateProfileCString("Version", "InstallGUID", "", iniFile);
- gnCheckForUpdates = GetPrivateProfileInt("Version", "CheckForUpdates", 1, iniFile);
gbMdiMaximize = GetPrivateProfileLong("Display", "MDIMaximize", true, iniFile);
glTreeWindowWidth = GetPrivateProfileLong("Display", "MDITreeWidth", 160, iniFile);
glTreeSplitRatio = GetPrivateProfileLong("Display", "MDITreeRatio", 128, iniFile);
@@ -401,6 +402,27 @@
gnPlugWindowLast = GetPrivateProfileDWord("Display", "PlugSelectWindowLast", 0, iniFile);
gnMsgBoxVisiblityFlags = GetPrivateProfileDWord("Display", "MsgBoxVisibilityFlags", uint32_max, iniFile);
+ // Internet Update
+ {
+ tm lastUpdate;
+ MemsetZero(lastUpdate);
+ CString s = GetPrivateProfileCString("Update", "LastUpdateCheck", "1970-01-01 00:00", iniFile);
+ if(sscanf(s, "%04d-%02d-%02d %02d:%02d", &lastUpdate.tm_year, &lastUpdate.tm_mon, &lastUpdate.tm_mday, &lastUpdate.tm_hour, &lastUpdate.tm_min) == 5)
+ {
+ lastUpdate.tm_year -= 1900;
+ lastUpdate.tm_mon--;
+ }
+ time_t outTime = _mkgmtime(&lastUpdate);
+ if(outTime < 0) outTime = 0;
+
+ CUpdateCheck::SetUpdateSettings
+ (
+ outTime,
+ GetPrivateProfileInt("Update", "UpdateCheckPeriod", CUpdateCheck::GetUpdateCheckPeriod(), iniFile),
+ GetPrivateProfileCString("Update", "UpdateURL", CUpdateCheck::GetUpdateURL(), iniFile)
+ );
+ }
+
CHAR s[16];
for (int ncol = 0; ncol < MAX_MODCOLORS; ncol++)
{
@@ -967,8 +989,7 @@
CString version = MptVersion::str;
WritePrivateProfileString("Version", "Version", version, iniFile);
WritePrivateProfileString("Version", "InstallGUID", gcsInstallGUID, iniFile);
- WritePrivateProfileLong("Version", "CheckForUpdates", gnCheckForUpdates, iniFile);
-
+
WINDOWPLACEMENT wpl;
wpl.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(&wpl);
@@ -990,8 +1011,22 @@
WritePrivateProfileLong("Display", "PlugSelectWindowLast", gnPlugWindowLast, iniFile);
WritePrivateProfileDWord("Display", "MsgBoxVisibilityFlags", gnMsgBoxVisiblityFlags, iniFile);
+ // Internet Update
+ {
+ CString outDate;
+ const time_t t = CUpdateCheck::GetLastUpdateCheck();
+ const tm* const lastUpdate = gmtime(&t);
+ if(lastUpdate != nullptr)
+ {
+ outDate.Format("%04d-%02d-%02d %02d:%02d", lastUpdate->tm_year + 1900, lastUpdate->tm_mon + 1, lastUpdate->tm_mday, lastUpdate->tm_hour, lastUpdate->tm_min);
+ }
+ WritePrivateProfileString("Update", "LastUpdateCheck", outDate, iniFile);
+ WritePrivateProfileDWord("Update", "UpdateCheckPeriod", CUpdateCheck::GetUpdateCheckPeriod(), iniFile);
+ WritePrivateProfileString("Update", "UpdateURL", CUpdateCheck::GetUpdateURL(), iniFile);
+ }
+
CHAR s[16];
- for (int ncol=0; ncol<MAX_MODCOLORS; ncol++)
+ for (int ncol = 0; ncol < MAX_MODCOLORS; ncol++)
{
wsprintf(s, "Color%02d", ncol);
WritePrivateProfileDWord("Display", s, rgbCustomColors[ncol], iniFile);
@@ -2411,6 +2446,7 @@
CMidiSetupDlg mididlg(m_dwMidiSetup, m_nMidiDevice);
CEQSetupDlg eqdlg(&m_EqSettings);
CAutoSaverGUI autosavedlg(m_pAutoSaver); //rewbs.AutoSaver
+ CUpdateSetupDlg updatedlg;
dlg.AddPage(&general);
dlg.AddPage(&sounddlg);
dlg.AddPage(&playerdlg);
@@ -2419,6 +2455,7 @@
dlg.AddPage(&colors);
dlg.AddPage(&mididlg);
dlg.AddPage(&autosavedlg);
+ dlg.AddPage(&updatedlg);
m_bOptionsLocked=true; //rewbs.customKeys
dlg.DoModal();
m_bOptionsLocked=false; //rewbs.customKeys
@@ -3060,6 +3097,14 @@
}
+void CMainFrame::OnInternetUpdate()
+//---------------------------------
+{
+ CUpdateCheck *updateCheck = CUpdateCheck::Create(false);
+ updateCheck->DoUpdateCheck();
+}
+
+
/////////////////////////////////////////////
//Misc helper functions
/////////////////////////////////////////////
Modified: trunk/OpenMPT/mptrack/Mainfrm.h
===================================================================
--- trunk/OpenMPT/mptrack/Mainfrm.h 2011-04-01 15:43:38 UTC (rev 839)
+++ trunk/OpenMPT/mptrack/Mainfrm.h 2011-04-03 21:35:05 UTC (rev 840)
@@ -423,7 +423,6 @@
static DWORD gdwNotificationType;
static CString gcsPreviousVersion;
static CString gcsInstallGUID;
- static int gnCheckForUpdates;
// Audio Setup
static DWORD m_dwSoundSetup, m_dwRate, m_dwQuality, m_nSrcMode, m_nBitsPerSample, m_nPreAmp, gbLoopSong, m_nChannels;
@@ -698,6 +697,7 @@
afx_msg LRESULT OnCustomKeyMsg(WPARAM, LPARAM);
afx_msg void OnViewMIDIMapping();
afx_msg void OnViewEditHistory();
+ afx_msg void OnInternetUpdate();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
Modified: trunk/OpenMPT/mptrack/Moptions.h
===================================================================
--- trunk/OpenMPT/mptrack/Moptions.h 2011-04-01 15:43:38 UTC (rev 839)
+++ trunk/OpenMPT/mptrack/Moptions.h 2011-04-03 21:35:05 UTC (rev 840)
@@ -13,6 +13,7 @@
OPTIONS_PAGE_COLORS,
OPTIONS_PAGE_MIDI,
OPTIONS_PAGE_AUTOSAVE,
+ OPTIONS_PAGE_UPDATE,
};
Modified: trunk/OpenMPT/mptrack/Mptrack.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Mptrack.cpp 2011-04-01 15:43:38 UTC (rev 839)
+++ trunk/OpenMPT/mptrack/Mptrack.cpp 2011-04-03 21:35:05 UTC (rev 840)
@@ -17,6 +17,7 @@
#include "version.h"
#include "test/test.h"
#include <shlwapi.h>
+#include "UpdateCheck.h"
// rewbs.memLeak
#define _CRTDBG_MAP_ALLOC
@@ -615,10 +616,6 @@
strcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_PROGRAM*32], "Cc p");
strcpy(&m_MidiCfg.szMidiSFXExt[0], "F0F000z");
CModDoc::CreateZxxFromType(m_MidiCfg.szMidiZXXExt, sfx_fixed_reso4Bit);
-
- #ifdef UPDATECHECKENABLED
- m_pRequestContext = NULL;
- #endif
}
/////////////////////////////////////////////////////////////////////////////
@@ -945,17 +942,11 @@
m_dwTimeStarted = timeGetTime();
m_bInitialized = TRUE;
- /*
- if (CMainFrame::gnCheckForUpdates) {
- try {
- UpdateCheck();
- } catch (...) {
- // Could not do update check. Don't compain - do nothing.
- // Assuming winhttp.dll is set as delay-load in the project settings,
- // we will end up here if the dll cannot be foung (e.g. on win98).
- }
+ if (CUpdateCheck::GetUpdateCheckPeriod() != 0)
+ {
+ CUpdateCheck *updateCheck = CUpdateCheck::Create(true);
+ updateCheck->DoUpdateCheck();
}
- */
// Open settings if the previous execution was with an earlier version.
if (!cmdInfo.m_bNoSettingsOnNewVersion && MptVersion::ToNum(CMainFrame::gcsPreviousVersion) < MptVersion::num) {
@@ -974,186 +965,6 @@
}
-#ifdef UPDATECHECKENABLED
-void __stdcall CTrackApp::InternetRequestCallback( HINTERNET /*hInternet*/, DWORD_PTR userData, DWORD dwInternetStatus,
- LPVOID /*lpvStatusInformation*/, DWORD /*dwStatusInformationLength*/)
-//-----------------------------------------------------------------------------------------------------
-{
-
- REQUEST_CONTEXT *pRequestContext = (REQUEST_CONTEXT*)userData;
- if (pRequestContext->hRequest == NULL) {
- return;
- }
-
- DWORD versionBytesToRead = 10;
-
- switch (dwInternetStatus) {
- case WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE:
- if (!WinHttpReceiveResponse(pRequestContext->hRequest, NULL)) {
- CleanupInternetRequest(pRequestContext);
- return;
- }
- break;
- case WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE:
- {
- DWORD dwDownloaded = 0;
- if (!WinHttpQueryDataAvailable(pRequestContext->hRequest, &dwDownloaded)) {
- Log("Error %u in WinHttpQueryDataAvailable.\n",GetLastError());
- CleanupInternetRequest(pRequestContext);
- return;
- }
- if (dwDownloaded<versionBytesToRead) {
- Log("Downloaded %d bytes, expected at least %d\n", dwDownloaded, versionBytesToRead);
- CleanupInternetRequest(pRequestContext);
- return;
- }
- break;
- }
- case WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE:
- {
- DWORD dwRead = 0;
- pRequestContext->lpBuffer = new char[versionBytesToRead+1];
- ZeroMemory(pRequestContext->lpBuffer, versionBytesToRead+1);
-
- if (!WinHttpReadData(pRequestContext->hRequest, (LPVOID)pRequestContext->lpBuffer, versionBytesToRead, &dwRead)) {
- Log("Error %u in WinHttpReadData.\n", GetLastError());
- CleanupInternetRequest(pRequestContext);
- return;
- }
- if (dwRead<versionBytesToRead) {
- Log("Read %d bytes, expected at least %d\n", dwRead, versionBytesToRead);
- CleanupInternetRequest(pRequestContext);
- return;
- }
- break;
- }
- case WINHTTP_CALLBACK_STATUS_READ_COMPLETE:
- {
- CString remoteVersion = pRequestContext->lpBuffer;
- CString localVersion = CMainFrame::GetFullVersionString();
- if (remoteVersion > localVersion) {
- CString message;
- message.Format("New version available: %s (you are using %s). Would you like more information?", remoteVersion, localVersion);
- if (AfxMessageBox(message, MB_ICONQUESTION|MB_YESNO ) == IDYES) {
- CString URL;
- URL.Format("http://openmpt.xwiki.com/xwiki/bin/view/Development/Builds?currentVersion=%s", localVersion);
- CTrackApp::OpenURL(URL);
- }
- }
- CleanupInternetRequest(pRequestContext);
- break;
- }
- default:
- Log("Unhandled callback - status %d given", dwInternetStatus);
- break;
- }
-
-}
-
-void CTrackApp::CleanupInternetRequest(REQUEST_CONTEXT *pRequestContext)
-//-------------------------------------------------------------------------
-{
- if (pRequestContext != NULL) {
- if (pRequestContext->lpBuffer != NULL) {
- delete[] pRequestContext->lpBuffer;
- pRequestContext->lpBuffer = NULL;
- }
-
- if (pRequestContext->postData != NULL) {
- delete[] pRequestContext->postData;
- pRequestContext->postData = NULL;
- }
-
- if (pRequestContext->hRequest != NULL) {
- WinHttpSetStatusCallback(pRequestContext->hRequest, NULL, NULL, NULL);
- WinHttpCloseHandle(pRequestContext->hRequest);
- pRequestContext->hRequest = NULL;
- }
-
- if (pRequestContext->hConnection != NULL) {
- WinHttpCloseHandle(pRequestContext->hConnection);
- pRequestContext->hConnection = NULL;
- }
-
- if (pRequestContext->hSession != NULL) {
- WinHttpCloseHandle(pRequestContext->hSession);
- pRequestContext->hSession = NULL;
- }
- }
-}
-
-void CTrackApp::UpdateCheck()
-//---------------------------
-{
- m_pRequestContext = new REQUEST_CONTEXT();
- m_pRequestContext->hSession = NULL;
- m_pRequestContext->hConnection = NULL;
- m_pRequestContext->hRequest = NULL;
- m_pRequestContext->lpBuffer = NULL;
- m_pRequestContext->postData = NULL;
-
- // Prepare post data
- if (CMainFrame::gcsInstallGUID == "") {
- //No GUID found in INI file - generate one.
- GUID guid;
- CoCreateGuid(&guid);
- BYTE* Str;
- UuidToString((UUID*)&guid, &Str);
- CMainFrame::gcsInstallGUID.Format("%s", (LPTSTR)Str);
- RpcStringFree(&Str);
- }
-
- CString csPostData;
- csPostData.Format("install_id=%s&install_version=%s", CMainFrame::gcsInstallGUID, CMainFrame::GetFullVersionString());
- int length = csPostData.GetLength();
- m_pRequestContext->postData = new char[length+1];
- strcpy(m_pRequestContext->postData, csPostData);
-
- m_pRequestContext->hSession = WinHttpOpen( L"OpenMPT/1.17", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
- WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_ASYNC);
- if (m_pRequestContext->hSession==NULL) {
- CleanupInternetRequest(m_pRequestContext);
- return;
- }
-
- m_pRequestContext->hConnection = WinHttpConnect(m_pRequestContext->hSession, L"www.soal.org", INTERNET_DEFAULT_HTTP_PORT, 0);
- if (m_pRequestContext->hConnection==NULL) {
- CleanupInternetRequest(m_pRequestContext);
- return;
- }
-
- m_pRequestContext->hRequest = WinHttpOpenRequest(m_pRequestContext->hConnection, L"POST", L"openmpt/OpenMPTversionCheck.php5",
- NULL, NULL, NULL, 0);
- if (m_pRequestContext->hRequest==NULL) {
- CleanupInternetRequest(m_pRequestContext);
- return;
- }
-
- if (!WinHttpAddRequestHeaders(m_pRequestContext->hRequest, L"Content-Type:application/x-www-form-urlencoded\r\n\r\n",
- -1L, WINHTTP_ADDREQ_FLAG_ADD)) {
- CleanupInternetRequest(m_pRequestContext);
- return;
- }
-
- WINHTTP_STATUS_CALLBACK pCallback = WinHttpSetStatusCallback(m_pRequestContext->hRequest,
- static_cast<WINHTTP_STATUS_CALLBACK>(InternetRequestCallback),
- WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS,
- NULL);
- if (pCallback == WINHTTP_INVALID_STATUS_CALLBACK) {
- Log("Error %d in WinHttpSetStatusCallback.\n", WINHTTP_INVALID_STATUS_CALLBACK);
- CleanupInternetRequest(m_pRequestContext);
- return;
- }
-
- if (!WinHttpSendRequest(m_pRequestContext->hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, m_pRequestContext->postData, length, length, (DWORD_PTR)m_pRequestContext)) {
- CleanupInternetRequest(m_pRequestContext);
- return;
- }
-}
-
-#endif
-
-
int CTrackApp::ExitInstance()
//---------------------------
{
@@ -1205,12 +1016,6 @@
// Uninitialize ACM
UninitializeACM();
- // Cleanup the internet request, in case it is still active.
- #ifdef UPDATECHECKENABLED
- CleanupInternetRequest(m_pRequestContext);
- delete m_pRequestContext;
- #endif
-
return CWinApp::ExitInstance();
}
Modified: trunk/OpenMPT/mptrack/Mptrack.h
===================================================================
--- trunk/OpenMPT/mptrack/Mptrack.h 2011-04-01 15:43:38 UTC (rev 839)
+++ trunk/OpenMPT/mptrack/Mptrack.h 2011-04-03 21:35:05 UTC (rev 840)
@@ -16,11 +16,6 @@
#include "../soundlib/Sndfile.h"
#include <windows.h>
-#ifdef UPDATECHECKENABLED
- #include <Specstrings.h> // In VC2003, '__in' was undefined in winhttp.h
- #include <winhttp.h>
-#endif
-
class CModDoc;
class CVstPluginManager;
@@ -101,20 +96,6 @@
/////////////////////////////////////////////////////////////////////////////
-// Internet connection context
-
-#ifdef UPDATECHECKENABLED
-typedef struct REQUEST_CONTEXT {
- HINTERNET hSession;
- HINTERNET hConnection;
- HINTERNET hRequest;
- LPSTR lpBuffer; // Buffer for storing read data
- LPSTR postData;
-} REQUEST_CONTEXT;
-#endif
-
-
-/////////////////////////////////////////////////////////////////////////////
// File dialog (open/save) results
struct FileDlgResult
{
@@ -161,11 +142,6 @@
TCHAR m_szStringsFileName[_MAX_PATH];
static bool m_bPortableMode;
- #ifdef UPDATECHECKENABLED
- // Internet request context
- REQUEST_CONTEXT *m_pRequestContext;
- #endif
-
public:
CTrackApp();
@@ -213,13 +189,6 @@
VOID StartSplashScreen();
VOID StopSplashScreen();
- #ifdef UPDATECHECKENABLED
- VOID UpdateCheck();
- static void __stdcall InternetRequestCallback( HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus,
- LPVOID lpvStatusInformation, DWORD dwStatusInformationLength);
- static void CleanupInternetRequest(REQUEST_CONTEXT *pRequestContext);
- #endif
-
// Localized strings
public:
VOID ImportLocalizedStrings();
Added: trunk/OpenMPT/mptrack/UpdateCheck.cpp
===================================================================
--- trunk/OpenMPT/mptrack/UpdateCheck.cpp (rev 0)
+++ trunk/OpenMPT/mptrack/UpdateCheck.cpp 2011-04-03 21:35:05 UTC (rev 840)
@@ -0,0 +1,325 @@
+/*
+ * UpdateCheck.cpp
+ * ---------------
+ * Purpose: Class for easy software update check.
+ * Notes : (currently none)
+ * Authors: OpenMPT Devs
+ */
+
+#include "stdafx.h"
+#include "UpdateCheck.h"
+#include "version.h"
+#include "misc_util.h"
+#include "Mptrack.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// Static configuration variables
+time_t CUpdateCheck::lastUpdateCheck = 0;
+int CUpdateCheck::updateCheckPeriod = 7;
+CString CUpdateCheck::updateBaseURL = "http://update.openmpt.org/check/%s";
+
+
+CUpdateCheck::CUpdateCheck(const bool autoUpdate)
+//-----------------------------------------------
+{
+ isAutoUpdate = autoUpdate;
+ threadHandle = NULL;
+}
+
+
+CUpdateCheck::~CUpdateCheck()
+//---------------------------
+{
+ if(threadHandle != NULL)
+ {
+ CloseHandle(threadHandle);
+ }
+}
+
+
+// Start update check
+void CUpdateCheck::DoUpdateCheck()
+//--------------------------------
+{
+ internetHandle = NULL;
+ connectionHandle = NULL;
+
+ DWORD dummy; // For Win9x
+ threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&CUpdateCheck::UpdateThread, (LPVOID)this, 0, &dummy);
+ if(isAutoUpdate)
+ {
+ SetThreadPriority(threadHandle, THREAD_PRIORITY_BELOW_NORMAL);
+ }
+}
+
+
+// Run update check (independent thread)
+DWORD WINAPI CUpdateCheck::UpdateThread(LPVOID param)
+//---------------------------------------------------
+{
+ CUpdateCheck *caller = (CUpdateCheck *)param;
+
+ const time_t now = time(nullptr);
+
+ if(caller->isAutoUpdate)
+ {
+ // Do we actually need to run the update check right now?
+ if(CUpdateCheck::updateCheckPeriod == 0 || difftime(now, CUpdateCheck::lastUpdateCheck) < (double)(CUpdateCheck::updateCheckPeriod * 86400))
+ {
+ caller->Terminate();
+ return 0;
+ }
+ }
+
+ const CString userAgent = CString("OpenMPT ") + MptVersion::str;
+ CString updateURL;
+ updateURL.Format(CUpdateCheck::updateBaseURL, MptVersion::str);
+
+ /*if (CMainFrame::gcsInstallGUID == "")
+ {
+ //No GUID found in INI file - generate one.
+ GUID guid;
+ CoCreateGuid(&guid);
+ BYTE* Str;
+ UuidToString((UUID*)&guid, &Str);
+ CMainFrame::gcsInstallGUID.Format("%s", (LPTSTR)Str);
+ RpcStringFree(&Str);
+ }*/
+
+ // Establish a connection.
+ caller->internetHandle = InternetOpen(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
+ if(caller->internetHandle == NULL)
+ {
+ caller->Die("Could not start update check:\n", GetLastError());
+ return 0;
+ }
+ caller->connectionHandle = InternetOpenUrl(caller->internetHandle, updateURL, NULL, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_UI, 0);
+ if(caller->connectionHandle == NULL)
+ {
+ caller->Die("Could not establish connection:\n", GetLastError());
+ return 0;
+ }
+
+ // Retrieve HTTP status code.
+ DWORD statusCodeHTTP = 0;
+ DWORD length = sizeof(statusCodeHTTP);
+ if(HttpQueryInfo(caller->connectionHandle, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&statusCodeHTTP, &length, NULL) == FALSE)
+ {
+ caller->Die("Could not retrieve HTTP header information:\n", GetLastError());
+ return 0;
+ }
+ if(statusCodeHTTP >= 400)
+ {
+ CString error;
+ error.Format("Version information could not be found on the server (HTTP status code %d). Maybe your version of OpenMPT is too old!", statusCodeHTTP);
+ caller->Die(error);
+ return 0;
+ }
+
+ // Download data.
+ CString resultData = "";
+ char *downloadBuffer = new char[DOWNLOAD_BUFFER_SIZE];
+ DWORD availableSize = 0, bytesRead = 0;
+ do
+ {
+ if(InternetQueryDataAvailable(caller->connectionHandle, &availableSize, 0, NULL) == FALSE)
+ {
+ caller->Die("Error while downloading update information data:\n", GetLastError());
+ }
+
+ LimitMax(availableSize, (DWORD)DOWNLOAD_BUFFER_SIZE);
+
+ if(InternetReadFile(caller->connectionHandle, downloadBuffer, availableSize, &bytesRead) == FALSE)
+ {
+ caller->Die("Error while downloading update information data:\n", GetLastError());
+ }
+
+ resultData.Append(downloadBuffer, availableSize);
+ } while(bytesRead != 0);
+ delete[] downloadBuffer;
+
+ // Now, evaluate the downloaded data.
+ if(!resultData.CompareNoCase("noupdate"))
+ {
+ if(!caller->isAutoUpdate)
+ {
+ ::MessageBox(0, "You already have the latest version of OpenMPT.", "OpenMPT Internet Update", MB_OK | MB_ICONINFORMATION);
+ }
+ } else
+ {
+ CString releaseVersion, releaseDate, releaseURL;
+ CString token;
+ int parseStep = 0, parsePos = 0;
+ while((token = resultData.Tokenize("\n", parsePos)) != "")
+ {
+ token.Trim();
+ switch(parseStep++)
+ {
+ case 0:
+ if(token.CompareNoCase("update") != 0)
+ {
+ caller->Die("Could not understand server response. Maybe your version of OpenMPT is too old!");
+ return 0;
+ }
+ break;
+ case 1:
+ releaseVersion = token;
+ break;
+ case 2:
+ releaseDate = token;
+ break;
+ case 3:
+ releaseURL = token;
+ break;
+ }
+ }
+ if(parseStep >= 4)
+ {
+ resultData.Format("A new version is available!\nOpenMPT %s has been released on %s. Would you like to visit %s for more information?", releaseVersion, releaseDate, releaseURL);
+ if(::MessageBox(0, resultData, "OpenMPT Internet Update", MB_YESNO | MB_ICONINFORMATION) == IDYES)
+ {
+ CTrackApp::OpenURL(releaseURL);
+ }
+ } else
+ {
+ caller->Die("Could not understand server response. Maybe your version of OpenMPT is too old!");
+ return 0;
+ }
+ }
+
+ CUpdateCheck::lastUpdateCheck = now;
+
+ caller->Terminate();
+ return 0;
+}
+
+
+// Die with error message
+void CUpdateCheck::Die(CString errorMessage)
+//------------------------------------------
+{
+ if(!isAutoUpdate)
+ {
+ ::MessageBox(0, errorMessage, "OpenMPT Internet Update Error", MB_OK | MB_ICONERROR);
+ }
+ Terminate();
+}
+
+
+// Die with WinINet error message
+void CUpdateCheck::Die(CString errorMessage, DWORD errorCode)
+//-----------------------------------------------------------
+{
+ if(!isAutoUpdate)
+ {
+ LPVOID lpMsgBuf;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ GetModuleHandle(TEXT("wininet.dll")), errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
+
+ errorMessage.Append((LPTSTR)lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ }
+ Die(errorMessage);
+}
+
+
+// Kill update object
+void CUpdateCheck::Terminate()
+//----------------------------
+{
+ if(connectionHandle != NULL)
+ {
+ InternetCloseHandle(connectionHandle);
+ connectionHandle = NULL;
+ }
+ if(internetHandle != NULL)
+ {
+ InternetCloseHandle(internetHandle);
+ internetHandle = NULL;
+ }
+ threadHandle = NULL; // If we got here, the thread asked for termination, so don't use CloseHandle()
+ delete this;
+}
+
+
+/////////////////////////////////////////////////////////////
+// CUpdateSetupDlg
+
+BEGIN_MESSAGE_MAP(CUpdateSetupDlg, CPropertyPage)
+ ON_COMMAND(IDC_BUTTON1, OnCheckNow)
+ ON_COMMAND(IDC_RADIO1, OnSettingsChanged)
+ ON_COMMAND(IDC_RADIO2, OnSettingsChanged)
+ ON_COMMAND(IDC_RADIO3, OnSettingsChanged)
+ ON_COMMAND(IDC_RADIO4, OnSettingsChanged)
+ ON_EN_CHANGE(IDC_EDIT1, OnSettingsChanged)
+END_MESSAGE_MAP()
+
+
+BOOL CUpdateSetupDlg::OnInitDialog()
+//----------------------------------
+{
+ CPropertyPage::OnInitDialog();
+
+ int radioID = 0;
+ switch(CUpdateCheck::GetUpdateCheckPeriod())
+ {
+ case 0: radioID = IDC_RADIO1; break;
+ case 1: radioID = IDC_RADIO2; break;
+ case 7: radioID = IDC_RADIO3; break;
+ case 31: radioID = IDC_RADIO4; break;
+ }
+ CheckRadioButton(IDC_RADIO1, IDC_RADIO4, radioID);
+ SetDlgItemText(IDC_EDIT1, CUpdateCheck::GetUpdateURL());
+
+ const time_t t = CUpdateCheck::GetLastUpdateCheck();
+ if(t > 0)
+ {
+ CString updateText;
+ const tm* const lastUpdate = localtime(&t);
+ if(lastUpdate != nullptr)
+ {
+ updateText.Format("The last successful update check was run on %04d-%02d-%02d, %02d:%02d.", lastUpdate->tm_year + 1900, lastUpdate->tm_mon + 1, lastUpdate->tm_mday, lastUpdate->tm_hour, lastUpdate->tm_min);
+ SetDlgItemText(IDC_LASTUPDATE, updateText);
+ }
+ }
+
+ return TRUE;
+}
+
+
+void CUpdateSetupDlg::OnOK()
+//--------------------------
+{
+ int updateCheckPeriod = CUpdateCheck::GetUpdateCheckPeriod();
+ if(IsDlgButtonChecked(IDC_RADIO1)) updateCheckPeriod = 0;
+ if(IsDlgButtonChecked(IDC_RADIO2)) updateCheckPeriod = 1;
+ if(IsDlgButtonChecked(IDC_RADIO3)) updateCheckPeriod = 7;
+ if(IsDlgButtonChecked(IDC_RADIO4)) updateCheckPeriod = 31;
+
+ CString updateURL;
+ GetDlgItemText(IDC_EDIT1, updateURL);
+ CUpdateCheck::SetUpdateSettings(CUpdateCheck::GetLastUpdateCheck(), updateCheckPeriod, updateURL);
+
+ CPropertyPage::OnOK();
+}
+
+
+BOOL CUpdateSetupDlg::OnSetActive()
+//---------------------------------
+{
+ CMainFrame::m_nLastOptionsPage = OPTIONS_PAGE_UPDATE;
+ return CPropertyPage::OnSetActive();
+}
+
+
+void CUpdateSetupDlg::OnCheckNow()
+//--------------------------------
+{
+ CUpdateCheck *updateCheck = CUpdateCheck::Create(false);
+ updateCheck->DoUpdateCheck();
+}
+
Added: trunk/OpenMPT/mptrack/UpdateCheck.h
===================================================================
--- trunk/OpenMPT/mptrack/UpdateCheck.h (rev 0)
+++ trunk/OpenMPT/mptrack/UpdateCheck.h 2011-04-03 21:35:05 UTC (rev 840)
@@ -0,0 +1,80 @@
+/*
+ * UpdateCheck.h
+ * -------------
+ * Purpose: Header for easy software update check.
+ * Notes : (currently none)
+ * Authors: OpenMPT Devs
+ */
+
+#pragma once
+#ifndef UPDATECHECK_H
+#define UPDATECHECK_H
+
+#include <WinInet.h>
+#include <time.h>
+
+// Setup dialog stuff
+#include "Mainfrm.h"
+#include "resource.h"
+#include "Moptions.h"
+
+
+#define DOWNLOAD_BUFFER_SIZE 256
+
+//================
+class CUpdateCheck
+//================
+{
+public:
+
+ // Force creation via "new" as we're using "delete this".
+ static CUpdateCheck *Create(bool autoUpdate) { return new CUpdateCheck(autoUpdate); };
+ void DoUpdateCheck();
+
+ static time_t GetLastUpdateCheck() { return lastUpdateCheck; };
+ static int GetUpdateCheckPeriod() { return updateCheckPeriod; };
+ static CString GetUpdateURL() { return updateBaseURL; };
+ static void SetUpdateSettings(time_t last, int period, CString url) { lastUpdateCheck = last; updateCheckPeriod = period; updateBaseURL = url; };
+
+protected:
+
+ // Static configuration variables
+ static time_t lastUpdateCheck; // Time of last successful update check
+ static int updateCheckPeriod; // Check for updates every x days
+ static CString updateBaseURL; // URL where the version check should be made.
+
+ bool isAutoUpdate; // Are we running an automatic update check?
+
+ // Runtime resource handles
+ HANDLE threadHandle;
+ HINTERNET internetHandle, connectionHandle;
+
+ CUpdateCheck(const bool showErrors);
+ ~CUpdateCheck();
+
+ static DWORD WINAPI UpdateThread(LPVOID param);
+ void Die(CString errorMessage);
+ void Die(CString errorMessage, DWORD errorCode);
+ void Terminate();
+};
+
+
+//=========================================
+class CUpdateSetupDlg: public CPropertyPage
+//=========================================
+{
+public:
+ CUpdateSetupDlg():CPropertyPage(IDD_OPTIONS_UPDATE)
+ { };
+
+protected:
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+ virtual BOOL OnSetActive();
+ afx_msg void OnSettingsChanged() { SetModified(TRUE); }
+ afx_msg void OnCheckNow();
+ DECLARE_MESSAGE_MAP()
+};
+
+#endif // UPDATECHECK_H
+
Modified: trunk/OpenMPT/mptrack/mptrack.rc
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.rc 2011-04-01 15:43:38 UTC (rev 839)
+++ trunk/OpenMPT/mptrack/mptrack.rc 2011-04-03 21:35:05 UTC (rev 840)
@@ -186,7 +186,25 @@
LTEXT "Samples used for fading:",IDC_STATIC,6,8,96,8
END
+IDD_OPTIONS_UPDATE DIALOGEX 0, 0, 274, 281
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Update"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX "Check for Updates",IDC_STATIC,6,6,258,66
+ CONTROL "Never",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON,12,18,240,8
+ CONTROL "Daily",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,12,30,240,8
+ CONTROL "Weekly (recommended)",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,12,42,240,8
+ CONTROL "Monthly",IDC_RADIO4,"Button",BS_AUTORADIOBUTTON,12,54,240,8
+ GROUPBOX "Advanced Settings",IDC_STATIC,6,78,258,60
+ LTEXT "Update server URL:",IDC_STATIC,12,90,246,8
+ EDITTEXT IDC_EDIT1,12,102,246,12,ES_AUTOHSCROLL
+ LTEXT "",IDC_LASTUPDATE,6,168,258,24
+ LTEXT "Do not change this unless you are absolutely sure of what you are doing.",IDC_STATIC,12,120,246,12
+ PUSHBUTTON "Check for Updates",IDC_BUTTON1,6,144,84,18
+END
+
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
@@ -266,6 +284,14 @@
TOPMARGIN, 7
BOTTOMMARGIN, 75
END
+
+ IDD_OPTIONS_UPDATE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 267
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 274
+ END
END
#endif // APSTUDIO_INVOKED
@@ -2035,6 +2061,7 @@
MENUITEM "&OpenMPT Website", ID_NETLINK_MODPLUG
MENUITEM "&Web Resources", ID_NETLINK_TOP_PICKS
MENUITEM SEPARATOR
+ MENUITEM "Check for &Updates...", ID_INTERNETUPDATE
MENUITEM "&About OpenMPT...", ID_APP_ABOUT
END
END
@@ -2750,6 +2777,7 @@
BEGIN
MENUITEM "&Load Preset...", ID_PRESET_LOAD
MENUITEM "&Save Preset As...", ID_PRESET_SAVE
+ MENUITEM "Create instrument from plugin", ID_PLUGINTOINSTRUMENT
MENUITEM SEPARATOR
MENUITEM "&Randomize Params", ID_PRESET_RANDOM
END
Modified: trunk/OpenMPT/mptrack/mptrack.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.vcproj 2011-04-01 15:43:38 UTC (rev 839)
+++ trunk/OpenMPT/mptrack/mptrack.vcproj 2011-04-03 21:35:05 UTC (rev 840)
@@ -126,7 +126,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="winmm.lib strmiids.lib dmoguids.lib version.lib opengl32.lib glu32.lib Rpcrt4.lib delayimp.lib"
+ AdditionalDependencies="winmm.lib strmiids.lib dmoguids.lib version.lib opengl32.lib glu32.lib Rpcrt4.lib delayimp.lib wininet.lib"
OutputFile=".\Bin/mptrack.exe"
Version="5.0"
LinkIncremental="1"
@@ -427,6 +427,9 @@
RelativePath=".\Undo.cpp">
</File>
<File
+ RelativePath=".\UpdateCheck.cpp">
+ </File>
+ <File
RelativePath=".\view_com.cpp">
</File>
<File
@@ -840,6 +843,9 @@
RelativePath=".\Undo.h">
</File>
<File
+ RelativePath=".\UpdateCheck.h">
+ </File>
+ <File
RelativePath=".\version.h">
</File>
<File
Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2011-04-01 15:43:38 UTC (rev 839)
+++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2011-04-03 21:35:05 UTC (rev 840)
@@ -189,7 +189,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="winmm.lib strmiids.lib dmoguids.lib version.lib opengl32.lib glu32.lib Rpcrt4.lib delayimp.lib"
+ AdditionalDependencies="winmm.lib strmiids.lib dmoguids.lib version.lib opengl32.lib glu32.lib Rpcrt4.lib delayimp.lib wininet.lib"
OutputFile=".\Bin/mptrack.exe"
Version="5.0"
LinkIncremental="1"
@@ -573,6 +573,10 @@
>
</File>
<File
+ RelativePath=".\UpdateCheck.cpp"
+ >
+ </File>
+ <File
RelativePath=".\view_com.cpp"
>
</File>
@@ -1119,6 +1123,10 @@
>
</File>
<File
+ RelativePath=".\UpdateCheck.h"
+ >
+ </File>
+ <File
RelativePath=".\version.h"
>
</File>
Modified: trunk/OpenMPT/mptrack/resource.h
===================================================================
--- trunk/OpenMPT/mptrack/resource.h 2011-04-01 15:43:38 UTC (rev 839)
+++ trunk/OpenMPT/mptrack/resource.h 2011-04-03 21:35:05 UTC (rev 840)
@@ -138,6 +138,7 @@
#define IDD_EDITHISTORY 526
#define IDD_SAMPLE_GRID_SIZE 527
#define IDD_SAMPLE_XFADE 528
+#define IDD_OPTIONS_UPDATE 529
#define IDC_BUTTON1 1001
#define IDC_BUTTON2 1002
#define IDC_BUTTON3 1003
@@ -930,6 +931,7 @@
#define IDC_EDIT_HISTORY 2432
#define IDC_SAMPLE_QUICKFADE 2433
#define IDC_SAMPLE_XFADE 2434
+#define IDC_LASTUPDATE 2435
#define ID_FILE_NEWMOD 32771
#define ID_FILE_NEWXM 32772
#define ID_FILE_NEWS3M 32773
@@ -1186,15 +1188,16 @@
#define ID_EDIT_MIXPASTE_ITSTYLE 60455
#define ID_VIEW_MPTHACKS 60456
#define ID_PLUGINTOINSTRUMENT 60457
+#define ID_INTERNETUPDATE 60458
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
-#define _APS_NEXT_RESOURCE_VALUE 529
-#define _APS_NEXT_COMMAND_VALUE 60458
-#define _APS_NEXT_CONTROL_VALUE 2435
+#define _APS_NEXT_RESOURCE_VALUE 530
+#define _APS_NEXT_COMMAND_VALUE 60459
+#define _APS_NEXT_CONTROL_VALUE 2436
#define _APS_NEXT_SYMED_VALUE 901
#endif
#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-01 15:43:44
|
Revision: 839
http://modplug.svn.sourceforge.net/modplug/?rev=839&view=rev
Author: saga-games
Date: 2011-04-01 15:43:38 +0000 (Fri, 01 Apr 2011)
Log Message:
-----------
I not am Yoda.
Modified Paths:
--------------
trunk/OpenMPT/installer/install.iss
Modified: trunk/OpenMPT/installer/install.iss
===================================================================
--- trunk/OpenMPT/installer/install.iss 2011-04-01 15:35:45 UTC (rev 838)
+++ trunk/OpenMPT/installer/install.iss 2011-04-01 15:43:38 UTC (rev 839)
@@ -251,7 +251,7 @@
case CurUninstallStep of
usUninstall:
begin
- if MsgBox('Do you want to keep OpenMPT your settings files (mptrack.ini, Keybindings.mkb, plugin.cache and local_tunings.tc)?', mbConfirmation, MB_YESNO or MB_DEFBUTTON2) = IDNO then
+ if MsgBox('Do you want to keep your OpenMPT settings files (mptrack.ini, Keybindings.mkb, plugin.cache and local_tunings.tc)?', mbConfirmation, MB_YESNO or MB_DEFBUTTON2) = IDNO then
begin
if(GetIniInt('Paths', 'UseAppDataDirectory', 1, 0, 0, ExpandConstant('{app}\mptrack.ini')) = 1) then
begin
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-01 15:35:51
|
Revision: 838
http://modplug.svn.sourceforge.net/modplug/?rev=838&view=rev
Author: saga-games
Date: 2011-04-01 15:35:45 +0000 (Fri, 01 Apr 2011)
Log Message:
-----------
Created tag for version 1.19.01.00
Added Paths:
-----------
tags/1.19.01.00/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-01 15:32:53
|
Revision: 837
http://modplug.svn.sourceforge.net/modplug/?rev=837&view=rev
Author: saga-games
Date: 2011-04-01 15:32:47 +0000 (Fri, 01 Apr 2011)
Log Message:
-----------
[Mod] Updated installer scripts.
Modified Paths:
--------------
trunk/OpenMPT/installer/install-unmo3-free-itd.iss
trunk/OpenMPT/installer/install.iss
Modified: trunk/OpenMPT/installer/install-unmo3-free-itd.iss
===================================================================
--- trunk/OpenMPT/installer/install-unmo3-free-itd.iss 2011-04-01 15:15:40 UTC (rev 836)
+++ trunk/OpenMPT/installer/install-unmo3-free-itd.iss 2011-04-01 15:32:47 UTC (rev 837)
@@ -51,8 +51,8 @@
begin
if(IsTaskSelected('downloadmo3')) then
begin
- ITD_AddMirror('http://openmpt.org/files/unmo3/2.4.0.1/unmo3.dll', ExpandConstant('{tmp}\openmpt-unmo3.dll.tmp'));
- ITD_AddFile('ftp://ftp.untergrund.net/users/sagamusix/openmpt/unmo3.dll', ExpandConstant('{tmp}\openmpt-unmo3.dll.tmp'));
+ ITD_AddFile('http://openmpt.org/files/unmo3/2.4.0.1/unmo3.dll', ExpandConstant('{tmp}\openmpt-unmo3.dll.tmp'));
+ ITD_AddMirror('ftp://ftp.untergrund.net/users/sagamusix/openmpt/unmo3.dll', ExpandConstant('{tmp}\openmpt-unmo3.dll.tmp'));
end else
begin
ITD_ClearFiles();
Modified: trunk/OpenMPT/installer/install.iss
===================================================================
--- trunk/OpenMPT/installer/install.iss 2011-04-01 15:15:40 UTC (rev 836)
+++ trunk/OpenMPT/installer/install.iss 2011-04-01 15:32:47 UTC (rev 837)
@@ -114,7 +114,7 @@
[Run]
; duh
-Filename: {app}\mptrack.exe; Parameters: """{app}\ExampleSongs\xaimus - digital sentience.it"""; Description: {cm:LaunchProgram,OpenMPT}; Flags: nowait postinstall skipifsilent
+Filename: {app}\mptrack.exe; Parameters: """{app}\ExampleSongs\manwe - evening glow.it"""; Description: {cm:LaunchProgram,OpenMPT}; Flags: nowait postinstall skipifsilent
Filename: "https://sourceforge.net/projects/kernelex/"; Description: "Download KernelEx (required on Windows 98 / Me)"; Flags: shellexec nowait postinstall skipifsilent; Check: not UsingWinNT();
[UninstallDelete]
@@ -251,7 +251,7 @@
case CurUninstallStep of
usUninstall:
begin
- if MsgBox('Do you want to remove OpenMPT settings files (mptrack.ini, Keybindings.mkb, plugin.cache and local_tunings.tc)?', mbConfirmation, MB_YESNO or MB_DEFBUTTON2) = IDYES then
+ if MsgBox('Do you want to keep OpenMPT your settings files (mptrack.ini, Keybindings.mkb, plugin.cache and local_tunings.tc)?', mbConfirmation, MB_YESNO or MB_DEFBUTTON2) = IDNO then
begin
if(GetIniInt('Paths', 'UseAppDataDirectory', 1, 0, 0, ExpandConstant('{app}\mptrack.ini')) = 1) then
begin
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-01 15:15:48
|
Revision: 836
http://modplug.svn.sourceforge.net/modplug/?rev=836&view=rev
Author: saga-games
Date: 2011-04-01 15:15:40 +0000 (Fri, 01 Apr 2011)
Log Message:
-----------
[Fix] Pattern Editor: Editing patterns through the Note Properties created just one undo point per module (http://bugs.openmpt.org/view.php?id=56#c118) (tx Harbinger)
[Fix] Pattern Editor: Setting the PC note plugin from the Note Properties didn't work.
[New] Instrument Editor: Clicking on an empty plugin slot in the plugin dropdown list opens the "Add Plugin" dialog (tx coda)
[New] Plugin Editor: New menu entry: Create instrument from plugin
[Mod] Options: "No extra-loud samples" is now enabled by default (more suitable for Mixmodes RC3 and Original)
[Mod] OpenMPT: Version is now 1.19.01.00 Final
Modified Paths:
--------------
trunk/OpenMPT/mptrack/AbstractVstEditor.cpp
trunk/OpenMPT/mptrack/AbstractVstEditor.h
trunk/OpenMPT/mptrack/Ctrl_ins.cpp
trunk/OpenMPT/mptrack/MainFrm.cpp
trunk/OpenMPT/mptrack/Mpdlgs.cpp
trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp
trunk/OpenMPT/mptrack/resource.h
trunk/OpenMPT/mptrack/version.h
trunk/OpenMPT/packageTemplate/History.txt
Modified: trunk/OpenMPT/mptrack/AbstractVstEditor.cpp
===================================================================
--- trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2011-04-01 15:03:17 UTC (rev 835)
+++ trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2011-04-01 15:15:40 UTC (rev 836)
@@ -46,6 +46,7 @@
ON_COMMAND(ID_NEXTVSTPRESET, OnSetNextVSTPreset)
ON_COMMAND(ID_VSTPRESETBACKWARDJUMP,OnVSTPresetBackwardJump)
ON_COMMAND(ID_VSTPRESETFORWARDJUMP, OnVSTPresetForwardJump)
+ ON_COMMAND(ID_PLUGINTOINSTRUMENT, OnCreateInstrument)
ON_COMMAND_RANGE(ID_PRESET_SET, ID_PRESET_SET+MAX_PLUGPRESETS, OnSetPreset)
ON_MESSAGE(WM_MOD_KEYCOMMAND, OnCustomKeyMsg) //rewbs.customKeys
ON_COMMAND_RANGE(ID_PLUGSELECT, ID_PLUGSELECT+MAX_MIXPLUGINS, OnToggleEditor) //rewbs.patPlugName
@@ -188,7 +189,11 @@
char rawname[256];
if(!m_pVstPlugin->GetProgramNameIndexed(index, -1, rawname))
{
- strcpy(rawname, "");
+ // Fallback: Try to get current program name.
+ if(m_pVstPlugin->Dispatch(effGetProgramName, 0, 0, rawname, 0) != 1)
+ {
+ strcpy(rawname, "");
+ }
}
SetNullTerminator(rawname);
CreateVerifiedProgramName(rawname, sizeof(rawname), name, sizeof(name), index);
@@ -202,9 +207,9 @@
void CAbstractVstEditor::OnSetPreset(UINT nID)
-//---------------------------------------------
+//--------------------------------------------
{
- int nIndex=nID-ID_PRESET_SET;
+ int nIndex = nID - ID_PRESET_SET;
if (nIndex>=0)
{
m_pVstPlugin->SetCurrentProgram(nIndex);
@@ -310,7 +315,7 @@
}
LRESULT CAbstractVstEditor::OnCustomKeyMsg(WPARAM wParam, LPARAM /*lParam*/)
-//----------------------------------------------------------------------
+//--------------------------------------------------------------------------
{
if (wParam == kcNull)
return NULL;
@@ -365,8 +370,7 @@
if(m_nInstrument < 0 && m_pVstPlugin->CanRecieveMidiEvents())
{
CModDoc *pModDoc = m_pVstPlugin->GetModDoc();
- CSoundFile *pSndFile = m_pVstPlugin->GetSoundFile();
- if(!pModDoc || !pSndFile)
+ if(pModDoc == nullptr)
return false;
if(!m_pVstPlugin->isInstrument() || pModDoc->GetSoundFile()->GetModSpecifications().instrumentsMax == 0 ||
@@ -375,28 +379,7 @@
return false;
} else
{
- // try to set up a new instrument
- bool bFirst = (pSndFile->GetNumInstruments() == 0);
- INSTRUMENTINDEX nIns = pModDoc->InsertInstrument(0);
- if(nIns == INSTRUMENTINDEX_INVALID)
- return false;
-
- MODINSTRUMENT *pIns = pSndFile->Instruments[nIns];
- m_nInstrument = nIns;
-
- _snprintf(pIns->name, CountOf(pIns->name) - 1, _T("%d: %s"), m_pVstPlugin->GetSlot() + 1, pSndFile->m_MixPlugins[m_pVstPlugin->GetSlot()].Info.szName);
- strncpy(pIns->filename, pSndFile->m_MixPlugins[m_pVstPlugin->GetSlot()].Info.szLibraryName, CountOf(pIns->filename) - 1);
- pIns->nMixPlug = (PLUGINDEX)m_pVstPlugin->GetSlot() + 1;
- pIns->nMidiChannel = 1;
- // People will forget to change this anyway, so the following lines can lead to some bad surprises after re-opening the module.
- //pIns->wMidiBank = (WORD)((m_pVstPlugin->GetCurrentProgram() >> 7) + 1);
- //pIns->nMidiProgram = (BYTE)((m_pVstPlugin->GetCurrentProgram() & 0x7F) + 1);
-
- pModDoc->UpdateAllViews(NULL, (nIns << HINT_SHIFT_INS) | HINT_INSTRUMENT | HINT_INSNAMES | HINT_ENVELOPE | (bFirst ? HINT_MODTYPE : 0));
- if(pSndFile->GetModSpecifications().supportsPlugins)
- pModDoc->SetModified();
-
- return true;
+ return CreateInstrument();
}
} else
{
@@ -741,11 +724,58 @@
}
void CAbstractVstEditor::OnVSTPresetForwardJump()
-//----------------------------------------------------
+//-----------------------------------------------
{
OnSetPreset(min(10+ID_PRESET_SET+m_pVstPlugin->GetCurrentProgram(), ID_PRESET_SET+m_pVstPlugin->GetNumPrograms()-1));
}
+
+void CAbstractVstEditor::OnCreateInstrument()
+//-------------------------------------------
+{
+ CreateInstrument();
+}
+
+
+// Try to set up a new instrument that is linked to the current plugin.
+bool CAbstractVstEditor::CreateInstrument()
+//-----------------------------------------
+{
+ CModDoc *pModDoc = m_pVstPlugin->GetModDoc();
+ CSoundFile *pSndFile = m_pVstPlugin->GetSoundFile();
+ if(pModDoc == nullptr || pSndFile == nullptr)
+ {
+ return false;
+ }
+
+ bool bFirst = (pSndFile->GetNumInstruments() == 0);
+ INSTRUMENTINDEX nIns = pModDoc->InsertInstrument(0);
+ if(nIns == INSTRUMENTINDEX_INVALID)
+ {
+ return false;
+ }
+
+ MODINSTRUMENT *pIns = pSndFile->Instruments[nIns];
+ m_nInstrument = nIns;
+
+ _snprintf(pIns->name, CountOf(pIns->name) - 1, _T("%d: %s"), m_pVstPlugin->GetSlot() + 1, pSndFile->m_MixPlugins[m_pVstPlugin->GetSlot()].Info.szName);
+ strncpy(pIns->filename, pSndFile->m_MixPlugins[m_pVstPlugin->GetSlot()].Info.szLibraryName, CountOf(pIns->filename) - 1);
+ pIns->nMixPlug = (PLUGINDEX)m_pVstPlugin->GetSlot() + 1;
+ pIns->nMidiChannel = 1;
+ // People will forget to change this anyway, so the following lines can lead to some bad surprises after re-opening the module.
+ //pIns->wMidiBank = (WORD)((m_pVstPlugin->GetCurrentProgram() >> 7) + 1);
+ //pIns->nMidiProgram = (BYTE)((m_pVstPlugin->GetCurrentProgram() & 0x7F) + 1);
+
+ pModDoc->UpdateAllViews(NULL, (nIns << HINT_SHIFT_INS) | HINT_INSTRUMENT | HINT_INSNAMES | HINT_ENVELOPE | (bFirst ? HINT_MODTYPE : 0));
+ if(pSndFile->GetModSpecifications().supportsPlugins)
+ {
+ pModDoc->SetModified();
+ }
+
+ return true;
+}
+
+
void CAbstractVstEditor::PrepareToLearnMacro(UINT nID)
{
m_nLearnMacro = (nID-ID_LEARN_MACRO_FROM_PLUGGUI);
Modified: trunk/OpenMPT/mptrack/AbstractVstEditor.h
===================================================================
--- trunk/OpenMPT/mptrack/AbstractVstEditor.h 2011-04-01 15:03:17 UTC (rev 835)
+++ trunk/OpenMPT/mptrack/AbstractVstEditor.h 2011-04-01 15:15:40 UTC (rev 836)
@@ -23,6 +23,7 @@
int GetLearnMacro();
void UpdatePresetField();
+ bool CreateInstrument();
afx_msg void OnLoadPreset();
afx_msg void OnSavePreset();
@@ -37,6 +38,7 @@
afx_msg void OnSetNextVSTPreset();
afx_msg void OnVSTPresetBackwardJump();
afx_msg void OnVSTPresetForwardJump();
+ afx_msg void OnCreateInstrument();
afx_msg LRESULT OnCustomKeyMsg(WPARAM, LPARAM); //rewbs.customKeys
//Overridden methods:
Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2011-04-01 15:03:17 UTC (rev 835)
+++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2011-04-01 15:15:40 UTC (rev 836)
@@ -9,6 +9,7 @@
#include "dlg_misc.h"
#include "tuningDialog.h"
#include "misc_util.h"
+#include "Vstplug.h"
#pragma warning(disable:4244) //conversion from 'type1' to 'type2', possible loss of data
@@ -2088,7 +2089,23 @@
if (pIns->nMixPlug) //if we have not just set to no plugin
{
- PSNDMIXPLUGIN pPlug = &(m_pSndFile->m_MixPlugins[pIns->nMixPlug-1]);
+ PSNDMIXPLUGIN pPlug = &(m_pSndFile->m_MixPlugins[pIns->nMixPlug - 1]);
+ if (pPlug == nullptr || pPlug->pMixPlugin == nullptr)
+ {
+ // No plugin in this slot: Ask user to add one.
+ CSelectPluginDlg dlg(m_pModDoc, nPlug - 1, this);
+ if (dlg.DoModal() == IDOK)
+ {
+ if(m_pSndFile->GetModSpecifications().supportsPlugins)
+ {
+ m_pModDoc->SetModified();
+ }
+ UpdatePluginList();
+ m_pModDoc->UpdateAllViews(NULL, HINT_MIXPLUGINS, NULL);
+ }
+
+ }
+
if (pPlug && pPlug->pMixPlugin)
{
::EnableWindow(::GetDlgItem(m_hWnd, IDC_INSVIEWPLG), true);
@@ -2102,7 +2119,6 @@
}
return;
}
-
}
}
Modified: trunk/OpenMPT/mptrack/MainFrm.cpp
===================================================================
--- trunk/OpenMPT/mptrack/MainFrm.cpp 2011-04-01 15:03:17 UTC (rev 835)
+++ trunk/OpenMPT/mptrack/MainFrm.cpp 2011-04-01 15:15:40 UTC (rev 836)
@@ -194,7 +194,7 @@
// Pattern Setup
DWORD CMainFrame::m_dwPatternSetup = PATTERN_PLAYNEWNOTE | PATTERN_EFFECTHILIGHT
| PATTERN_SMALLFONT | PATTERN_CENTERROW
- | PATTERN_DRAGNDROPEDIT | PATTERN_FLATBUTTONS
+ | PATTERN_DRAGNDROPEDIT | PATTERN_FLATBUTTONS | PATTERN_NOEXTRALOUD
| PATTERN_2NDHIGHLIGHT | PATTERN_STDHIGHLIGHT /*| PATTERN_HILITETIMESIGS*/
| PATTERN_SHOWPREVIOUS | PATTERN_CONTSCROLL | PATTERN_SYNCMUTE | PATTERN_AUTODELAY | PATTERN_NOTEFADE;
DWORD CMainFrame::m_nRowSpacing = 16; // primary highlight (measures)
@@ -823,7 +823,7 @@
if (!m_wndToolBar.Create(this)) return -1;
if (!m_wndStatusBar.Create(this)) return -1;
if (!m_wndTree.Create(this, IDD_TREEVIEW, CBRS_LEFT|CBRS_BORDER_RIGHT, IDD_TREEVIEW)) return -1;
- m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
+ m_wndStatusBar.SetIndicators(indicators, CountOf(indicators));
m_wndToolBar.Init(this);
m_wndTree.RecalcLayout();
@@ -3078,7 +3078,7 @@
str += (librarynames) ? p->GetLibraryName() : p->GetName();
if(str.GetLength() <= size0) str += "undefined";
- CBox.AddString(str);
+ CBox.SetItemData(CBox.AddString(str), iPlug + 1);
}
#endif // NO_VST
}
@@ -3094,8 +3094,8 @@
//-----------------------------------------------------------------------
{
char s[72], sname[64];
- UINT nParams = plug.GetNumParameters();
- for (UINT i=0; i<nParams; i++)
+ const PlugParamIndex nParams = plug.GetNumParameters();
+ for (PlugParamIndex i = 0; i < nParams; i++)
{
plug.GetParamName(i, sname, sizeof(sname));
wsprintf(s, "%02d: %s", i, sname);
Modified: trunk/OpenMPT/mptrack/Mpdlgs.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Mpdlgs.cpp 2011-04-01 15:03:17 UTC (rev 835)
+++ trunk/OpenMPT/mptrack/Mpdlgs.cpp 2011-04-01 15:15:40 UTC (rev 836)
@@ -9,7 +9,7 @@
#include "snddev.h"
#include ".\mpdlgs.h"
-#define str_preampChangeNote GetStrI18N(_TEXT("Note: Pre-Amp setting affects sample volume only. Changing this setting may cause undesired effects on volume balance between sample based instruments and plugin instruments."))
+#define str_preampChangeNote GetStrI18N(_TEXT("Note: The Pre-Amp setting affects sample volume only. Changing it may cause undesired effects on volume balance between sample based instruments and plugin instruments.\nIn other words: Don't touch this slider unless you know what you are doing."))
//#pragma warning(disable:4244) //"conversion from 'type1' to 'type2', possible loss of data"
Modified: trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp
===================================================================
--- trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp 2011-04-01 15:03:17 UTC (rev 835)
+++ trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp 2011-04-01 15:15:40 UTC (rev 836)
@@ -621,6 +621,7 @@
m_nRow = nRow;
m_nChannel = nChannel;
m_nPattern = nPat;
+ m_bModified = false;
// Init Pages
if (m_pageNote) m_pageNote->Init(m_Command);
if (m_pageVolume) m_pageVolume->Init(m_Command);
@@ -871,7 +872,7 @@
CSoundFile* pSndFile = m_pModDoc->GetSoundFile();
m_nInstr = combo->GetItemData(n);
//Checking whether note names should be recreated.
- if(pSndFile && pSndFile->Instruments[m_nInstr] && pSndFile->Instruments[oldInstr])
+ if(!MODCOMMAND::IsPcNote(m_nNote) && pSndFile && pSndFile->Instruments[m_nInstr] && pSndFile->Instruments[oldInstr])
{
if(pSndFile->Instruments[m_nInstr]->pTuning != pSndFile->Instruments[oldInstr]->pTuning)
UpdateDialog();
Modified: trunk/OpenMPT/mptrack/resource.h
===================================================================
--- trunk/OpenMPT/mptrack/resource.h 2011-04-01 15:03:17 UTC (rev 835)
+++ trunk/OpenMPT/mptrack/resource.h 2011-04-01 15:15:40 UTC (rev 836)
@@ -1185,6 +1185,7 @@
#define ID_SAMPLE_QUICKFADE 60454
#define ID_EDIT_MIXPASTE_ITSTYLE 60455
#define ID_VIEW_MPTHACKS 60456
+#define ID_PLUGINTOINSTRUMENT 60457
// Next default values for new objects
//
@@ -1192,7 +1193,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 529
-#define _APS_NEXT_COMMAND_VALUE 60457
+#define _APS_NEXT_COMMAND_VALUE 60458
#define _APS_NEXT_CONTROL_VALUE 2435
#define _APS_NEXT_SYMED_VALUE 901
#endif
Modified: trunk/OpenMPT/mptrack/version.h
===================================================================
--- trunk/OpenMPT/mptrack/version.h 2011-04-01 15:03:17 UTC (rev 835)
+++ trunk/OpenMPT/mptrack/version.h 2011-04-01 15:15:40 UTC (rev 836)
@@ -14,8 +14,8 @@
//Version definitions. The only thing that needs to be changed when changing version number.
#define VER_MAJORMAJOR 1
#define VER_MAJOR 19
-#define VER_MINOR 00
-#define VER_MINORMINOR 31
+#define VER_MINOR 01
+#define VER_MINORMINOR 00
//Creates version number from version parts that appears in version string.
//For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of
Modified: trunk/OpenMPT/packageTemplate/History.txt
===================================================================
--- trunk/OpenMPT/packageTemplate/History.txt 2011-04-01 15:03:17 UTC (rev 835)
+++ trunk/OpenMPT/packageTemplate/History.txt 2011-04-01 15:15:40 UTC (rev 836)
@@ -7,18 +7,16 @@
[Reg]: known issue / regression
[Mod]: change
[Var]: other
-(tx XYZ): thanks to XYZ for telling us about the bug
+(tx XYZ): thanks to XYZ for telling us about the bug / requesting the feature
-v1.19.01.00 (March 2011, revision 833)
+v1.19.01.00 (April 2011, revision 836)
--------------------------------------
Pattern tab
- [New] <Jojo> Clicking and dragging the row numbers selects the whole row now (Excel / Calc style) - see http://bugs.openmpt.org/view.php?id=45
+ [New] <Jojo> Clicking and dragging the row numbers selects the whole row in Excel / Calc style (http://bugs.openmpt.org/view.php?id=45)
[New] <Jojo> The new keyboard shortcuts "Select beat" and "Select measure" can be used to automatically extend the current selection to the beat / measure boundaries.
[New] <Jojo> Experimental feature: Play the whole pattern row when entering notes and chords into the pattern editor. This can be enabled from the setup screen.
- [Imp] <Jojo> Special paste modes have been moved to a sub menu in the context menu, to save some space.
- [Imp] <Jojo> Status bar now indicates if highpass filter is enabled on a channel. (http://bugs.openmpt.org/view.php?id=92)
- [Mod] <Jojo> Using the Goto Dialog should now update channel parameters and set the elapsed time. (http://bugs.openmpt.org/view.php?id=28)
+ [Mod] <Jojo> Using the Goto Dialog updates channel parameters and sets the elapsed time now. (http://bugs.openmpt.org/view.php?id=28)
[Mod] <Jojo> Undo steps have been increased from 100 to 1000.
[Fix] <Jojo> Shrink selection is more consistent with Shrink pattern now: Entries on odd rows are not ignored anymore if there is no entry in the even rows. Also, cleaning of the pattern after shrinking the selection has been fixed - it cleaned whole commands instead of just the selected parts of a command. (http://bugs.openmpt.org/view.php?id=89)
[Fix] <Jojo> Cursor paste was possible even when editing was disabled.
@@ -37,6 +35,7 @@
Pattern tab::Note properties
[Fix] <Jojo> The meaning of Q0x was displayed wrong for S3M / IT.
[Fix] <Jojo> Changing a value didn't create an undo point. (http://bugs.openmpt.org/view.php?id=56)
+ [Fix] <Jojo> Setting the PC note plugin didn't work.
Pattern tab::Find/replace
[New] <Jojo> Added Find / Replace mode: Find in current pattern selection. (http://bugs.openmpt.org/view.php?id=42)
@@ -44,6 +43,8 @@
[Mod] <Jojo> "Replace All" just creates one undo point now.
Pattern tab::GUI
+ [Imp] <Jojo> Special paste modes have been moved to a sub menu in the context menu, to save some space.
+ [Imp] <Jojo> Status bar now indicates if highpass filter is enabled on a channel. (http://bugs.openmpt.org/view.php?id=92)
[Imp] <Jojo> The dodgy note colour is now also customisable.
[Mod] <Jojo> When removing a channel (via context menu) that contains no data in any pattern, no warning is shown anymore.
@@ -59,6 +60,7 @@
[Fix] <re> Changing zoom level should now preserve the view position better. (http://bugs.openmpt.org/view.php?id=3)
Instrument tab
+ [New] <Jojo> Clicking on an empty plugin slot in the plugin dropdown list opens the "Add Plugin" dialog (tx coda)
[Imp] <re> Ctrl + Mouse Wheel can now be used for zooming into the envelopes.
[Imp] <Jojo> When pressing the up arrow key in the sample map while the cursor is on the lowest note (C-0), the sample map doesn't lose focus anymore. It is also not possible anymore to move the sample map out of view by clicking the area above the lowest note.
[Mod] <Jojo> Copying and pasting envelopes with no points isn't possible anymore. (Who wants to do that anyway?)
@@ -69,6 +71,7 @@
VST
[New] <Jojo> Plugins can now request common file dialogs (file and directory selection).
+ [New] <Jojo> New menu entry in the plugin editor: Create instrument from plugin
[Mod] <Jojo> When automatically inserting a new instrument from the VST editor, the bank and patch values are now not filled in anymore, so it is easier to change to another patch while editing.
[Mod] <Jojo> Various small improvements to support VST 2.4 plugins better.
[Fix] <Jojo> Speaker arrangement is now sent to the plugins upon initialization. This fixes Voxengo SPAN 2 (a VST 2.4 plugin). Does this break other multichannel plugins?
@@ -95,26 +98,28 @@
IT
[New] <Jojo> Edit history information can now be read from and saved to IT / MPTM files. This is based on an undocumented feature in Impulse Tracker. Use View -> Edit History for viewing or deleting this information.
[Imp] <Jojo> IT files made with Modplug Tracker 1.00a5 are now also detected as such. Since long patterns can also be created in other trackers (e.g. Chibi), long patterns are not used to identify files made with MPT anymore.
- [Imp] <Jojo> IT Loader: Autovibrato sweep is now fixed when loading IT files made with old versions of (Open)MPT.
[Mod] <Jojo> Sane values are used again for the "cwtv" and "cmwt" header fields when saving IT files; in fact the same values as in compatibility export are used. To be able to distinguish between raped and compatibility-exported IT files, "OMPT" is written in the "reserved" header field. As a consequence, IT files made with OpenMPT can now be loaded in Impulse Tracker again.
- [Mod] <Jojo> IT Loader: MIDI macros are now cleared when loading IT files made with old Impulse Tracker versions (< 2.14), so that Zxx commands won't break the songs anymore (fixes denonde.it, fix from Schism Tracker).
[Fix] <Jojo> Incorrect notes were memorized for PPS (and possibly other effects) when working with instruments that had non-default note assignments (f.e. C-5 => D-4)
[Fix] <Jojo> In compatible mode, bidi loops are now treated like in IT's software mixer. (http://bugs.openmpt.org/view.php?id=29)
[Fix] <Jojo> Sample autovibrato is now hopefully a bit closer to Impulse Tracker in compatible mode... (http://bugs.openmpt.org/view.php?id=5)
[Fix] <Jojo> The envelope handling was altered slightly to work more like in Schism Tracker. This fixes a combination of Envelope Carry + Portamento as it can be found in "electric bunny" by Alpha C.
[Fix] <Jojo> Various fixes to playback of multi-sample instruments. "Ultima Ratio" by Nebularia and "Shuttle Departure" by Sphenx sound better now.
[Fix] <Jojo> The extended sample map is not saved anymore in the instrument headers when using compatibility export.
- [Fix] <Jojo> IT Loader / Saver: Note mapping items that aren't notes are now ignored.
- [Fix] <Jojo> IT Saver: Non-existing envelopes are now replaced by a default (disabled) envelope, so that they can still be edited in Impulse Tracker.
+IT::Loading and Saving
+ [Imp] <Jojo> Autovibrato sweep is now fixed when loading IT files made with old versions of (Open)MPT.
+ [Mod] <Jojo> MIDI macros are now cleared when loading IT files made with old Impulse Tracker versions (< 2.14), so that Zxx commands won't break the songs anymore (fixes denonde.it, fix from Schism Tracker).
+ [Fix] <Jojo> Note mapping items that aren't notes (f.e. empty notes) are now ignored when loading and saving.
+ [Fix] <Jojo> When saving, non-existing envelopes are now replaced by a default (disabled) envelope, so that they can still be edited in Impulse Tracker.
+
MPTM
- [New] <Jojo> Each pattern can now have a custom time signature (rows per beat and rows per measure) which can be set from the pattern properties dialog.
+ [New] <Jojo> Each pattern can now have a custom time signature (rows per beat and rows per measure) which can be set from the pattern properties dialog. (http://forum.openmpt.org/index.php?topic=4022.0)
[New] <Jojo> Edit history information (read the "IT" section above for an explanation)
XM
- [Fix] <Jojo> XM Compatibility: Various mind-boggling combinations of EDx, notes and instrument numbers should work correctly now.
- [Fix] <Jojo> XM Compatibility: When there's a instrument number next to a 3xx effect which differs from the previous instrument number, it resets the instrument properties of the previous instrument now.
- [Fix] <Jojo> XM Compatibility: Portamento combined with an Offset command results in the offset command being ignored.
+ [Fix] <Jojo> Various mind-boggling combinations of EDx, notes and instrument numbers should work correctly in compatible mode now.
+ [Fix] <Jojo> When there's a instrument number next to a 3xx effect which differs from the previous instrument number, it resets the instrument properties of the previous instrument in compatible mode.
+ [Fix] <Jojo> Portamento combined with an Offset command results in the offset command being ignored in compatible mode.
[Fix] <Jojo> XM Loader: Fixed handling of instruments with no samples, so that instruments assigned to VST plugins work correctly.
MOD
@@ -122,9 +127,9 @@
[Fix] <Jojo> The maximum speed for MOD files was off by one in some places (31 instead of 32).
MOD::Loading
- [New] <Jojo> Added a heuristic detection for VBlank MODs. Most MODs use the CIA timer instead of VBlank timing, but some don't.
- [New] <Jojo> Added a heuristic detection for PT 1.x playback mode: If there is pattern data that looks like it needs on-the-fly sample swapping, PT 1.x mode is enabled.
- [New] <Jojo> Added a heuristic detection for MODs with 7-bit panning, which is then automatically converted to 8-bit panning.
+ [New] <Jojo> Heuristic detection for VBlank MODs. Most MODs use the CIA timer instead of VBlank timing, but some don't.
+ [New] <Jojo> Heuristic detection for PT 1.x playback mode: If there is pattern data that looks like it needs on-the-fly sample swapping, PT 1.x mode is enabled.
+ [New] <Jojo> Heuristic detection for MODs with 7-bit panning, which is then automatically converted to 8-bit panning.
[Fix] <Jojo> Tentative fix for MODs with short loops at the sample start that were most likely not intended.
S3M
@@ -133,8 +138,8 @@
[Fix] <Jojo> S3M Loader: Fix to pattern loader (for empty patterns)
[Fix] <Jojo> Removed the X param (#) effect from the supported effect list.
[Fix] <Jojo> Speed and tempo values are now adjusted to what Scream Tracker actually expects (speed 1 - 254, tempo 33 - 255) - anything out of this range is ignored by Scream Tracker, so it is now also ignored by OpenMPT.
- [Fix] <Jojo> Pattern breaks >= C40 are now ingnored.
- [Fix] <Jojo> Global volume commands > V40 are now ignored. Global volume is processed on tick 1 to emulate ST3's behaviour (far from perfect).
+ [Fix] <Jojo> Pattern breaks >= C40 are now ignored.
+ [Fix] <Jojo> Global volume commands > V40 are now ignored.
Other modules
[Imp] <Jojo> Garbage characters in sample / instrument / song names should be gone now.. This should f.e. avoid sample names like " ntitled" turning up in modules after deleting sample names.
@@ -160,6 +165,7 @@
[Mod] <Jojo> The "Original" mix mode now also has a version number (1.16) to reflect what the "original" thing is.
[Mod] <Jojo> Updated genre list in the MP3 export dialog.
[Mod] <Jojo> When using the ACM MP3 codec, 320kbit/s bitrate should now be available.
+ [Mod] <Jojo> "No extra-loud samples" is now enabled by default (as it's more suitable for mixmodes RC3 and Original)
[Mod] <Jojo> The MMX acceleration label in the Soundcard setup dialog is now updated according to the multimedia extensions that are supported by the CPU (3DNow! / SSE)
[Mod] <Jojo> Updated unmo3.dll to version 2.4.0.1
[Mod] <Jojo> Updated the internet link list in the Help menu.
@@ -766,16 +772,14 @@
Mod conversion
[Imp] <Jojo> Convert E9x to Q8x as Q0x actually means "continue" and not "no change" for the volume change.
- [Imp] <Jojo> Even better conversion of various pattern effects, including 8-Bit Panning, Arpeggio (XM swaps the two parameters) including Surround, Note Cut/Off/Fade conversion, MOD retrigger, XM->IT volume column limitations, illegal notes).
+ [Imp] <Jojo> Even better conversion of various pattern effects, including 7/8-Bit Panning, Surround, Note Cut/Off/Fade conversion, MOD retrigger, XM->IT volume column limitations, illegal notes).
[Imp] <Jojo> Proper conversion of Pxy effect.
[Imp] <Jojo> Full volume column conversion, resetting default global volume / tempo / speed for MOD files.
[Imp] <Jojo> \xx is converted to Zxx when converting to / saving S3M files or "compatible" IT files.
[Imp] <Jojo> Somewhat decent conversion of Kxx (Key Off) from XM to S3M/IT.
[Imp] <Jojo> Trim instrument envelopes if they're too long for the new format.
- [Imp] <Jojo> Convert 500/600 commands properly from MOD to any format, Adjust sustain loops for XM files, removed XM arpeggio conversion (it might be unwanted).
+ [Imp] <Jojo> Convert 500/600 commands properly from MOD to any format, Adjust sustain loops for XM files.
[Imp] <Jojo> Try to use fix commands that don't have a "memory" (00 value) in XM (Arpeggio) and MOD format (Arpeggio and a few others) by using the previous value.
- [Fix] <Jojo> Proper conversion between IT 8-Bit panning effect and S3M 7-Bit panning effect with surround.
- [Fix] <Jojo> Unset release nodes were corrupted when converting modules.
Playback (see also format-specific changes below)
[Imp] <Jojo> Mixing: It's now possible to go down to 1ms latency (works with ASIO).
@@ -843,7 +847,7 @@
S3M::Loading
[Imp] <Jojo> Smarter Zxx conversion without message box (heuristic detection).
- [Fix] <Jojo> Limit minimum sample preamp value to 16.
+ [Fix] <Jojo> Minimum sample preamp value is now 16 (like in ST3).
[Fix] <Jojo> Small modifications to pattern loader to load somewhat broken S3M files (fix from xmp).
[Fix] <Jojo> Don't reset global volume to max if it is 0 for "new" S3M modules.
[Fix] <Jojo> Disable loop for sample with very short loop at the beginning.
@@ -901,7 +905,7 @@
[Fix] <Jojo> F20 won't turn into G20.
MOD::Playback compatibility
- [Fix] <Jojo> 8-Bit Panning is not 7-Bit panning (using 800...8FF instead of 800...880 now - fixes f.e. DOPE.MOD).
+ [Fix] <Jojo> Using 8-Bit (800-8FF) Panning instead of 7-Bit panning (800-880) now - fixes f.e. DOPE.MOD.
[Fix] <Jojo> Pattern loops are now handled correctly.
Setup
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-01 15:03:24
|
Revision: 835
http://modplug.svn.sourceforge.net/modplug/?rev=835&view=rev
Author: saga-games
Date: 2011-04-01 15:03:17 +0000 (Fri, 01 Apr 2011)
Log Message:
-----------
[Fix] S3M Loader: Sample header and sample data offsets can now be 0. (The specs only say that pattern offset 0 means "empty pattern")
[Reg] Removed S3M global volume hacks from revision 831 (there are too many non-ST3 S3Ms around to emulate this faithfully)
Revision Links:
--------------
http://modplug.svn.sourceforge.net/modplug/?rev=831&view=rev
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_s3m.cpp
trunk/OpenMPT/soundlib/Snd_fx.cpp
Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_s3m.cpp 2011-04-01 14:59:06 UTC (rev 834)
+++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2011-04-01 15:03:17 UTC (rev 835)
@@ -355,7 +355,7 @@
for (UINT iSmp=1; iSmp<=insnum; iSmp++)
{
UINT nInd = ((DWORD)smppos[iSmp - 1]) * 16;
- if ((!nInd) || (nInd + 0x50 > dwMemLength)) continue;
+ if (nInd + 0x50 > dwMemLength) continue;
memcpy(s, lpStream + nInd, 0x50);
memcpy(Samples[iSmp].filename, s+1, 12);
@@ -504,7 +504,7 @@
}
// Reading samples
- for (UINT iRaw = 1; iRaw <= insnum; iRaw++) if ((Samples[iRaw].nLength) && (smpdatapos[iRaw - 1]))
+ for (UINT iRaw = 1; iRaw <= insnum; iRaw++) if (Samples[iRaw].nLength)
{
UINT flags = (psfh.version == 1) ? RS_PCM8S : RS_PCM8U;
if (insflags[iRaw-1] & 4) flags += 5;
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-04-01 14:59:06 UTC (rev 834)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-04-01 15:03:17 UTC (rev 835)
@@ -343,11 +343,11 @@
break;
// Global Volume
case CMD_GLOBALVOLUME:
- // ST3 applies global volume on tick 1 and does other weird things, but we just emulate this part for now.
- if((GetType() & MOD_TYPE_S3M) && nMusicSpeed <= 1)
- {
- break;
- }
+ // ST3 applies global volume on tick 1 and does other weird things, but we won't emulate this for now.
+// if((GetType() & MOD_TYPE_S3M) && nMusicSpeed <= 1)
+// {
+// break;
+// }
if (!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) param <<= 1;
if(IsCompatibleMode(TRK_IMPULSETRACKER | TRK_FASTTRACKER2 | TRK_SCREAMTRACKER))
@@ -1880,12 +1880,12 @@
// Set Global Volume
case CMD_GLOBALVOLUME:
- // ST3 applies global volume on tick 1 and does other weird things, but we just emulate this part for now.
- if(((GetType() & MOD_TYPE_S3M) && m_nTickCount != 1)
- || (!(GetType() & MOD_TYPE_S3M) && !(m_dwSongFlags & SONG_FIRSTTICK)))
- {
- break;
- }
+ // ST3 applies global volume on tick 1 and does other weird things, but we won't emulate this for now.
+// if(((GetType() & MOD_TYPE_S3M) && m_nTickCount != 1)
+// || (!(GetType() & MOD_TYPE_S3M) && !(m_dwSongFlags & SONG_FIRSTTICK)))
+// {
+// break;
+// }
if (!(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT))) param <<= 1;
//IT compatibility 16. FT2, ST3 and IT ignore out-of-range values
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-04-01 14:59:14
|
Revision: 834
http://modplug.svn.sourceforge.net/modplug/?rev=834&view=rev
Author: saga-games
Date: 2011-04-01 14:59:06 +0000 (Fri, 01 Apr 2011)
Log Message:
-----------
[Mod] Package Template: added latin-american keymaps (tx jmkz), as well as coda's US MPT/IT keymap.
[Mod] Added latin-american keymap autodetection to installer.
Modified Paths:
--------------
trunk/OpenMPT/installer/install.iss
Added Paths:
-----------
trunk/OpenMPT/packageTemplate/extraKeymaps/US_mptit_(coda).mkb
trunk/OpenMPT/packageTemplate/extraKeymaps/es-LA_it-mpt_jmkz.mkb
trunk/OpenMPT/packageTemplate/extraKeymaps/es-LA_mpt_jmkz.mkb
Modified: trunk/OpenMPT/installer/install.iss
===================================================================
--- trunk/OpenMPT/installer/install.iss 2011-03-27 12:41:58 UTC (rev 833)
+++ trunk/OpenMPT/installer/install.iss 2011-04-01 14:59:06 UTC (rev 834)
@@ -208,6 +208,14 @@
begin
keyboardFilepath := 'DE_jojo';
end;
+ $0a: // Spanish
+ begin
+ // Spanish latin-american keymap, so we ignore Spain.
+ if(GetUILanguage <> $0c0a) then
+ begin
+ keyboardFilepath := 'es-LA_mpt_(jmkz)';
+ end;
+ end;
$0c: // French
begin
keyboardFilepath := 'FR_mpt_(legovitch)';
Added: trunk/OpenMPT/packageTemplate/extraKeymaps/US_mptit_(coda).mkb
===================================================================
--- trunk/OpenMPT/packageTemplate/extraKeymaps/US_mptit_(coda).mkb (rev 0)
+++ trunk/OpenMPT/packageTemplate/extraKeymaps/US_mptit_(coda).mkb 2011-04-01 14:59:06 UTC (rev 834)
@@ -0,0 +1,338 @@
+//-------- OpenMPT key binding definition file -------
+//-Format is: -
+//- Context:Command ID:Modifiers:Key:KeypressEventType //Comments -
+//----------------------------------------------------------------------
+version:1
+
+//----( Global Context (0) )------------
+0:1347:2:78:1 //File/New: Ctrl+N (KeyDown)
+0:1346:0:120:1 //File/Open: F9 (KeyDown)
+0:1346:2:82:1 //File/Open: Ctrl+R (KeyDown)
+0:1348:2:82:2 //File/Close: Ctrl+R (KeyUp)
+0:1349:2:83:1 //File/Save: Ctrl+S (KeyDown)
+0:1350:2:87:1 //File/Save As: Ctrl+W (KeyDown)
+0:1350:0:121:1 //File/Save As: F10 (KeyDown)
+0:1030:0:116:2 //Play song/Pause song: F5 (KeyUp)
+0:1031:0:119:1 //Pause song: F8 (KeyDown)
+0:1029:2:116:1 //Play song from start: Ctrl+F5 (KeyDown)
+0:1028:0:118:1 //Play song from cursor: F7 (KeyDown)
+0:1027:0:117:5 //Play pattern from start: F6 (KeyDown|KeyHold)
+0:1026:2:118:5 //Play pattern from cursor: Ctrl+F7 (KeyDown|KeyHold)
+0:1374:2:80:1 //Estimate Song Length: Ctrl+P (KeyDown)
+0:1359:2:8:1 //Undo: Ctrl+Backspace (KeyDown)
+0:1360:2:88:1 //Cut: Ctrl+X (KeyDown)
+0:1361:2:67:1 //Copy: Ctrl+C (KeyDown)
+0:1362:2:86:1 //Paste: Ctrl+V (KeyDown)
+0:1686:4:77:1 //Mix Paste (old IT Style): Alt+M (KeyDown)
+0:1793:3:86:1 //Paste Flood: Shift+Ctrl+V (KeyDown)
+0:1021:0:122:1 //View General: F11 (KeyDown)
+0:1022:0:113:1 //View Pattern: F2 (KeyDown)
+0:1022:0:116:1 //View Pattern: F5 (KeyDown)
+0:1023:0:114:1 //View Samples: F3 (KeyDown)
+0:1024:0:115:1 //View Instruments: F4 (KeyDown)
+0:1025:1:120:1 //View Comments: Shift+F9 (KeyDown)
+0:1367:4:122:1 //Toggle Main View: Alt+F11 (KeyDown)
+0:1368:4:122:2 //Toggle Tree View: Alt+F11 (KeyUp)
+0:1369:0:123:1 //View Options: F12 (KeyDown)
+0:1370:0:112:1 //Help (to do): F1 (KeyDown)
+0:1032:1:188:5 //Previous instrument: Shift+, (KeyDown|KeyHold)
+0:1032:2:38:5 //Previous instrument: Ctrl+Up (KeyDown|KeyHold)
+0:1033:1:190:5 //Next instrument: Shift+. (KeyDown|KeyHold)
+0:1033:2:40:5 //Next instrument: Ctrl+Down (KeyDown|KeyHold)
+0:1036:0:111:5 //Previous octave: Num / (KeyDown|KeyHold)
+0:1037:0:106:5 //Next octave: Num * (KeyDown|KeyHold)
+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:2:34:5 //Jump down by measure: Ctrl+Page Down (KeyDown|KeyHold)
+2:1018:2:33:5 //Jump up by measure: Ctrl+Page Up (KeyDown|KeyHold)
+2:1338:4:34:5 //Jump down by beat: Alt+Page Down (KeyDown|KeyHold)
+2:1339:4:33:5 //Jump up by beat: Alt+Page Up (KeyDown|KeyHold)
+2:1019:0:34:5 //Snap down to measure: Page Down (KeyDown|KeyHold)
+2:1020:0:33:5 //Snap up to measure: Page Up (KeyDown|KeyHold)
+2:1340:6:34:5 //Snap down to beat: Ctrl+Alt+Page Down (KeyDown|KeyHold)
+2:1341:6:33:5 //Snap up to beat: Ctrl+Alt+Page Up (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: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+Shift (KeyDown)
+2:1051:2:17:1 //Copy select key: Ctrl+Ctrl (KeyDown)
+2:1011:4:76:1 //Select channel / Select all: Alt+L (KeyDown)
+2:1003:0:13:1 //Quick copy: Enter (KeyDown)
+2:1004:0:32:5 //Quick paste: Space (KeyDown|KeyHold)
+2:1002:0:56:1 //Play row: 8 (KeyDown)
+2:1317:4:18:1 //Set row jump on note entry: Alt+Alt (KeyDown)
+2:1062:0:93:1 //Show note properties: Application (KeyDown)
+2:1063:2:93:1 //Show context (right-click) menu: Ctrl+Application (KeyDown)
+2:1005:4:120:1 //Mute current channel: Alt+F9 (KeyDown)
+2:1006:4:121:1 //Solo current channel: Alt+F10 (KeyDown)
+2:1671:4:67:1 //Copy and lose selection: Alt+C (KeyDown)
+2:1007:4:81:5 //Transpose +1: Alt+Q (KeyDown|KeyHold)
+2:1008:4:65:5 //Transpose -1: Alt+A (KeyDown|KeyHold)
+2:1009:6:81:5 //Transpose +12: Ctrl+Alt+Q (KeyDown|KeyHold)
+2:1010:6:65:5 //Transpose -12: Ctrl+Alt+A (KeyDown|KeyHold)
+2:1012:4:74:1 //Amplify selection: Alt+J (KeyDown)
+2:1014:4:75:1 //Interpolate volume: Alt+K (KeyDown)
+2:1015:4:88:1 //Interpolate effect: Alt+X (KeyDown)
+2:1016:4:66:1 //Open effect visualizer: Alt+B (KeyDown)
+2:1013:4:83:1 //Apply current instrument: Alt+S (KeyDown)
+2:1664:0:46:1 //Clear field (IT Style): Delete (KeyDown)
+2:1665:0:190:5 //Clear field and step (IT Style): . (KeyDown|KeyHold)
+2:1061:0:8:1 //Delete rows: Backspace (KeyDown)
+2:1377:1:46:1 //Delete all rows: Shift+Delete (KeyDown)
+2:1378:0:45:5 //Insert Row: Insert (KeyDown|KeyHold)
+2:1379:1:45:5 //Insert All Rows: Shift+Insert (KeyDown|KeyHold)
+2:1055:0:109:1 //Previous pattern: Num - (KeyDown)
+2:1054:0:107:1 //Next pattern: Num + (KeyDown)
+
+//----( Pattern Context [bottom] - Note Col (3) )------------
+3:1064:0:90:1 //Base octave C: Z (KeyDown)
+3:1065:0:83:1 //Base octave C#: S (KeyDown)
+3:1066:0:88:1 //Base octave D: X (KeyDown)
+3:1067:0:68:1 //Base octave D#: D (KeyDown)
+3:1068:0:67:1 //Base octave E: C (KeyDown)
+3:1069:0:86:1 //Base octave F: V (KeyDown)
+3:1070:0:71:1 //Base octave F#: G (KeyDown)
+3:1071:0:66:1 //Base octave G: B (KeyDown)
+3:1072:0:72:1 //Base octave G#: H (KeyDown)
+3:1073:0:78:1 //Base octave A: N (KeyDown)
+3:1074:0:74:1 //Base octave A#: J (KeyDown)
+3:1075:0:77:1 //Base octave B: M (KeyDown)
+3:1076:0:81:1 //Base octave +1 C: Q (KeyDown)
+3:1076:0:188:1 //Base octave +1 C: , (KeyDown)
+3:1077:0:50:1 //Base octave +1 C#: 2 (KeyDown)
+3:1077:0:76:1 //Base octave +1 C#: L (KeyDown)
+3:1078:0:87:1 //Base octave +1 D: W (KeyDown)
+3:1079:0:51:1 //Base octave +1 D#: 3 (KeyDown)
+3:1080:0:69:1 //Base octave +1 E: E (KeyDown)
+3:1081:0:82:1 //Base octave +1 F: R (KeyDown)
+3:1082:0:53:1 //Base octave +1 F#: 5 (KeyDown)
+3:1083:0:84:1 //Base octave +1 G: T (KeyDown)
+3:1084:0:54:1 //Base octave +1 G#: 6 (KeyDown)
+3:1085:0:89:1 //Base octave +1 A: Y (KeyDown)
+3:1086:0:55:1 //Base octave +1 A#: 7 (KeyDown)
+3:1087:0:85:1 //Base octave +1 B: U (KeyDown)
+3:1088:0:73:1 //Base octave +2 C: I (KeyDown)
+3:1089:0:57:1 //Base octave +2 C#: 9 (KeyDown)
+3:1090:0:79:1 //Base octave +2 D: O (KeyDown)
+3:1091:0:48:1 //Base octave +2 D#: 0 (KeyDown)
+3:1092:0:80:1 //Base octave +2 E: P (KeyDown)
+3:1093:0:189:1 //Base octave +2 F: - (KeyDown)
+3:1212:0:96:1 //Set octave 0: Num 0 (KeyDown)
+3:1213:0:97:1 //Set octave 1: Num 1 (KeyDown)
+3:1214:0:98:1 //Set octave 2: Num 2 (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:101:1 //Set octave 5: Num 5 (KeyDown)
+3:1218:0:102:1 //Set octave 6: Num 6 (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:105:1 //Set octave 9: Num 9 (KeyDown)
+3:1316:1:16:1 //Chord Modifier: Shift+Shift (KeyDown)
+3:1667:0:49:1 //Note Cut (don't remember instrument): 1 (KeyDown)
+3:1668:0:192:1 //Note Off (don't remember instrument): ` (KeyDown)
+3:1788:1:49:1 //Parameter control(MPTm only): Shift+1 (KeyDown)
+3:1789:3:49:1 //Parameter control(smooth)(MPTm only): Shift+Ctrl+1 (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:1246:0:79:1 //Vol command - Offset: O (KeyDown)
+
+//----( Pattern Context [bottom] - FX Col (6) )------------
+
+//----( Pattern Context [bottom] - Param Col (7) )------------
+7:1247:0:48:1 //FX Param digit 0: 0 (KeyDown)
+7:1248:0:49:1 //FX Param digit 1: 1 (KeyDown)
+7:1249:0:50:1 //FX Param digit 2: 2 (KeyDown)
+7:1250:0:51:1 //FX Param digit 3: 3 (KeyDown)
+7:1251:0:52:1 //FX Param digit 4: 4 (KeyDown)
+7:1252:0:53:1 //FX Param digit 5: 5 (KeyDown)
+7:1253:0:54:1 //FX Param digit 6: 6 (KeyDown)
+7:1254:0:55:1 //FX Param digit 7: 7 (KeyDown)
+7:1255:0:56:1 //FX Param digit 8: 8 (KeyDown)
+7:1256:0:57:1 //FX Param digit 9: 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:1673:0:13:1 //Load a Sample: Enter (KeyDown)
+8:1673:4:79:1 //Load a Sample: Alt+O (KeyDown)
+8:1674:4:83:1 //Save Sample: Alt+S (KeyDown)
+8:1675:0:45:1 //New Sample: Insert (KeyDown)
+8:1380:4:66:1 //Trim sample around loop points: Alt+B (KeyDown)
+8:1380:4:76:1 //Trim sample around loop points: Alt+L (KeyDown)
+8:1383:0:190:1 //Silence sample selection: . (KeyDown)
+8:1384:4:78:1 //Normalise Sample: Alt+N (KeyDown)
+8:1385:4:77:1 //Amplify Sample: Alt+M (KeyDown)
+8:1381:4:71:1 //Reverse sample: Alt+G (KeyDown)
+8:1382:0:46:1 //Delete sample selection: Delete (KeyDown)
+8:1386:0:107:1 //Zoom Out: Num + (KeyDown)
+8:1387:0:109:1 //Zoom In: Num - (KeyDown)
+8:1784:2:73:1 //Invert sample phase: Ctrl+I (KeyDown)
+8:1785:2:85:1 //Signed/Unsigned conversion: Ctrl+U (KeyDown)
+8:1790:2:69:1 //Remove DC Offset: Ctrl+E (KeyDown)
+8:1856:2:68:1 //Quick fade: Ctrl+D (KeyDown)
+8:1857:2:76:1 //Crossfade sample loop: Ctrl+L (KeyDown)
+
+//----( Instrument Context [bottom] (9) )------------
+9:1837:0:107:5 //Zoom In: Num + (KeyDown|KeyHold)
+9:1838:0:109:5 //Zoom Out: Num - (KeyDown|KeyHold)
+9:1825:1:9:5 //Select previous envelope point: Shift+Tab (KeyDown|KeyHold)
+9:1826:0:9:5 //Select next envelope point: Tab (KeyDown|KeyHold)
+9:1821:0:37:5 //Move envelope point left: Left (KeyDown|KeyHold)
+9:1822:0:39:5 //Move envelope point right: Right (KeyDown|KeyHold)
+9:1823:0:38:5 //Move envelope point up: Up (KeyDown|KeyHold)
+9:1834:0:33:5 //Move envelope point up (big step): Page Up (KeyDown|KeyHold)
+9:1824:0:40:5 //Move envelope point down: Down (KeyDown|KeyHold)
+9:1835:0:34:5 //Move envelope point down (big step): Page Down (KeyDown|KeyHold)
+9:1827:0:45:5 //Insert envelope point: Insert (KeyDown|KeyHold)
+9:1828:0:46:5 //Remove envelope point: Delete (KeyDown|KeyHold)
+9:1829:0:36:1 //Set loop start: Home (KeyDown)
+9:1830:0:35:1 //Set loop end: End (KeyDown)
+9:1831:2:36:1 //Set sustain loop start: Ctrl+Home (KeyDown)
+9:1832:2:35:1 //Set sustain loop end: Ctrl+End (KeyDown)
+9:1833:2:82:1 //Toggle release node: Ctrl+R (KeyDown)
+
+//----( Comments Context [bottom] (10) )------------
+
+//----( Unknown Context (11) )------------
+
+//----( Unknown Context (12) )------------
+
+//----( Plugin GUI Context (13) )------------
+13:1763:0:37:1 //Previous plugin preset: Left (KeyDown)
+13:1764:0:39:1 //Next plugin preset: Right (KeyDown)
+13:1782:0:38:1 //Plugin preset backward jump: Up (KeyDown)
+13:1783:0:40:1 //Plugin preset forward jump: Down (KeyDown)
+13:1765:2:80:1 //Randomize plugin parameters: Ctrl+P (KeyDown)
+13:1839:2:82:1 //Toggle parameter recording: Ctrl+R (KeyDown)
+13:1840:2:75:1 //Pass key presses to plugin: Ctrl+K (KeyDown)
+13:1841:2:66:1 //Bypass plugin: Ctrl+B (KeyDown)
+
+//----( General Context [top] (14) )------------
+
+//----( Pattern Context [top] (15) )------------
+
+//----( Sample Context [top] (16) )------------
+
+//----( Instrument Context [top] (17) )------------
+17:1851:2:68:1 //Duplicate instrument: Ctrl+D (KeyDown)
+17:1850:3:69:1 //Edit sample map: Shift+Ctrl+E (KeyDown)
+17:1849:2:69:1 //Edit current sample: Ctrl+E (KeyDown)
+17:1846:3:77:1 //Map all notes to selected note: Shift+Ctrl+M (KeyDown)
+17:1847:2:77:1 //Map all notes to selected sample: Ctrl+M (KeyDown)
+17:1848:2:82:1 //Reset note mapping: Ctrl+R (KeyDown)
+17:1843:4:81:1 //Transpose +1 (note map): Alt+Q (KeyDown)
+17:1842:4:65:1 //Transpose -1 (note map): Alt+A (KeyDown)
+17:1845:6:81:1 //Transpose +12 (note map): Ctrl+Alt+Q (KeyDown)
+17:1844:6:65:1 //Transpose -12 (note map): Ctrl+Alt+A (KeyDown)
+
+//----( Comments Context [top] (18) )------------
+
+//----( Orderlist (19) )------------
+19:1802:0:46:5 //Delete Order: Delete (KeyDown|KeyHold)
+19:1803:0:45:5 //Insert Order: Insert (KeyDown|KeyHold)
+19:1804:0:13:5 //Edit Pattern: Enter (KeyDown|KeyHold)
+19:1805:0:9:5 //Switch to pattern editor: Tab (KeyDown|KeyHold)
+19:1794:0:37:5 //Previous Order: Left (KeyDown|KeyHold)
+19:1794:0:38:5 //Previous Order: Up (KeyDown|KeyHold)
+19:1795:0:39:5 //Next Order: Right (KeyDown|KeyHold)
+19:1795:0:40:5 //Next Order: Down (KeyDown|KeyHold)
+19:1796:0:36:5 //First Order: Home (KeyDown|KeyHold)
+19:1797:0:35:5 //Last Order: End (KeyDown|KeyHold)
+19:1807:0:48:5 //Pattern index digit 0: 0 (KeyDown|KeyHold)
+19:1807:0:96:5 //Pattern index digit 0: Num 0 (KeyDown|KeyHold)
+19:1808:0:49:5 //Pattern index digit 1: 1 (KeyDown|KeyHold)
+19:1808:0:97:5 //Pattern index digit 1: Num 1 (KeyDown|KeyHold)
+19:1809:0:50:5 //Pattern index digit 2: 2 (KeyDown|KeyHold)
+19:1809:0:98:5 //Pattern index digit 2: Num 2 (KeyDown|KeyHold)
+19:1810:0:51:5 //Pattern index digit 3: 3 (KeyDown|KeyHold)
+19:1810:0:99:5 //Pattern index digit 3: Num 3 (KeyDown|KeyHold)
+19:1811:0:52:5 //Pattern index digit 4: 4 (KeyDown|KeyHold)
+19:1811:0:100:5 //Pattern index digit 4: Num 4 (KeyDown|KeyHold)
+19:1812:0:53:5 //Pattern index digit 5: 5 (KeyDown|KeyHold)
+19:1812:0:101:5 //Pattern index digit 5: Num 5 (KeyDown|KeyHold)
+19:1813:0:54:5 //Pattern index digit 6: 6 (KeyDown|KeyHold)
+19:1813:0:102:5 //Pattern index digit 6: Num 6 (KeyDown|KeyHold)
+19:1814:0:55:5 //Pattern index digit 7: 7 (KeyDown|KeyHold)
+19:1814:0:103:5 //Pattern index digit 7: Num 7 (KeyDown|KeyHold)
+19:1815:0:56:5 //Pattern index digit 8: 8 (KeyDown|KeyHold)
+19:1815:0:104:5 //Pattern index digit 8: Num 8 (KeyDown|KeyHold)
+19:1816:0:57:5 //Pattern index digit 9: 9 (KeyDown|KeyHold)
+19:1816:0:105:5 //Pattern index digit 9: Num 9 (KeyDown|KeyHold)
+19:1817:0:107:5 //Increase pattern index : Num + (KeyDown|KeyHold)
+19:1817:0:187:5 //Increase pattern index : = (KeyDown|KeyHold)
+19:1818:0:109:5 //Decrease pattern index: Num - (KeyDown|KeyHold)
+19:1818:0:189:5 //Decrease pattern index: - (KeyDown|KeyHold)
+19:1853:0:73:1 //Ignore (+++) Index: I (KeyDown)
+19:1854:0:32:1 //Invalid (---) Index: Space (KeyDown)
Added: trunk/OpenMPT/packageTemplate/extraKeymaps/es-LA_it-mpt_jmkz.mkb
===================================================================
--- trunk/OpenMPT/packageTemplate/extraKeymaps/es-LA_it-mpt_jmkz.mkb (rev 0)
+++ trunk/OpenMPT/packageTemplate/extraKeymaps/es-LA_it-mpt_jmkz.mkb 2011-04-01 14:59:06 UTC (rev 834)
@@ -0,0 +1,367 @@
+//-------- OpenMPT key binding definition file -------
+//-Format is: -
+//- Context:Command ID:Modifiers:Key:KeypressEventType //Comments -
+//----------------------------------------------------------------------
+version:1
+
+//----( 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:1350:3:83:1 //File/Save As: Shift+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:1 //Play pattern from start: F7 (KeyDown)
+0:1026:2:118:1 //Play pattern from cursor: Ctrl+F7 (KeyDown)
+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:1362:2:86:1 //Paste: Ctrl+V (KeyDown)
+0:1362:1:45:1 //Paste: Shift+INSERT (KeyDown)
+0:1363:3:86:1 //Mix Paste: Shift+Ctrl+V (KeyDown)
+0:1793:1:86:5 //Paste Flood: Shift+V (KeyDown|KeyHold)
+0:1820:6:86:1 //Push Forward Paste: Ctrl+Alt+V (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:1025:4:67:1 //View Comments: Alt+C (KeyDown)
+0:1368:2:113:1 //Toggle Tree View: Ctrl+F2 (KeyDown)
+0:1369:2:112:1 //View Options: Ctrl+F1 (KeyDown)
+0:1781:2:114:1 //View MIDI mapping: Ctrl+F3 (KeyDown)
+0:1370:0:112:1 //Help (to do): F1 (KeyDown)
+0:1032:2:111:5 //Previous instrument: Ctrl+TECLA DE DIVISION (KeyDown|KeyHold)
+0:1032:2:38:5 //Previous instrument: Ctrl+FLECHA ARRIBA (KeyDown|KeyHold)
+0:1033:2:106:5 //Next instrument: Ctrl+TECLA DE MULTIPLICACION (KeyDown|KeyHold)
+0:1033:2:40:5 //Next instrument: Ctrl+FLECHA ABAJO (KeyDown|KeyHold)
+0:1036:0:111:1 //Previous octave: TECLA DE DIVISION (KeyDown)
+0:1037:0:106:1 //Next octave: TECLA DE MULTIPLICACION (KeyDown)
+0:1034:2:37:5 //Previous order: Ctrl+FLECHA IZQUIERDA (KeyDown|KeyHold)
+0:1035:2:39:5 //Next order: Ctrl+FLECHA DERECHA (KeyDown|KeyHold)
+
+//----( General Context [bottom] (1) )------------
+
+//----( Pattern Context [bottom] (2) )------------
+2:1017:0:34:5 //Jump down by measure: AV PAG (KeyDown|KeyHold)
+2:1018:0:33:5 //Jump up by measure: RE PAG (KeyDown|KeyHold)
+2:1338:4:34:5 //Jump down by beat: Alt+AV PAG (KeyDown|KeyHold)
+2:1339:4:33:5 //Jump up by beat: Alt+RE PAG (KeyDown|KeyHold)
+2:1340:6:34:5 //Snap down to beat: Ctrl+Alt+AV PAG (KeyDown|KeyHold)
+2:1341:6:33:5 //Snap up to beat: Ctrl+Alt+RE PAG (KeyDown|KeyHold)
+2:1038:0:40:5 //Navigate down by 1 row: FLECHA ABAJO (KeyDown|KeyHold)
+2:1039:0:38:5 //Navigate up by 1 row: FLECHA ARRIBA (KeyDown|KeyHold)
+2:1691:4:40:5 //Navigate down by spacing: Alt+FLECHA ABAJO (KeyDown|KeyHold)
+2:1692:4:38:5 //Navigate up by spacing: Alt+FLECHA ARRIBA (KeyDown|KeyHold)
+2:1040:0:37:5 //Navigate left: FLECHA IZQUIERDA (KeyDown|KeyHold)
+2:1041:0:39:5 //Navigate right: FLECHA DERECHA (KeyDown|KeyHold)
+2:1042:0:9:5 //Navigate to next channel: TABULACION (KeyDown|KeyHold)
+2:1043:1:9:5 //Navigate to previous channel: Shift+TABULACION (KeyDown|KeyHold)
+2:1044:0:36:1 //Go to first channel: INICIO (KeyDown)
+2:1045:2:36:1 //Go to first row: Ctrl+INICIO (KeyDown)
+2:1046:6:36:1 //Go to first row of first channel: Ctrl+Alt+INICIO (KeyDown)
+2:1047:0:35:1 //Go to last channel: FIN (KeyDown)
+2:1048:2:35:1 //Go to last row: Ctrl+FIN (KeyDown)
+2:1049:6:35:1 //Go to last row of last channel: Ctrl+Alt+FIN (KeyDown)
+2:1050:1:16:1 //Selection key: Shift+MAYUSCULAS (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:1 //Quick copy: ENTRAR (KeyDown)
+2:1004:0:32:5 //Quick paste: BARRA ESPACIADORA (KeyDown|KeyHold)
+2:1001:2:32:1 //Enable recording: Ctrl+BARRA ESPACIADORA (KeyDown)
+2:1002:2:13:5 //Play row: Ctrl+ENTRAR (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+TABULACION (KeyDown)
+2:1806:2:68:1 //Duplicate pattern: Ctrl+D (KeyDown)
+2:1836:2:191:1 //Edit plugin assigned to PC note: Ctrl+} (KeyDown)
+2:1662:6:80:1 //Toggle channel's plugin editor: Ctrl+Alt+P (KeyDown)
+2:1062:0:93:1 //Show note properties: APLICACI\xD3N (KeyDown)
+2:1772:5:80:1 //Show pattern properties window: Shift+Alt+P (KeyDown)
+2:1819:2:69:1 //Split Keyboard Settings dialog: Ctrl+E (KeyDown)
+2:1776:1:122:1 //Toggle loop pattern: Shift+F11 (KeyDown)
+2:1780:2:84:1 //Show playback time at current row: Ctrl+T (KeyDown)
+2:1005:0:121:1 //Mute current channel: F10 (KeyDown)
+2:1006:2:121:1 //Solo current channel: Ctrl+F10 (KeyDown)
+2:1771:6:121:1 //Unmute all channels: Ctrl+Alt+F10 (KeyDown)
+2:1786:2:82:1 //Reset channel: Ctrl+R (KeyDown)
+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: SUPR (KeyDown)
+2:1664:1:190:1 //Clear field (IT Style): Shift+. (KeyDown)
+2:1059:2:46:5 //Clear row and step: Ctrl+SUPR (KeyDown|KeyHold)
+2:1665:1:46:5 //Clear field and step (IT Style): Shift+SUPR (KeyDown|KeyHold)
+2:1061:0:8:5 //Delete rows: RETROCESO (KeyDown|KeyHold)
+2:1377:2:8:5 //Delete all rows: Ctrl+RETROCESO (KeyDown|KeyHold)
+2:1378:0:45:5 //Insert Row: INSERT (KeyDown|KeyHold)
+2:1379:2:45:5 //Insert All Rows: Ctrl+INSERT (KeyDown|KeyHold)
+2:1055:0:109:5 //Previous pattern: TECLA DE SUSTRACCION (KeyDown|KeyHold)
+2:1054:0:107:5 //Next pattern: TECLA DE ADICION (KeyDown|KeyHold)
+
+//----( Pattern Context [bottom] - Note Col (3) )------------
+3:1064:0:90:1 //Base octave C: Z (KeyDown)
+3:1065:0:83:1 //Base octave C#: S (KeyDown)
+3:1066:0:88:1 //Base octave D: X (KeyDown)
+3:1067:0:68:1 //Base octave D#: D (KeyDown)
+3:1068:0:67:1 //Base octave E: C (KeyDown)
+3:1069:0:86:1 //Base octave F: V (KeyDown)
+3:1070:0:71:1 //Base octave F#: G (KeyDown)
+3:1071:0:66:1 //Base octave G: B (KeyDown)
+3:1072:0:72:1 //Base octave G#: H (KeyDown)
+3:1073:0:78:1 //Base octave A: N (KeyDown)
+3:1074:0:74:1 //Base octave A#: J (KeyDown)
+3:1075:0:77:1 //Base octave B: M (KeyDown)
+3:1076:0:81:1 //Base octave +1 C: Q (KeyDown)
+3:1076:0:188:1 //Base octave +1 C: , (KeyDown)
+3:1077:0:50:1 //Base octave +1 C#: 2 (KeyDown)
+3:1077:0:76:1 //Base octave +1 C#: L (KeyDown)
+3:1078:0:87:1 //Base octave +1 D: W (KeyDown)
+3:1078:0:190:1 //Base octave +1 D: . (KeyDown)
+3:1079:0:51:1 //Base octave +1 D#: 3 (KeyDown)
+3:1079:0:192:1 //Base octave +1 D#: \xF1 (KeyDown)
+3:1080:0:69:1 //Base octave +1 E: E (KeyDown)
+3:1080:0:189:1 //Base octave +1 E: - (KeyDown)
+3:1081:0:82:1 //Base octave +1 F: R (KeyDown)
+3:1082:0:53:1 //Base octave +1 F#: 5 (KeyDown)
+3:1083:0:84:1 //Base octave +1 G: T (KeyDown)
+3:1084:0:54:1 //Base octave +1 G#: 6 (KeyDown)
+3:1085:0:89:1 //Base octave +1 A: Y (KeyDown)
+3:1086:0:55:1 //Base octave +1 A#: 7 (KeyDown)
+3:1087:0:85:1 //Base octave +1 B: U (KeyDown)
+3:1088:0:73:1 //Base octave +2 C: I (KeyDown)
+3:1089:0:57:1 //Base octave +2 C#: 9 (KeyDown)
+3:1090:0:79:1 //Base octave +2 D: O (KeyDown)
+3:1091:0:48:1 //Base octave +2 D#: 0 (KeyDown)
+3:1092:0:80:1 //Base octave +2 E: P (KeyDown)
+3:1212:0:96:1 //Set octave 0: NUMERO 0 (KeyDown)
+3:1213:0:97:1 //Set octave 1: NUMERO 1 (KeyDown)
+3:1214:0:98:1 //Set octave 2: NUMERO 2 (KeyDown)
+3:1215:0:99:1 //Set octave 3: NUMERO 3 (KeyDown)
+3:1216:0:100:1 //Set octave 4: NUMERO 4 (KeyDown)
+3:1217:0:101:1 //Set octave 5: NUMERO 5 (KeyDown)
+3:1218:0:102:1 //Set octave 6: NUMERO 6 (KeyDown)
+3:1219:0:103:1 //Set octave 7: NUMERO 7 (KeyDown)
+3:1220:0:104:1 //Set octave 8: NUMERO 8 (KeyDown)
+3:1221:0:105:1 //Set octave 9: NUMERO 9 (KeyDown)
+3:1316:1:16:1 //Chord Modifier: Shift+MAYUSCULAS (KeyDown)
+3:1200:0:220:1 //Note Cut: | (KeyDown)
+3:1201:0:221:1 //Note Off: \xBF (KeyDown)
+3:1791:1:221:1 //Note Fade: Shift+\xBF (KeyDown)
+3:1788:1:219:1 //Parameter control(MPTm only): Shift+' (KeyDown)
+3:1789:0:219:1 //Parameter control(smooth)(MPTm only): ' (KeyDown)
+
+//----( Pattern Context [bottom] - Ins Col (4) )------------
+4:1202:0:96:1 //Set instrument digit 0: NUMERO 0 (KeyDown)
+4:1202:0:48:1 //Set instrument digit 0: 0 (KeyDown)
+4:1203:0:97:1 //Set instrument digit 1: NUMERO 1 (KeyDown)
+4:1203:0:49:1 //Set instrument digit 1: 1 (KeyDown)
+4:1204:0:98:1 //Set instrument digit 2: NUMERO 2 (KeyDown)
+4:1204:0:50:1 //Set instrument digit 2: 2 (KeyDown)
+4:1205:0:99:1 //Set instrument digit 3: NUMERO 3 (KeyDown)
+4:1205:0:51:1 //Set instrument digit 3: 3 (KeyDown)
+4:1206:0:100:1 //Set instrument digit 4: NUMERO 4 (KeyDown)
+4:1206:0:52:1 //Set instrument digit 4: 4 (KeyDown)
+4:1207:0:101:1 //Set instrument digit 5: NUMERO 5 (KeyDown)
+4:1207:0:53:1 //Set instrument digit 5: 5 (KeyDown)
+4:1208:0:102:1 //Set instrument digit 6: NUMERO 6 (KeyDown)
+4:1208:0:54:1 //Set instrument digit 6: 6 (KeyDown)
+4:1209:0:103:1 //Set instrument digit 7: NUMERO 7 (KeyDown)
+4:1209:0:55:1 //Set instrument digit 7: 7 (KeyDown)
+4:1210:0:104:1 //Set instrument digit 8: NUMERO 8 (KeyDown)
+4:1210:0:56:1 //Set instrument digit 8: 8 (KeyDown)
+4:1211:0:105:1 //Set instrument digit 9: NUMERO 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: NUMERO 0 (KeyDown)
+5:1223:0:49:1 //Set volume digit 1: 1 (KeyDown)
+5:1223:0:97:1 //Set volume digit 1: NUMERO 1 (KeyDown)
+5:1224:0:50:1 //Set volume digit 2: 2 (KeyDown)
+5:1224:0:98:1 //Set volume digit 2: NUMERO 2 (KeyDown)
+5:1225:0:51:1 //Set volume digit 3: 3 (KeyDown)
+5:1225:0:99:1 //Set volume digit 3: NUMERO 3 (KeyDown)
+5:1226:0:52:1 //Set volume digit 4: 4 (KeyDown)
+5:1226:0:100:1 //Set volume digit 4: NUMERO 4 (KeyDown)
+5:1227:0:53:1 //Set volume digit 5: 5 (KeyDown)
+5:1227:0:101:1 //Set volume digit 5: NUMERO 5 (KeyDown)
+5:1228:0:54:1 //Set volume digit 6: 6 (KeyDown)
+5:1228:0:102:1 //Set volume digit 6: NUMERO 6 (KeyDown)
+5:1229:0:55:1 //Set volume digit 7: 7 (KeyDown)
+5:1229:0:103:1 //Set volume digit 7: NUMERO 7 (KeyDown)
+5:1230:0:56:1 //Set volume digit 8: 8 (KeyDown)
+5:1230:0:104:1 //Set volume digit 8: NUMERO 8 (KeyDown)
+5:1231:0:57:1 //Set volume digit 9: 9 (KeyDown)
+5:1231:0:105:1 //Set volume digit 9: NUMERO 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:1246:0:79:1 //Vol command - Offset: O (KeyDown)
+
+//----( Pattern Context [bottom] - FX Col (6) )------------
+6:1294:0:226:1 //FX midi macro slide: < (KeyDown)
+6:1295:1:192:1 //FX combined note delay and note cut: Shift+\xF1 (KeyDown)
+6:1295:0:186:1 //FX combined note delay and note cut: AGUDO (KeyDown)
+6:1666:0:189:1 //FX parameter extension command: - (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: NUMERO 0 (KeyDown)
+7:1248:0:49:1 //FX Param digit 1: 1 (KeyDown)
+7:1248:0:97:1 //FX Param digit 1: NUMERO 1 (KeyDown)
+7:1249:0:50:1 //FX Param digit 2: 2 (KeyDown)
+7:1249:0:98:1 //FX Param digit 2: NUMERO 2 (KeyDown)
+7:1250:0:51:1 //FX Param digit 3: 3 (KeyDown)
+7:1250:0:99:1 //FX Param digit 3: NUMERO 3 (KeyDown)
+7:1251:0:52:1 //FX Param digit 4: 4 (KeyDown)
+7:1251:0:100:1 //FX Param digit 4: NUMERO 4 (KeyDown)
+7:1252:0:53:1 //FX Param digit 5: 5 (KeyDown)
+7:1252:0:101:1 //FX Param digit 5: NUMERO 5 (KeyDown)
+7:1253:0:54:1 //FX Param digit 6: 6 (KeyDown)
+7:1253:0:102:1 //FX Param digit 6: NUMERO 6 (KeyDown)
+7:1254:0:55:1 //FX Param digit 7: 7 (KeyDown)
+7:1254:0:103:1 //FX Param digit 7: NUMERO 7 (KeyDown)
+7:1255:0:56:1 //FX Param digit 8: 8 (KeyDown)
+7:1255:0:104:1 //FX Param digit 8: NUMERO 8 (KeyDown)
+7:1256:0:57:1 //FX Param digit 9: 9 (KeyDown)
+7:1256:0:105:1 //FX Param digit 9: NUMERO 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: RETROCESO (KeyDown)
+8:1384:1:78:1 //Normalise Sample: Shift+N (KeyDown)
+8:1385:3:65:1 //Amplify Sample: Shift+Ctrl+A (KeyDown)
+8:1385:2:77:1 //Amplify Sample: Ctrl+M (KeyDown)
+8:1381:3:82:1 //Reverse sample: Shift+Ctrl+R (KeyDown)
+8:1382:0:46:1 //Delete sample selection: SUPR (KeyDown)
+8:1386:0:107:1 //Zoom Out: TECLA DE ADICION (KeyDown)
+8:1387:0:109:1 //Zoom In: TECLA DE SUSTRACCION (KeyDown)
+8:1784:2:73:1 //Invert sample phase: Ctrl+I (KeyDown)
+8:1785:2:85:1 //Signed/Unsigned conversion: Ctrl+U (KeyDown)
+8:1790:2:69:1 //Remove DC Offset: Ctrl+E (KeyDown)
+8:1856:2:68:1 //Quick fade: Ctrl+D (KeyDown)
+8:1857:2:76:1 //Crossfade sample loop: Ctrl+L (KeyDown)
+
+//----( Instrument Context [bottom] (9) )------------
+9:1837:0:107:5 //Zoom In: TECLA DE ADICION (KeyDown|KeyHold)
+9:1838:0:109:5 //Zoom Out: TECLA DE SUSTRACCION (KeyDown|KeyHold)
+9:1825:1:9:5 //Select previous envelope point: Shift+TABULACION (KeyDown|KeyHold)
+9:1826:0:9:5 //Select next envelope point: TABULACION (KeyDown|KeyHold)
+9:1821:0:37:5 //Move envelope point left: FLECHA IZQUIERDA (KeyDown|KeyHold)
+9:1822:0:39:5 //Move envelope point right: FLECHA DERECHA (KeyDown|KeyHold)
+9:1823:0:38:5 //Move envelope point up: FLECHA ARRIBA (KeyDown|KeyHold)
+9:1834:0:33:5 //Move envelope point up (big step): RE PAG (KeyDown|KeyHold)
+9:1824:0:40:5 //Move envelope point down: FLECHA ABAJO (KeyDown|KeyHold)
+9:1835:0:34:5 //Move envelope point down (big step): AV PAG (KeyDown|KeyHold)
+9:1827:0:45:1 //Insert envelope point: INSERT (KeyDown)
+9:1828:0:46:1 //Remove envelope point: SUPR (KeyDown)
+9:1828:0:8:1 //Remove envelope point: RETROCESO (KeyDown)
+9:1829:0:36:1 //Set loop start: INICIO (KeyDown)
+9:1830:0:35:1 //Set loop end: FIN (KeyDown)
+9:1831:2:36:1 //Set sustain loop start: Ctrl+INICIO (KeyDown)
+9:1832:2:35:1 //Set sustain loop end: Ctrl+FIN (KeyDown)
+9:1833:2:82:1 //Toggle release node: Ctrl+R (KeyDown)
+
+//----( Comments Context [bottom] (10) )------------
+
+//----( Unknown Context (11) )------------
+
+//----( Unknown Context (12) )------------
+
+//----( Plugin GUI Context (13) )------------
+13:1763:0:109:5 //Previous plugin preset: TECLA DE SUSTRACCION (KeyDown|KeyHold)
+13:1764:0:107:5 //Next plugin preset: TECLA DE ADICION (KeyDown|KeyHold)
+13:1782:2:109:5 //Plugin preset backward jump: Ctrl+TECLA DE SUSTRACCION (KeyDown|KeyHold)
+13:1783:2:107:5 //Plugin preset forward jump: Ctrl+TECLA DE ADICION (KeyDown|KeyHold)
+13:1765:3:68:1 //Randomize plugin parameters: Shift+Ctrl+D (KeyDown)
+13:1839:2:82:1 //Toggle parameter recording: Ctrl+R (KeyDown)
+13:1840:2:75:1 //Pass key presses to plugin: Ctrl+K (KeyDown)
+13:1841:2:66:1 //Bypass plugin: Ctrl+B (KeyDown)
+
+//----( General Context [top] (14) )------------
+
+//----( Pattern Context [top] (15) )------------
+
+//----( Sample Context [top] (16) )------------
+
+//----( Instrument Context [top] (17) )------------
+17:1851:2:68:1 //Duplicate instrument: Ctrl+D (KeyDown)
+17:1850:3:69:1 //Edit sample map: Shift+Ctrl+E (KeyDown)
+17:1849:2:69:1 //Edit current sample: Ctrl+E (KeyDown)
+17:1846:3:77:1 //Map all notes to selected note: Shift+Ctrl+M (KeyDown)
+17:1847:2:77:1 //Map all notes to selected sample: Ctrl+M (KeyDown)
+17:1848:2:82:1 //Reset note mapping: Ctrl+R (KeyDown)
+17:1843:2:81:1 //Transpose +1 (note map): Ctrl+Q (KeyDown)
+17:1842:2:65:1 //Transpose -1 (note map): Ctrl+A (KeyDown)
+17:1845:3:81:1 //Transpose +12 (note map): Shift+Ctrl+Q (KeyDown)
+17:1844:3:65:1 //Transpose -12 (note map): Shift+Ctrl+A (KeyDown)
+
+//----( Comments Context [top] (18) )------------
+
+//----( Orderlist (19) )------------
+19:1802:0:46:5 //Delete Order: SUPR (KeyDown|KeyHold)
+19:1803:0:45:5 //Insert Order: INSERT (KeyDown|KeyHold)
+19:1804:0:13:5 //Edit Pattern: ENTRAR (KeyDown|KeyHold)
+19:1805:0:9:5 //Switch to pattern editor: TABULACION (KeyDown|KeyHold)
+19:1794:0:37:5 //Previous Order: FLECHA IZQUIERDA (KeyDown|KeyHold)
+19:1794:0:38:5 //Previous Order: FLECHA ARRIBA (KeyDown|KeyHold)
+19:1795:0:39:5 //Next Order: FLECHA DERECHA (KeyDown|KeyHold)
+19:1795:0:40:5 //Next Order: FLECHA ABAJO (KeyDown|KeyHold)
+19:1796:0:36:5 //First Order: INICIO (KeyDown|KeyHold)
+19:1797:0:35:5 //Last Order: FIN (KeyDown|KeyHold)
+19:1807:0:48:5 //Pattern index digit 0: 0 (KeyDown|KeyHold)
+19:1807:0:96:5 //Pattern index digit 0: NUMERO 0 (KeyDown|KeyHold)
+19:1808:0:49:5 //Pattern index digit 1: 1 (KeyDown|KeyHold)
+19:1808:0:97:5 //Pattern index digit 1: NUMERO 1 (KeyDown|KeyHold)
+19:1809:0:50:5 //Pattern index digit 2: 2 (KeyDown|KeyHold)
+19:1809:0:98:5 //Pattern index digit 2: NUMERO 2 (KeyDown|KeyHold)
+19:1810:0:51:5 //Pattern index digit 3: 3 (KeyDown|KeyHold)
+19:1810:0:99:5 //Pattern index digit 3: NUMERO 3 (KeyDown|KeyHold)
+19:1811:0:52:5 //Pattern index digit 4: 4 (KeyDown|KeyHold)
+19:1811:0:100:5 //Pattern index digit 4: NUMERO 4 (KeyDown|KeyHold)
+19:1812:0:53:5 //Pattern index digit 5: 5 (KeyDown|KeyHold)
+19:1812:0:101:5 //Pattern index digit 5: NUMERO 5 (KeyDown|KeyHold)
+19:1813:0:54:5 //Pattern index digit 6: 6 (KeyDown|KeyHold)
+19:1813:0:102:5 //Pattern index digit 6: NUMERO 6 (KeyDown|KeyHold)
+19:1814:0:55:5 //Pattern index digit 7: 7 (KeyDown|KeyHold)
+19:1814:0:103:5 //Pattern index digit 7: NUMERO 7 (KeyDown|KeyHold)
+19:1815:0:56:5 //Pattern index digit 8: 8 (KeyDown|KeyHold)
+19:1815:0:104:5 //Pattern index digit 8: NUMERO 8 (KeyDown|KeyHold)
+19:1816:0:57:5 //Pattern index digit 9: 9 (KeyDown|KeyHold)
+19:1816:0:105:5 //Pattern index digit 9: NUMERO 9 (KeyDown|KeyHold)
+19:1817:0:107:5 //Increase pattern index : TECLA DE ADICION (KeyDown|KeyHold)
+19:1817:0:187:5 //Increase pattern index : + (KeyDown|KeyHold)
+19:1818:0:109:5 //Decrease pattern index: TECLA DE SUSTRACCION (KeyDown|KeyHold)
+19:1818:0:189:5 //Decrease pattern index: - (KeyDown|KeyHold)
Added: trunk/OpenMPT/packageTemplate/extraKeymaps/es-LA_mpt_jmkz.mkb
===================================================================
--- trunk/OpenMPT/packageTemplate/extraKeymaps/es-LA_mpt_jmkz.mkb (rev 0)
+++ trunk/OpenMPT/packageTemplate/extraKeymaps/es-LA_mpt_jmkz.mkb 2011-04-01 14:59:06 UTC (rev 834)
@@ -0,0 +1,377 @@
+//-------- OpenMPT key binding definition file -------
+//-Format is: -
+//- Context:Command ID:Modifiers:Key:KeypressEventType //Comments -
+//----------------------------------------------------------------------
+version:1
+
+//----( 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:1350:3:83:1 //File/Save As: Shift+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:1 //Play pattern from start: F7 (KeyDown)
+0:1026:2:118:1 //Play pattern from cursor: Ctrl+F7 (KeyDown)
+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:1362:2:86:1 //Paste: Ctrl+V (KeyDown)
+0:1362:1:45:1 //Paste: Shift+INSERT (KeyDown)
+0:1363:3:86:1 //Mix Paste: Shift+Ctrl+V (KeyDown)
+0:1793:1:86:5 //Paste Flood: Shift+V (KeyDown|KeyHold)
+0:1820:6:86:1 //Push Forward Paste: Ctrl+Alt+V (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:1025:4:67:1 //View Comments: Alt+C (KeyDown)
+0:1368:2:113:1 //Toggle Tree View: Ctrl+F2 (KeyDown)
+0:1369:2:112:1 //View Options: Ctrl+F1 (KeyDown)
+0:1781:2:114:1 //View MIDI mapping: Ctrl+F3 (KeyDown)
+0:1370:0:112:1 //Help (to do): F1 (KeyDown)
+0:1032:2:111:5 //Previous instrument: Ctrl+TECLA DE DIVISION (KeyDown|KeyHold)
+0:1032:2:38:5 //Previous instrument: Ctrl+FLECHA ARRIBA (KeyDown|KeyHold)
+0:1033:2:106:5 //Next instrument: Ctrl+TECLA DE MULTIPLICACION (KeyDown|KeyHold)
+0:1033:2:40:5 //Next instrument: Ctrl+FLECHA ABAJO (KeyDown|KeyHold)
+0:1036:0:111:1 //Previous octave: TECLA DE DIVISION (KeyDown)
+0:1037:0:106:1 //Next octave: TECLA DE MULTIPLICACION (KeyDown)
+0:1034:2:37:5 //Previous order: Ctrl+FLECHA IZQUIERDA (KeyDown|KeyHold)
+0:1035:2:39:5 //Next order: Ctrl+FLECHA DERECHA (KeyDown|KeyHold)
+
+//----( General Context [bottom] (1) )------------
+
+//----( Pattern Context [bottom] (2) )------------
+2:1017:0:34:5 //Jump down by measure: AV PAG (KeyDown|KeyHold)
+2:1018:0:33:5 //Jump up by measure: RE PAG (KeyDown|KeyHold)
+2:1338:4:34:5 //Jump down by beat: Alt+AV PAG (KeyDown|KeyHold)
+2:1339:4:33:5 //Jump up by beat: Alt+RE PAG (KeyDown|KeyHold)
+2:1340:6:34:5 //Snap down to beat: Ctrl+Alt+AV PAG (KeyDown|KeyHold)
+2:1341:6:33:5 //Snap up to beat: Ctrl+Alt+RE PAG (KeyDown|KeyHold)
+2:1038:0:40:5 //Navigate down by 1 row: FLECHA ABAJO (KeyDown|KeyHold)
+2:1039:0:38:5 //Navigate up by 1 row: FLECHA ARRIBA (KeyDown|KeyHold)
+2:1691:4:40:5 //Navigate down by spacing: Alt+FLECHA ABAJO (KeyDown|KeyHold)
+2:1692:4:38:5 //Navigate up by spacing: Alt+FLECHA ARRIBA (KeyDown|KeyHold)
+2:1040:0:37:5 //Navigate left: FLECHA IZQUIERDA (KeyDown|KeyHold)
+2:1041:0:39:5 //Navigate right: FLECHA DERECHA (KeyDown|KeyHold)
+2:1042:0:9:5 //Navigate to next channel: TABULACION (KeyDown|KeyHold)
+2:1043:1:9:5 //Navigate to previous channel: Shift+TABULACION (KeyDown|KeyHold)
+2:1044:0:36:1 //Go to first channel: INICIO (KeyDown)
+2:1045:2:36:1 //Go to first row: Ctrl+INICIO (KeyDown)
+2:1046:6:36:1 //Go to first row of first channel: Ctrl+Alt+INICIO (KeyDown)
+2:1047:0:35:1 //Go to last channel: FIN (KeyDown)
+2:1048:2:35:1 //Go to last row: Ctrl+FIN (KeyDown)
+2:1049:6:35:1 //Go to last row of last channel: Ctrl+Alt+FIN (KeyDown)
+2:1050:1:16:1 //Selection key: Shift+MAYUSCULAS (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:1 //Quick copy: ENTRAR (KeyDown)
+2:1004:0:32:5 //Quick paste: BARRA ESPACIADORA (KeyDown|KeyHold)
+2:1001:2:32:1 //Enable recording: Ctrl+BARRA ESPACIADORA (KeyDown)
+2:1002:2:13:5 //Play row: Ctrl+ENTRAR (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+TABULACION (KeyDown)
+2:1806:2:68:1 //Duplicate pattern: Ctrl+D (KeyDown)
+2:1836:2:191:1 //Edit plugin assigned to PC note: Ctrl+} (KeyDown)
+2:1662:6:80:1 //Toggle channel's plugin editor: Ctrl+Alt+P (KeyDown)
+2:1062:0:93:1 //Show note properties: APLICACI\xD3N (KeyDown)
+2:1772:5:80:1 //Show pattern properties window: Shift+Alt+P (KeyDown)
+2:1819:2:69:1 //Split Keyboard Settings dialog: Ctrl+E (KeyDown)
+2:1776:1:122:1 //Toggle loop pattern: Shift+F11 (KeyDown)
+2:1780:2:84:1 //Show playback time at current row: Ctrl+T (KeyDown)
+2:1005:0:121:1 //Mute current channel: F10 (KeyDown)
+2:1006:2:121:1 //Solo current channel: Ctrl+F10 (KeyDown)
+2:1771:6:121:1 //Unmute all channels: Ctrl+Alt+F10 (KeyDown)
+2:1786:2:82:1 //Reset channel: Ctrl+R (KeyDown)
+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: SUPR (KeyDown)
+2:1664:1:190:1 //Clear field (IT Style): Shift+. (KeyDown)
+2:1059:2:46:5 //Clear row and step: Ctrl+SUPR (KeyDown|KeyHold)
+2:1665:1:46:5 //Clear field and step (IT Style): Shift+SUPR (KeyDown|KeyHold)
+2:1061:0:8:5 //Delete rows: RETROCESO (KeyDown|KeyHold)
+2:1377:2:8:5 //Delete all rows: Ctrl+RETROCESO (KeyDown|KeyHold)
+2:1378:0:45:5 //Insert Row: INSERT (KeyDown|KeyHold)
+2:1379:2:45:5 //Insert All Rows: Ctrl+INSERT (KeyDown|KeyHold)
+2:1055:0:109:5 //Previous pattern: TECLA DE SUSTRACCION (KeyDown|KeyHold)
+2:1054:0:107:5 //Next pattern: TECLA DE ADICION (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 A: P (KeyDown)
+3:1074:0:186:1 //Base octave A#: AGUDO (KeyDown)
+3:1075:0:187:1 //Base octave 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:192:1 //Base octave +1 A: \xF1 (KeyDown)
+3:1086:0:222:1 //Base octave +1 A#: { (KeyDown)
+3:1087:0:191:1 //Base octave +1 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:189:1 //Base octave +2 A: - (KeyDown)
+3:1212:0:48:1 //Set octave 0: 0 (KeyDown)
+3:1212:0:96:1 //Set octave 0: NUMERO 0 (KeyDown)
+3:1213:0:49:1 //Set octave 1: 1 (KeyDown)
+3:1213:0:97:1 //Set octave 1: NUMERO 1 (KeyDown)
+3:1214:0:50:1 //Set octave 2: 2 (KeyDown)
+3:1214:0:98:1 //Set octave 2: NUMERO 2 (KeyDown)
+3:1215:0:51:1 //Set octave 3: 3 (KeyDown)
+3:1215:0:99:1 //Set octave 3: NUMERO 3 (KeyDown)
+3:1216:0:52:1 //Set octave 4: 4 (KeyDown)
+3:1216:0:100:1 //Set octave 4: NUMERO 4 (KeyDown)
+3:1217:0:53:1 //Set octave 5: 5 (KeyDown)
+3:1217:0:101:1 //Set octave 5: NUMERO 5 (KeyDown)
+3:1218:0:54:1 //Set octave 6: 6 (KeyDown)
+3:1218:0:102:1 //Set octave 6: NUMERO 6 (KeyDown)
+3:1219:0:55:1 //Set octave 7: 7 (KeyDown)
+3:1219:0:103:1 //Set octave 7: NUMERO 7 (KeyDown)
+3:1220:0:56:1 //Set octave 8: 8 (KeyDown)
+3:1220:0:104:1 //Set octave 8: NUMERO 8 (KeyDown)
+3:1221:0:57:1 //Set octave 9: 9 (KeyDown)
+3:1221:0:105:1 //Set octave 9: NUMERO 9 (KeyDown)
+3:1316:1:16:1 //Chord Modifier: Shift+MAYUSCULAS (KeyDown)
+3:1200:0:220:1 //Note Cut: | (KeyDown)
+3:1201:0:221:1 //Note Off: \xBF (KeyDown)
+3:1791:1:221:1 //Note Fade: Shift+\xBF (KeyDown)
+3:1788:1:219:1 //Parameter control(MPTm only): Shift+' (KeyDown)
+3:1789:0:219:1 //Parameter control(smooth)(MPTm only): ' (KeyDown)
+
+//----( Pattern Context [bottom] - Ins Col (4) )------------
+4:1202:0:96:1 //Set instrument digit 0: NUMERO 0 (KeyDown)
+4:1202:0:48:1 //Set instrument digit 0: 0 (KeyDown)
+4:1203:0:97:1 //Set instrument digit 1: NUMERO 1 (KeyDown)
+4:1203:0:49:1 //Set instrument digit 1: 1 (KeyDown)
+4:1204:0:98:1 //Set instrument digit 2: NUMERO 2 (KeyDown)
+4:1204:0:50:1 //Set instrument digit 2: 2 (KeyDown)
+4:1205:0:99:1 //Set instrument digit 3: NUMERO 3 (KeyDown)
+4:1205:0:51:1 //Set instrument digit 3: 3 (KeyDown)
+4:1206:0:100:1 //Set instrument digit 4: NUMERO 4 (KeyDown)
+4:1206:0:52:1 //Set instrument digit 4: 4 (KeyDown)
+4:1207:0:101:1 //Set instrument digit 5: NUMERO 5 (KeyDown)
+4:1207:0:53:1 //Set instrument digit 5: 5 (KeyDown)
+4:1208:0:102:1 //Set instrument digit 6: NUMERO 6 (KeyDown)
+4:1208:0:54:1 //Set instrument digit 6: 6 (KeyDown)
+4:1209:0:103:1 //Set instrument digit 7: NUMERO 7 (KeyDown)
+4:1209:0:55:1 //Set instrument digit 7: 7 (KeyDown)
+4:1210:0:104:1 //Set instrument digit 8: NUMERO 8 (KeyDown)
+4:1210:0:56:1 //Set instrument digit 8: 8 (KeyDown)
+4:1211:0:105:1 //Set instrument digit 9: NUMERO 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: NUMERO 0 (KeyDown)
+5:1223:0:49:1 //Set volume digit 1: 1 (KeyDown)
+5:1223:0:97:1 //Set volume digit 1: NUMERO 1 (KeyDown)
+5:1224:0:50:1 //Set volume digit 2: 2 (KeyDown)
+5:1224:0:98:1 //Set volume digit 2: NUMERO 2 (KeyDown)
+5:1225:0:51:1 //Set volume digit 3: 3 (KeyDown)
+5:1225:0:99:1 //Set volume digit 3: NUMERO 3 (KeyDown)
+5:1226:0:52:1 //Set volume digit 4: 4 (KeyDown)
+5:1226:0:100:1 //Set volume digit 4: NUMERO 4 (KeyDown)
+5:1227:0:53:1 //Set volume digit 5: 5 (KeyDown)
+5:1227:0:101:1 //Set volume digit 5: NUMERO 5 (KeyDown)
+5:1228:0:54:1 //Set volume digit 6: 6 (KeyDown)
+5:1228:0:102:1 //Set volume digit 6: NUMERO 6 (KeyDown)
+5:1229:0:55:1 //Set volume digit 7: 7 (KeyDown)
+5:1229:0:103:1 //Set volume digit 7: NUMERO 7 (KeyDown)
+5:1230:0:56:1 //Set volume digit 8: 8 (KeyDown)
+5:1230:0:104:1 //Set volume digit 8: NUMERO 8 (KeyDown)
+5:1231:0:57:1 //Set volume digit 9: 9 (KeyDown)
+5:1231:0:105:1 //Set volume digit 9: NUMERO 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:1246:0:79:1 //Vol command - Offset: O (KeyDown)
+
+//----( Pattern Context [bottom] - FX Col (6) )------------
+6:1294:0:226:1 //FX midi macro slide: < (KeyDown)
+6:1295:1:192:1 //FX combined note delay and note cut: Shift+\xF1 (KeyDown)
+6:1295:0:186:1 //FX combined note delay and note cut: AGUDO (KeyDown)
+6:1666:0:189:1 //FX parameter extension command: - (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: NUMERO 0 (KeyDown)
+7:1248:0:49:1 //FX Param digit 1: 1 (KeyDown)
+7:1248:0:97:1 //FX Param digit 1: NUMERO 1 (KeyDown)
+7:1249:0:50:1 //FX Param digit 2: 2 (KeyDown)
+7:1249:0:98:1 //FX Param digit 2: NUMERO 2 (KeyDown)
+7:1250:0:51:1 //FX Param digit 3: 3 (KeyDown)
+7:1250:0:99:1 //FX Param digit 3: NUMERO 3 (KeyDown)
+7:1251:0:52:1 //FX Param digit 4: 4 (KeyDown)
+7:1251:0:100:1 //FX Param digit 4: NUMERO 4 (KeyDown)
+7:1252:0:53:1 //FX Param digit 5: 5 (KeyDown)
+7:1252:0:101:1 //FX Param digit 5: NUMERO 5 (KeyDown)
+7:1253:0:54:1 //FX Param digit 6: 6 (KeyDown)
+7:1253:0:102:1 //FX Param digit 6: NUMERO 6 (KeyDown)
+7:1254:0:55:1 //FX Param digit 7: 7 (KeyDown)
+7:1254:0:103:1 //FX Param digit 7: NUMERO 7 (KeyDown)
+7:1255:0:56:1 //FX Param digit 8: 8 (KeyDown)
+7:1255:0:104:1 //FX Param digit 8: NUMERO 8 (KeyDown)
+7:1256:0:57:1 //FX Param digit 9: 9 (KeyDown)
+7:1256:0:105:1 //FX Param digit 9: NUMERO 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: RETROCESO (KeyDown)
+8:1384:1:78:1 //Normalise Sample: Shift+N (KeyDown)
+8:1385:3:65:1 //Amplify Sample: Shift+Ctrl+A (KeyDown)
+8:1385:2:77:1 //Amplify Sample: Ctrl+M (KeyDown)
+8:1381:3:82:1 //Reverse sample: Shift+Ctrl+R (KeyDown)
+8:1382:0:46:1 //Delete sample selection: SUPR (KeyDown)
+8:1386:0:107:1 //Zoom Out: TECLA DE ADICION (KeyDown)
+8:1387:0:109:1 //Zoom In: TECLA DE SUSTRACCION (KeyDown)
+8:1784:2:73:1 //Invert sample phase: Ctrl+I (KeyDown)
+8:1785:2:85:1 //Signed/Unsigned conversion: Ctrl+U (KeyDown)
+8:1790:2:69:1 //Remove DC Offset: Ctrl+E (KeyDown)
+8:1856:2:68:1 //Quick fade: Ctrl+D (KeyDown)
+8:1857:2:76:1 //Crossfade sample loop: Ctrl+L (KeyDown)
+
+//----( Instrument Context [bottom] (9) )------------
+9:1837:0:107:5 //Zoom In: TECLA DE ADICION (KeyDown|KeyHold)
+9:1838:0:109:5 //Zoom Out: TECLA DE SUSTRACCION (KeyDown|KeyHold)
+9:1825:1:9:5 //Select previous envelope point: Shift+TABULACION (KeyDown|KeyHold)
+9:1826:0:9:5 //Select next envelope point: TABULACION (KeyDown|KeyHold)
+9:1821:0:37:5 //Move envelope point left: FLECHA IZQUIERDA (KeyDown|KeyHold)
+9:1822:0:39:5 //Move envelope point right: FLECHA DERECHA (KeyDown|KeyHold)
+9:1823:0:38:5 //Move envelope point up: FLECHA ARRIBA (KeyDown|KeyHold)
+9:1834:0:33:5 //Move envelope point up (big step): RE PAG (KeyDown|KeyHold)
+9:1824:0:40:5 //Move envelope point down: FLECHA ABAJO (KeyDown|KeyHold)
+9:1835:0:34:5 //Move envelope point down (big step): AV PAG (KeyDown|KeyHold)
+9:1827:0:45:1 //Insert envelope point: INSERT (KeyDown)
+9:1828:0:46:1 //Remove envelope point: SUPR (KeyDown)
+9:1828:0:8:1 //Remove envelope point: RETROCESO (KeyDown)
+9:1829:0:36:1 //Set loop start: INICIO (KeyDown)
+9:1830:0:35:1 //Set loop end: FIN (KeyDown)
+9:1831:2:36:1 //Set sustain loop start: Ctrl+INICIO (KeyDown)
+9:1832:2:35:1 //Set sustain loop end: Ctrl+FIN (KeyDown)
+9:1833:2:82:1 //Toggle release node: Ctrl+R (KeyDown)
+
+//----( Comments Context [bottom] (10) )------------
+
+//----( Unknown Context (11) )------------
+
+//----( Unknown Context (12) )------------
+
+//----( Plugin GUI Context (13) )------------
+13:1763:0:109:5 //Previous plugin preset: TECLA DE SUSTRACCION (KeyDown|KeyHold)
+13:1764:0:107:5 //Next plugin preset: TECLA DE ADICION (KeyDown|KeyHold)
+13:1782:2:109:5 //Plugin preset backward jump: Ctrl+TECLA DE SUSTRACCION (KeyDown|KeyHold)
+13:1783:2:107:5 //Plugin preset forward jump: Ctrl+TECLA DE ADICION (KeyDown|KeyHold)
+13:1765:3:68:1 //Randomize plugin parameters: Shift+Ctrl+D (KeyDown)
+13:1839:2:82:1 //Toggle parameter recording: Ctrl+R (KeyDown)
+13:1840:2:75:1 //Pass key presses to plugin: Ctrl+K (KeyDown)
+13:1841:2:66:1 //Bypass plugin: Ctrl+B (KeyDown)
+
+//----( General Context [top] (14) )------------
+
+//----( Pattern Context [top] (15) )------------
+
+//----( Sample Context [top] (16) )------------
+
+//----( Instrument Context [top] (17) )------------
+17:1851:2:68:1 //Duplicate instrument: Ctrl+D (KeyDown)
+17:1850:3:69:1 //Edit sample map: Shift+Ctrl+E (KeyDown)
+17:1849:2:69:1 //Edit current sample: Ctrl+E (KeyDown)
+17:1846:3:77:1 //Map all notes to selected note: Shift+Ctrl+M (KeyDown)
+17:1847:2:77:1 //Map all notes to selected sample: Ctrl+M (KeyDown)
+17:1848:2:82:1 //Reset note mapping: Ctrl+R (KeyDown)
+17:1843:2:81:1 //Transpose +1 (note map): Ctrl+Q (KeyDown)
+17:1842:2:65:1 //Transpose -1 (note map): Ctrl+A (KeyDown)
+17:1845:3:81:1 //Transpose +12 (note map): Shift+Ctrl+Q (KeyDown)
+17:1844:3:65:1 //Transpose -12 (note map): Shift+Ctrl+A (KeyDown)
+
+//----( Comments Context [top] (18) )------------
+
+//----( Orderlist (19) )------------
+19:1802:0:46:5 //Delete Order: SUPR (KeyDown|KeyHold)
+19:1803:0:45:5 //Insert Order: INSERT (KeyDown|KeyHold)
+19:1804:0:13:5 //Edit Pattern: ENTRAR (KeyDown|KeyHold)
+19:1805:0:9:5 //Switch to pattern editor: TABULACION (KeyDown|KeyHold)
+19:1794:0:37:5 //Previous Order: FLECHA IZQUIERDA (KeyDown|KeyHold)
+19:1794:0:38:5 //Previous Order: FLECHA ARRIBA (KeyDown|KeyHold)
+19:1795:0:39:5 //Next Order: FLECHA DERECHA (KeyDown|KeyHold)
+19:1795:0:40:5 //Next Order: FLECHA ABAJO (KeyDown|KeyHold)
+19:1796:0:36:5 //First Order: INICIO (KeyDown|KeyHold)
+19:1797:0:35:5 //Last Order: FIN (KeyDown|KeyHold)
+19:1807:0:48:5 //Pattern index digit 0: 0 (KeyDown|KeyHold)
+19:1807:0:96:5 //Pattern index digit 0: NUMERO 0 (KeyDown|KeyHold)
+19:1808:0:49:5 //Pattern index digit 1: 1 (KeyDown|KeyHold)
+19:1808:0:97:5 //Pattern index digit 1: NUMERO 1 (KeyDown|KeyHold)
+19:1809:0:50:5 //Pattern index digit 2: 2 (KeyDown|KeyHold)
+19:1809:0:98:5 //Pattern index digit 2: NUMERO 2 (KeyDown|KeyHold)
+19:1810:0:51:5 //Pattern index digit 3: 3 (KeyDown|KeyHold)
+19:1810:0:99:5 //Pattern index digit 3: NUMERO 3 (KeyDown|KeyHold)
+19:1811:0:52:5 //Pattern index digit 4: 4 (KeyDown|KeyHold)
+19:1811:0:100:5 //Pattern index digit 4: NUMERO 4 (KeyDown|KeyHold)
+19:1812:0:53:5 //Pattern index digit 5: 5 (KeyDown|KeyHold)
+19:1812:0:101:5 //Pattern index digit 5: NUMERO 5 (KeyDown|KeyHold)
+19:1813:0:54:5 //Pattern index digit 6: 6 (KeyDown|KeyHold)
+19:1813:0:102:5 //Pattern index digit 6: NUMERO 6 (KeyDown|KeyHold)
+19:1814:0:55:5 //Pattern index digit 7: 7 (KeyDown|KeyHold)
+19:1814:0:103:5 //Pattern index digit 7: NUMERO 7 (KeyDown|KeyHold)
+19:1815:0:56:5 //Pattern index digit 8: 8 (KeyDown|KeyHold)
+19:1815:0:104:5 //Pattern index digit 8: NUMERO 8 (KeyDown|KeyHold)
+19:1816:0:57:5 //Pattern index digit 9: 9 (KeyDown|KeyHold)
+19:1816:0:105:5 //Pattern index digit 9: NUMERO 9 (KeyDown|KeyHold)
+19:1817:0:107:5 //Increas...
[truncated message content] |
|
From: <sag...@us...> - 2011-03-27 12:42:05
|
Revision: 833
http://modplug.svn.sourceforge.net/modplug/?rev=833&view=rev
Author: saga-games
Date: 2011-03-27 12:41:58 +0000 (Sun, 27 Mar 2011)
Log Message:
-----------
[Mod] Updated release notes, History.txt, removed example songs
Modified Paths:
--------------
trunk/OpenMPT/packageTemplate/History.txt
trunk/OpenMPT/packageTemplate/OMPT_1.19_ReleaseNotes.html
Removed Paths:
-------------
trunk/OpenMPT/packageTemplate/ExampleSongs/coda - control.it
trunk/OpenMPT/packageTemplate/ExampleSongs/coda - doilies.it
trunk/OpenMPT/packageTemplate/ExampleSongs/coda - silver gardener.it
trunk/OpenMPT/packageTemplate/ExampleSongs/lsnk - meander.it
trunk/OpenMPT/packageTemplate/ExampleSongs/nobuyuki - enlilsong1.it
trunk/OpenMPT/packageTemplate/ExampleSongs/smh - on the moon.it
trunk/OpenMPT/packageTemplate/ExampleSongs/xaimus - digital sentience.it
trunk/OpenMPT/packageTemplate/ExampleSongs/xaimus - drunk in toronto.it
Deleted: trunk/OpenMPT/packageTemplate/ExampleSongs/coda - control.it
===================================================================
(Binary files differ)
Deleted: trunk/OpenMPT/packageTemplate/ExampleSongs/coda - doilies.it
===================================================================
(Binary files differ)
Deleted: trunk/OpenMPT/packageTemplate/ExampleSongs/coda - silver gardener.it
===================================================================
(Binary files differ)
Deleted: trunk/OpenMPT/packageTemplate/ExampleSongs/lsnk - meander.it
===================================================================
(Binary files differ)
Deleted: trunk/OpenMPT/packageTemplate/ExampleSongs/nobuyuki - enlilsong1.it
===================================================================
(Binary files differ)
Deleted: trunk/OpenMPT/packageTemplate/ExampleSongs/smh - on the moon.it
===================================================================
(Binary files differ)
Deleted: trunk/OpenMPT/packageTemplate/ExampleSongs/xaimus - digital sentience.it
===================================================================
(Binary files differ)
Deleted: trunk/OpenMPT/packageTemplate/ExampleSongs/xaimus - drunk in toronto.it
===================================================================
(Binary files differ)
Modified: trunk/OpenMPT/packageTemplate/History.txt
===================================================================
--- trunk/OpenMPT/packageTemplate/History.txt 2011-03-26 17:57:33 UTC (rev 832)
+++ trunk/OpenMPT/packageTemplate/History.txt 2011-03-27 12:41:58 UTC (rev 833)
@@ -10,17 +10,17 @@
(tx XYZ): thanks to XYZ for telling us about the bug
-v1.19.01.00 (March 2011, revision 827)
+v1.19.01.00 (March 2011, revision 833)
--------------------------------------
Pattern tab
[New] <Jojo> Clicking and dragging the row numbers selects the whole row now (Excel / Calc style) - see http://bugs.openmpt.org/view.php?id=45
[New] <Jojo> The new keyboard shortcuts "Select beat" and "Select measure" can be used to automatically extend the current selection to the beat / measure boundaries.
[New] <Jojo> Experimental feature: Play the whole pattern row when entering notes and chords into the pattern editor. This can be enabled from the setup screen.
[Imp] <Jojo> Special paste modes have been moved to a sub menu in the context menu, to save some space.
- [Imp] <Jojo> Status bar now indicates if highpass filter is enabled on a channel.
+ [Imp] <Jojo> Status bar now indicates if highpass filter is enabled on a channel. (http://bugs.openmpt.org/view.php?id=92)
[Mod] <Jojo> Using the Goto Dialog should now update channel parameters and set the elapsed time. (http://bugs.openmpt.org/view.php?id=28)
[Mod] <Jojo> Undo steps have been increased from 100 to 1000.
- [Fix] <Jojo> Shrink selection is more consistent with Shrink pattern now: Entries on odd rows are not ignored anymore if there is no entry in the even rows. Also, cleaning of the pattern after shrinking the selection has been fixed - it cleaned whole commands instead of just the selected parts of a command.
+ [Fix] <Jojo> Shrink selection is more consistent with Shrink pattern now: Entries on odd rows are not ignored anymore if there is no entry in the even rows. Also, cleaning of the pattern after shrinking the selection has been fixed - it cleaned whole commands instead of just the selected parts of a command. (http://bugs.openmpt.org/view.php?id=89)
[Fix] <Jojo> Cursor paste was possible even when editing was disabled.
[Fix] <Jojo> Using Right-Click -> Change Plugin on PC notes did not work for plugin numbers that were higher than the highest instrument number.
[Fix] <Jojo> When entering chords into the pattern editor, the module was only marked as modified if the base note of the chord was changed.
@@ -31,6 +31,7 @@
[Fix] <Jojo> When restarting a pattern, the song timer was not reset properly.
[Fix] <Jojo> Entering a note-off event in the MOD format created an unnecessary undo event.
[Fix] <Jojo> Automation data is not written to the pattern if the current module format does not support smooth midi macros.
+ [Fix] <Jojo> Selections were not clamped properly to the end of the pattern sometimes.
[Reg] <Jojo> The "Position aware timer" option is gone. The position aware timer is now automatically used. It was optional in the first place because of some buggy code, which is now fixed.
Pattern tab::Note properties
@@ -53,6 +54,7 @@
[Imp] <re> Ctrl + Mouse Wheel can now be used for zooming into the sample data.
[Mod] <Jojo> Undo steps have been increased from 100 to 1000 (per sample).
[Fix] <Jojo> When cutting samples with a loop, the loop end point was not always moved correctly if the cut start was in the loop.
+ [Fix] <Jojo> Loop point controls also accept large numbers to be inputted manually.
[Fix] <Jojo> Sample Undo didn't preserve the sample name.
[Fix] <re> Changing zoom level should now preserve the view position better. (http://bugs.openmpt.org/view.php?id=3)
@@ -60,6 +62,7 @@
[Imp] <re> Ctrl + Mouse Wheel can now be used for zooming into the envelopes.
[Imp] <Jojo> When pressing the up arrow key in the sample map while the cursor is on the lowest note (C-0), the sample map doesn't lose focus anymore. It is also not possible anymore to move the sample map out of view by clicking the area above the lowest note.
[Mod] <Jojo> Copying and pasting envelopes with no points isn't possible anymore. (Who wants to do that anyway?)
+ [Fix] <Jojo> Fadeout control also accepts large numbers to be inputted manually. (http://bugs.openmpt.org/view.php?id=81)
[Fix] <Jojo> Changing the filter mode didn't mark the file as modified.
[Fix] <Jojo> The note mapping doesn't allow items anymore that aren't notes (such as "no note" or "note cut"). Such notes couldn't be entered manually, however when converting from other formats this was possible and it could crash the tracker (http://bugs.openmpt.org/view.php?id=61).
[Fix] <Jojo> Various actions in the instrument note map and envelope view should now also mark the instrument as modified (when working in the ITP format).
@@ -102,6 +105,7 @@
[Fix] <Jojo> Various fixes to playback of multi-sample instruments. "Ultima Ratio" by Nebularia and "Shuttle Departure" by Sphenx sound better now.
[Fix] <Jojo> The extended sample map is not saved anymore in the instrument headers when using compatibility export.
[Fix] <Jojo> IT Loader / Saver: Note mapping items that aren't notes are now ignored.
+ [Fix] <Jojo> IT Saver: Non-existing envelopes are now replaced by a default (disabled) envelope, so that they can still be edited in Impulse Tracker.
MPTM
[New] <Jojo> Each pattern can now have a custom time signature (rows per beat and rows per measure) which can be set from the pattern properties dialog.
@@ -128,7 +132,9 @@
[Fix] <Jojo> Octave 8 was allowed in S3M files while it shouldn't (it wasn't even saved in the file)
[Fix] <Jojo> S3M Loader: Fix to pattern loader (for empty patterns)
[Fix] <Jojo> Removed the X param (#) effect from the supported effect list.
- [Fix] <Jojo> Speed and tempo values are now adjusted to what Scream Tracker actually expects (speed 1 - 254, tempo 32 - 255) - anything out of this range is ignored by Scream Tracker, so it is now also ignored by OpenMPT.
+ [Fix] <Jojo> Speed and tempo values are now adjusted to what Scream Tracker actually expects (speed 1 - 254, tempo 33 - 255) - anything out of this range is ignored by Scream Tracker, so it is now also ignored by OpenMPT.
+ [Fix] <Jojo> Pattern breaks >= C40 are now ingnored.
+ [Fix] <Jojo> Global volume commands > V40 are now ignored. Global volume is processed on tick 1 to emulate ST3's behaviour (far from perfect).
Other modules
[Imp] <Jojo> Garbage characters in sample / instrument / song names should be gone now.. This should f.e. avoid sample names like " ntitled" turning up in modules after deleting sample names.
@@ -141,6 +147,7 @@
Misc
[New] <Jojo> WAV Export: Sample-exact cue points are now written at each pattern transition.
+ [New] <Jojo> Most MPT hacks in modules can now be found through View -> Find MPT Hacks in Song.
[Imp] <Jojo> Paths to VST plugins in mptrack.ini and plugin.cache are now also relative in portable mode. This means that finally, *all* stored paths are now relative in portable mode.
[Imp] <Jojo> Additional new keyboard shortcuts: Panic, View Edit History, Set Invalid / Ignore (--- / +++) Pattern (in the orderlist), plus the ones mentioned in above categories
[Imp] <Jojo> Some improvements were made to the Registry / INI reading: If there were no Registry settings because MPT 1.16 was previously not installed, the INI file is now also read as it might contain some lines created by the installer.
Modified: trunk/OpenMPT/packageTemplate/OMPT_1.19_ReleaseNotes.html
===================================================================
--- trunk/OpenMPT/packageTemplate/OMPT_1.19_ReleaseNotes.html 2011-03-26 17:57:33 UTC (rev 832)
+++ trunk/OpenMPT/packageTemplate/OMPT_1.19_ReleaseNotes.html 2011-03-27 12:41:58 UTC (rev 833)
@@ -125,6 +125,7 @@
<li>IT files not saved using compatibility export can now finally be opened in Impulse Tracker again.</li>
<li>The new <strong>compatible mix mode</strong> should be used when composing music in the XM and IT format (it is automatically used when working with MOD and S3M). It uses the same volume levels and panning settings as Schism Tracker and should therefore allow for easier interchange of tracked tunes between various trackers.</li>
<li>The MOD loader has been extended with heuristic detection methods for files with 7-bit panning, VBlank MODs and MODs made with ProTracker 1.x.</li>
+ <li>Most <strong>MPT Hacks</strong> in modules can now be found through View → Find MPT Hacks in Song.</li>
<li>As always, countless other <strong>playback compatibility fixes</strong> have made it into this version of OpenMPT.</li>
</ul>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-03-26 17:57:40
|
Revision: 832
http://modplug.svn.sourceforge.net/modplug/?rev=832&view=rev
Author: saga-games
Date: 2011-03-26 17:57:33 +0000 (Sat, 26 Mar 2011)
Log Message:
-----------
[New] Most MPT hacks in modules can now be found through View -> Find MPT Hacks in Song.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/MPTHacks.cpp
trunk/OpenMPT/mptrack/Moddoc.cpp
trunk/OpenMPT/mptrack/Moddoc.h
trunk/OpenMPT/mptrack/mptrack.rc
trunk/OpenMPT/mptrack/resource.h
trunk/OpenMPT/soundlib/mod_specifications.h
Modified: trunk/OpenMPT/mptrack/MPTHacks.cpp
===================================================================
--- trunk/OpenMPT/mptrack/MPTHacks.cpp 2011-03-26 15:16:39 UTC (rev 831)
+++ trunk/OpenMPT/mptrack/MPTHacks.cpp 2011-03-26 17:57:33 UTC (rev 832)
@@ -85,8 +85,8 @@
};
// Go through the module to find out if it contains any hacks introduced by (Open)MPT
-bool CModDoc::HasMPTHacks(bool autofix)
-//-------------------------------------
+bool CModDoc::HasMPTHacks(const bool autofix)
+//-------------------------------------------
{
const CModSpecifications *originalSpecs = &m_SndFile.GetModSpecifications();
// retrieve original (not hacked) specs.
@@ -107,6 +107,7 @@
}
bool foundHacks = false, foundHere = false;
+ CString message;
ClearLog();
// Check for plugins
@@ -126,7 +127,8 @@
// Pattern count
if(m_SndFile.GetNumPatterns() > originalSpecs->patternsMax)
{
- AddToLog("Found too many patterns\n");
+ message.Format("Found too many patterns (%d allowed)\n", originalSpecs->patternsMax);
+ AddToLog(message);
foundHacks = true;
// REQUIRES (INTELLIGENT) AUTOFIX
}
@@ -146,7 +148,10 @@
}
}
if(foundHere)
- AddToLog("Found incompatible pattern lengths\n");
+ {
+ message.Format("Found incompatible pattern lengths (must be between %d and %d rows)\n", originalSpecs->patternRowsMin, originalSpecs->patternRowsMax);
+ AddToLog(message);
+ }
// Check for invalid pattern commands
foundHere = false;
@@ -179,7 +184,8 @@
// Check for too many channels
if(m_SndFile.GetNumChannels() > originalSpecs->channelsMax || m_SndFile.GetNumChannels() < originalSpecs->channelsMin)
{
- AddToLog("Found incompatible channel count\n");
+ message.Format("Found incompatible channel count (must be between %d and %d channels)\n", originalSpecs->channelsMin, originalSpecs->channelsMax);
+ AddToLog(message);
foundHacks = true;
// REQUIRES (INTELLIGENT) AUTOFIX
}
@@ -203,7 +209,8 @@
// Check for too many samples
if(m_SndFile.GetNumSamples() > originalSpecs->samplesMax)
{
- AddToLog("Found too many samples\n");
+ message.Format("Found too many samples (%d allowed)\n", originalSpecs->samplesMax);
+ AddToLog(message);
foundHacks = true;
// REQUIRES (INTELLIGENT) AUTOFIX
}
@@ -211,7 +218,8 @@
// Check for too many instruments
if(m_SndFile.GetNumInstruments() > originalSpecs->instrumentsMax)
{
- AddToLog("Found too many instruments\n");
+ message.Format("Found too many instruments (%d allowed)\n", originalSpecs->instrumentsMax);
+ AddToLog(message);
foundHacks = true;
// REQUIRES (INTELLIGENT) AUTOFIX
}
@@ -253,7 +261,8 @@
// Check for too many orders
if(m_SndFile.Order.GetLengthTailTrimmed() > originalSpecs->ordersMax)
{
- AddToLog("Found too many orders\n");
+ message.Format("Found too many orders (%d allowed)\n", originalSpecs->ordersMax);
+ AddToLog(message);
foundHacks = true;
// REQUIRES (INTELLIGENT) AUTOFIX
}
@@ -261,7 +270,8 @@
// Check for invalid default tempo
if(m_SndFile.m_nDefaultTempo > originalSpecs->tempoMax || m_SndFile.m_nDefaultTempo < originalSpecs->tempoMin)
{
- AddToLog("Found incompatible default tempo\n");
+ message.Format("Found incompatible default tempo (must be between %d and %d)\n", originalSpecs->tempoMin, originalSpecs->tempoMax);
+ AddToLog(message);
foundHacks = true;
if(autofix)
m_SndFile.m_nDefaultTempo = CLAMP(m_SndFile.m_nDefaultTempo, originalSpecs->tempoMin, originalSpecs->tempoMax);
@@ -270,7 +280,8 @@
// Check for invalid default speed
if(m_SndFile.m_nDefaultSpeed > originalSpecs->speedMax || m_SndFile.m_nDefaultSpeed < originalSpecs->speedMin)
{
- AddToLog("Found incompatible default speed\n");
+ message.Format("Found incompatible default speed (must be between %d and %d)\n", originalSpecs->speedMin, originalSpecs->speedMax);
+ AddToLog(message);
foundHacks = true;
if(autofix)
m_SndFile.m_nDefaultSpeed = CLAMP(m_SndFile.m_nDefaultSpeed, originalSpecs->speedMin, originalSpecs->speedMax);
@@ -312,7 +323,7 @@
// Check for new tempo modes
if(m_SndFile.m_nTempoMode != tempo_mode_classic)
{
- AddToLog("Found incompatible tempo mode\n");
+ AddToLog("Found incompatible tempo mode (only classic tempo mode allowed)\n");
foundHacks = true;
if(autofix)
m_SndFile.m_nTempoMode = tempo_mode_classic;
@@ -358,7 +369,7 @@
if(m_SndFile.m_nMixLevels != mixLevels_compatible)
{
- AddToLog("Found incorrect mix levels\n");
+ AddToLog("Found incorrect mix levels (only compatible mix levels allowed)\n");
foundHacks = true;
if(autofix)
m_SndFile.m_nMixLevels = mixLevels_compatible;
@@ -366,6 +377,6 @@
if(autofix && foundHacks)
SetModified();
-
+
return foundHacks;
}
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2011-03-26 15:16:39 UTC (rev 831)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2011-03-26 17:57:33 UTC (rev 832)
@@ -53,6 +53,7 @@
ON_COMMAND(ID_VIEW_COMMENTS, OnEditComments)
ON_COMMAND(ID_VIEW_GRAPH, OnEditGraph) //rewbs.graph
ON_COMMAND(ID_VIEW_EDITHISTORY, OnViewEditHistory)
+ ON_COMMAND(ID_VIEW_MPTHACKS, OnViewMPTHacks)
ON_COMMAND(ID_INSERT_PATTERN, OnInsertPattern)
ON_COMMAND(ID_INSERT_SAMPLE, OnInsertSample)
ON_COMMAND(ID_INSERT_INSTRUMENT, OnInsertInstrument)
@@ -3513,6 +3514,18 @@
}
+void CModDoc::OnViewMPTHacks()
+//----------------------------
+{
+ if(!HasMPTHacks())
+ {
+ AddToLog("No hacks found.\n");
+ }
+ ShowLog();
+ ClearLog();
+}
+
+
LRESULT CModDoc::OnCustomKeyMsg(WPARAM wParam, LPARAM /*lParam*/)
//---------------------------------------------------------------
{
Modified: trunk/OpenMPT/mptrack/Moddoc.h
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.h 2011-03-26 15:16:39 UTC (rev 831)
+++ trunk/OpenMPT/mptrack/Moddoc.h 2011-03-26 17:57:33 UTC (rev 832)
@@ -346,7 +346,7 @@
bool RestartPosToPattern();
- bool HasMPTHacks(bool autofix = false);
+ bool HasMPTHacks(const bool autofix = false);
void FixNullStrings();
@@ -436,6 +436,7 @@
afx_msg void OnPatternPlay(); //rewbs.customKeys
afx_msg void OnPatternPlayNoLoop(); //rewbs.customKeys
afx_msg void OnViewEditHistory();
+ afx_msg void OnViewMPTHacks();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
Modified: trunk/OpenMPT/mptrack/mptrack.rc
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.rc 2011-03-26 15:16:39 UTC (rev 831)
+++ trunk/OpenMPT/mptrack/mptrack.rc 2011-03-26 17:57:33 UTC (rev 832)
@@ -2008,12 +2008,13 @@
MENUITEM "&Tree", IDD_TREEVIEW
END
MENUITEM SEPARATOR
- MENUITEM "Set&up...", ID_VIEW_OPTIONS
- MENUITEM "Add &Plugin...", ID_PLUGIN_SETUP
- MENUITEM "Channel &Manager...", ID_CHANNEL_MANAGER
- MENUITEM "Song Properties...", ID_VIEW_SONGPROPERTIES
+ MENUITEM "S&etup...", ID_VIEW_OPTIONS
+ MENUITEM "Pl&ugin Manager...", ID_PLUGIN_SETUP
+ MENUITEM "Ch&annel Manager...", ID_CHANNEL_MANAGER
+ MENUITEM "Song P&roperties...", ID_VIEW_SONGPROPERTIES
MENUITEM "&MIDI Mapping...", ID_VIEW_MIDIMAPPING
MENUITEM "Edit &History...", ID_VIEW_EDITHISTORY
+ MENUITEM "Find MPT Hacks in Song", ID_VIEW_MPTHACKS
END
POPUP "&Window"
BEGIN
Modified: trunk/OpenMPT/mptrack/resource.h
===================================================================
--- trunk/OpenMPT/mptrack/resource.h 2011-03-26 15:16:39 UTC (rev 831)
+++ trunk/OpenMPT/mptrack/resource.h 2011-03-26 17:57:33 UTC (rev 832)
@@ -1184,6 +1184,7 @@
#define ID_SAMPLE_GRID 60453
#define ID_SAMPLE_QUICKFADE 60454
#define ID_EDIT_MIXPASTE_ITSTYLE 60455
+#define ID_VIEW_MPTHACKS 60456
// Next default values for new objects
//
@@ -1191,7 +1192,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 529
-#define _APS_NEXT_COMMAND_VALUE 60456
+#define _APS_NEXT_COMMAND_VALUE 60457
#define _APS_NEXT_CONTROL_VALUE 2435
#define _APS_NEXT_SYMED_VALUE 901
#endif
Modified: trunk/OpenMPT/soundlib/mod_specifications.h
===================================================================
--- trunk/OpenMPT/soundlib/mod_specifications.h 2011-03-26 15:16:39 UTC (rev 831)
+++ trunk/OpenMPT/soundlib/mod_specifications.h 2011-03-26 17:57:33 UTC (rev 832)
@@ -193,7 +193,7 @@
false, // No notecut.
true, // Has noteoff.
false, // No notefade.
- 255, // Pattern max.
+ 256, // Pattern max.
255, // Order max.
1, // Channel min
32, // Channel max
@@ -233,8 +233,8 @@
false, // No notecut.
true, // Has noteoff.
false, // No notefade.
- 255, // Pattern max.
- 256, // Order max.
+ 256, // Pattern max.
+ 255, // Order max.
1, // Channel min
127, // Channel max
32, // Min tempo
@@ -272,7 +272,7 @@
true, // Has notecut.
false, // No noteoff.
false, // No notefade.
- 99, // Pattern max.
+ 100, // Pattern max.
255, // Order max.
1, // Channel min
32, // Channel max
@@ -312,7 +312,7 @@
true, // Has notecut.
false, // No noteoff.
false, // No notefade.
- 99, // Pattern max.
+ 100, // Pattern max.
255, // Order max.
1, // Channel min
32, // Channel max
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-03-26 15:16:46
|
Revision: 831
http://modplug.svn.sourceforge.net/modplug/?rev=831&view=rev
Author: saga-games
Date: 2011-03-26 15:16:39 +0000 (Sat, 26 Mar 2011)
Log Message:
-----------
[Fix] S3M compatibility: Tempo 32 is not allowed anymore (not supported by ST3), default speed of 255 is also forbidden (not supported by ST3)
[Fix] S3M compatibility: Global volume commands > V40 are now ignored. Global volume is processed on tick 1 to emulate ST3's behaviour (far from perfect).
[Fix] S3M compatibility: Pattern breaks >= C40 are now ingnored.
[Fix] Pattern Editor: Automatically generated selections were not clamped properly to the end of the pattern.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_gen.cpp
trunk/OpenMPT/mptrack/Draw_pat.cpp
trunk/OpenMPT/soundlib/Load_s3m.cpp
trunk/OpenMPT/soundlib/Snd_fx.cpp
trunk/OpenMPT/soundlib/Sndfile.h
trunk/OpenMPT/soundlib/mod_specifications.h
Modified: trunk/OpenMPT/mptrack/Ctrl_gen.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_gen.cpp 2011-03-26 13:07:43 UTC (rev 830)
+++ trunk/OpenMPT/mptrack/Ctrl_gen.cpp 2011-03-26 15:16:39 UTC (rev 831)
@@ -92,16 +92,17 @@
// -> CODE#0016
// -> DESC="default tempo update"
// m_SpinTempo.SetRange(32, 255); // 255 bpm max
- // S3M HACK
+
if(m_pSndFile->GetType() & MOD_TYPE_S3M)
{
- m_SpinTempo.SetRange(33, 255);
- m_SpinSpeed.SetRange(1, 255);
+ // S3M HACK: ST3 will ignore speed 255, even though it can be used with Axx.
+ m_SpinSpeed.SetRange(1, 254);
} else
{
- m_SpinTempo.SetRange((short)specs.tempoMin, (short)specs.tempoMax);
m_SpinSpeed.SetRange((short)specs.speedMin, (short)specs.speedMax);
}
+ m_SpinTempo.SetRange((short)specs.tempoMin, (short)specs.tempoMax);
+
// -! BEHAVIOUR_CHANGE#0016
m_SpinGlobalVol.SetRange(0, 128);
m_SpinSamplePA.SetRange(0, 2000);
Modified: trunk/OpenMPT/mptrack/Draw_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Draw_pat.cpp 2011-03-26 13:07:43 UTC (rev 830)
+++ trunk/OpenMPT/mptrack/Draw_pat.cpp 2011-03-26 15:16:39 UTC (rev 831)
@@ -1318,9 +1318,9 @@
if (pSndFile)
{
y1 = max(y1, 0);
- y2 = min(y2, (int)pSndFile->Patterns[m_nPattern].GetNumRows());
+ y2 = min(y2, (int)pSndFile->Patterns[m_nPattern].GetNumRows() - 1);
x1 = max(x1, 0);
- x2 = min(x2, pSndFile->GetNumChannels() * 8 - 4);
+ x2 = min(x2, pSndFile->GetNumChannels() * 8 - (8 - LAST_COLUMN));
}
}
// end rewbs.fix3417
Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_s3m.cpp 2011-03-26 13:07:43 UTC (rev 830)
+++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2011-03-26 15:16:39 UTC (rev 831)
@@ -598,8 +598,8 @@
header[0x2E] = 'R';
header[0x2F] = 'M';
header[0x30] = m_nDefaultGlobalVolume >> 2;
- header[0x31] = CLAMP(m_nDefaultSpeed, 1, 255);
- header[0x32] = CLAMP(m_nDefaultTempo, 32, 255);
+ header[0x31] = CLAMP(m_nDefaultSpeed, 1, 254);
+ header[0x32] = CLAMP(m_nDefaultTempo, 33, 255);
header[0x33] = CLAMP(m_nSamplePreAmp, 0x10, 0x7F) | 0x80; // Bit 8 = Stereo
header[0x34] = 0x08; // 8 Channels for UltraClick removal (default)
header[0x35] = 0xFC; // Write pan positions
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-03-26 13:07:43 UTC (rev 830)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-03-26 15:16:39 UTC (rev 831)
@@ -227,6 +227,11 @@
break;
// Pattern Break
case CMD_PATTERNBREAK:
+ if(param >= 64 && (GetType() & MOD_TYPE_S3M))
+ {
+ // ST3 ignores invalid pattern breaks.
+ break;
+ }
patternBreakOnThisRow = true;
//Try to check next row for XPARAM
nextRow = nullptr;
@@ -338,10 +343,16 @@
break;
// Global Volume
case CMD_GLOBALVOLUME:
+ // ST3 applies global volume on tick 1 and does other weird things, but we just emulate this part for now.
+ if((GetType() & MOD_TYPE_S3M) && nMusicSpeed <= 1)
+ {
+ break;
+ }
+
if (!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) param <<= 1;
- if(IsCompatibleMode(TRK_IMPULSETRACKER | TRK_FASTTRACKER2))
+ if(IsCompatibleMode(TRK_IMPULSETRACKER | TRK_FASTTRACKER2 | TRK_SCREAMTRACKER))
{
- //IT compatibility 16. Both FT2 and IT ignore out-of-range values
+ //IT compatibility 16. FT2, ST3 and IT ignore out-of-range values
if (param <= 128)
nGlbVol = param << 1;
}
@@ -1869,11 +1880,16 @@
// Set Global Volume
case CMD_GLOBALVOLUME:
- if (!(m_dwSongFlags & SONG_FIRSTTICK)) break;
+ // ST3 applies global volume on tick 1 and does other weird things, but we just emulate this part for now.
+ if(((GetType() & MOD_TYPE_S3M) && m_nTickCount != 1)
+ || (!(GetType() & MOD_TYPE_S3M) && !(m_dwSongFlags & SONG_FIRSTTICK)))
+ {
+ break;
+ }
- if (!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) param <<= 1;
- //IT compatibility 16. Both FT2 and IT ignore out-of-range values
- if(IsCompatibleMode(TRK_IMPULSETRACKER | TRK_FASTTRACKER2))
+ if (!(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT))) param <<= 1;
+ //IT compatibility 16. FT2, ST3 and IT ignore out-of-range values
+ if(IsCompatibleMode(TRK_IMPULSETRACKER | TRK_FASTTRACKER2 | TRK_SCREAMTRACKER))
{
if (param <= 128)
m_nGlobalVolume = param << 1;
@@ -2056,6 +2072,11 @@
// Pattern Break
case CMD_PATTERNBREAK:
+ if(param >= 64 && (GetType() & MOD_TYPE_S3M))
+ {
+ // ST3 ignores invalid pattern breaks.
+ break;
+ }
m_nNextPatStartRow = 0; // FT2 E60 bug
m = NULL;
if (m_nRow < Patterns[m_nPattern].GetNumRows()-1)
@@ -3021,7 +3042,7 @@
//------------------------------------------------------------------------------------------
{
MODCHANNEL *pChn = &Chn[nChn];
- DWORD dwMacro = (*((DWORD *)pszMidiMacro)) & MACRO_MASK;
+ DWORD dwMacro = LittleEndian(*((DWORD *)pszMidiMacro)) & MACRO_MASK;
int nInternalCode;
// Not Internal Device ?
@@ -3775,57 +3796,6 @@
}
-// This is how backward jumps should not be tested. :) (now unused)
-BOOL CSoundFile::IsValidBackwardJump(UINT nStartOrder, UINT nStartRow, UINT nJumpOrder, UINT nJumpRow) const
-//----------------------------------------------------------------------------------------------------------
-{
- while ((nJumpOrder < Patterns.Size()) && (Order[nJumpOrder] == Order.GetIgnoreIndex())) nJumpOrder++;
- if ((nStartOrder >= Patterns.Size()) || (nJumpOrder >= Patterns.Size())) return FALSE;
- // Treat only case with jumps in the same pattern
- if (nJumpOrder > nStartOrder) return TRUE;
-
- if ((nJumpOrder < nStartOrder) || (nJumpRow >= Patterns[nStartOrder].GetNumRows())
- || (!(Patterns[nStartOrder])) || (nStartRow >= MAX_PATTERN_ROWS) || (nJumpRow >= MAX_PATTERN_ROWS)) return FALSE;
-
- // See if the pattern is being played backward
- BYTE row_hist[MAX_PATTERN_ROWS];
-
- memset(row_hist, 0, sizeof(row_hist));
- UINT nRows = Patterns[nStartOrder].GetNumRows(), row = nJumpRow;
-
- if (nRows > MAX_PATTERN_ROWS) nRows = MAX_PATTERN_ROWS;
- row_hist[nStartRow] = TRUE;
- while ((row < MAX_PATTERN_ROWS) && (!row_hist[row]))
- {
- if (row >= nRows) return TRUE;
- row_hist[row] = TRUE;
- const MODCOMMAND* p = Patterns[nStartOrder].GetpModCommand(row, m_nChannels);
- row++;
- int breakrow = -1, posjump = 0;
- for (UINT i=0; i<m_nChannels; i++, p++)
- {
- if (p->command == CMD_POSITIONJUMP)
- {
- if (p->param < nStartOrder) return FALSE;
- if (p->param > nStartOrder) return TRUE;
- posjump = TRUE;
- } else
- if (p->command == CMD_PATTERNBREAK)
- {
- breakrow = p->param;
- }
- }
- if (breakrow >= 0)
- {
- if (!posjump) return TRUE;
- row = breakrow;
- }
- if (row >= nRows) return TRUE;
- }
- return FALSE;
-}
-
-
//////////////////////////////////////////////////////
// Note/Period/Frequency functions
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2011-03-26 13:07:43 UTC (rev 830)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2011-03-26 15:16:39 UTC (rev 831)
@@ -917,7 +917,6 @@
void DoFreqSlide(MODCHANNEL *pChn, LONG nFreqSlide);
void GlobalVolSlide(UINT param, UINT * nOldGlobalVolSlide);
DWORD IsSongFinished(UINT nOrder, UINT nRow) const;
- BOOL IsValidBackwardJump(UINT nStartOrder, UINT nStartRow, UINT nJumpOrder, UINT nJumpRow) const;
void UpdateTimeSignature();
UINT GetNumTicksOnCurrentRow() { return m_nMusicSpeed * (m_nPatternDelay + 1) + m_nFrameDelay; };
Modified: trunk/OpenMPT/soundlib/mod_specifications.h
===================================================================
--- trunk/OpenMPT/soundlib/mod_specifications.h 2011-03-26 13:07:43 UTC (rev 830)
+++ trunk/OpenMPT/soundlib/mod_specifications.h 2011-03-26 15:16:39 UTC (rev 831)
@@ -276,7 +276,7 @@
255, // Order max.
1, // Channel min
32, // Channel max
- 32, // Min tempo
+ 33, // Min tempo
255, // Max tempo
64, // Min pattern rows
64, // Max pattern rows
@@ -316,7 +316,7 @@
255, // Order max.
1, // Channel min
32, // Channel max
- 32, // Min tempo
+ 33, // Min tempo
255, // Max tempo
64, // Min pattern rows
64, // Max pattern rows
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-03-26 13:07:50
|
Revision: 830
http://modplug.svn.sourceforge.net/modplug/?rev=830&view=rev
Author: saga-games
Date: 2011-03-26 13:07:43 +0000 (Sat, 26 Mar 2011)
Log Message:
-----------
[Fix] Sample Editor: Loop point controls also accept large numbers to be inputted manually.
[Fix] Instrument Editor: Fadeout control also accepts large numbers to be inputted manually.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_ins.cpp
trunk/OpenMPT/mptrack/Ctrl_ins.h
trunk/OpenMPT/mptrack/mptrack.rc
trunk/OpenMPT/mptrack/version.h
Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2011-03-25 18:36:23 UTC (rev 829)
+++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2011-03-26 13:07:43 UTC (rev 830)
@@ -825,6 +825,7 @@
DDX_Control(pDX, IDC_COMBO6, m_CbnMixPlug); //rewbs.instroVSTi
DDX_Control(pDX, IDC_COMBO9, m_CbnResampling);
DDX_Control(pDX, IDC_FILTERMODE, m_CbnFilterMode);
+ DDX_Control(pDX, IDC_EDIT7, m_EditFadeOut);
DDX_Control(pDX, IDC_SPIN7, m_SpinFadeOut);
DDX_Control(pDX, IDC_SPIN8, m_SpinGlobalVol);
DDX_Control(pDX, IDC_SPIN9, m_SpinPanning);
@@ -1163,10 +1164,10 @@
m_EditName.SetLimitText(specs->instrNameLengthMax);
m_EditFileName.SetLimitText(specs->instrFilenameLengthMax);
- BOOL bITandMPT = ((m_pSndFile->m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (m_pSndFile->m_nInstruments)) ? TRUE : FALSE;
+ const BOOL bITandMPT = ((m_pSndFile->m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (m_pSndFile->m_nInstruments)) ? TRUE : FALSE;
//rewbs.instroVSTi
- BOOL bITandXM = ((m_pSndFile->m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_XM)) && (m_pSndFile->m_nInstruments)) ? TRUE : FALSE;
- bool bMPTOnly = ((m_pSndFile->m_nType == MOD_TYPE_MPT) && (m_pSndFile->m_nInstruments)) ? TRUE : FALSE;
+ const BOOL bITandXM = ((m_pSndFile->m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_XM)) && (m_pSndFile->m_nInstruments)) ? TRUE : FALSE;
+ const BOOL bMPTOnly = ((m_pSndFile->m_nType == MOD_TYPE_MPT) && (m_pSndFile->m_nInstruments)) ? TRUE : FALSE;
::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT10), bITandXM);
::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT11), bITandXM);
::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT7), bITandXM);
@@ -1180,11 +1181,10 @@
m_SpinMidiBK.EnableWindow(bITandXM); //rewbs.MidiBank
//end rewbs.instroVSTi
+ const bool extendedFadeoutRange = (m_pSndFile->m_nType & MOD_TYPE_XM) != 0;
m_SpinFadeOut.EnableWindow(bITandXM);
- if(m_pSndFile->m_nType & MOD_TYPE_XM)
- m_SpinFadeOut.SetRange(0, 32767);
- else
- m_SpinFadeOut.SetRange(0, 8192);
+ m_SpinFadeOut.SetRange(0, extendedFadeoutRange ? 32767 : 8192);
+ m_EditFadeOut.SetLimitText(extendedFadeoutRange ? 5 : 4);
// Panning ranges (0...64 for IT, 0...256 for MPTM)
m_SpinPanning.SetRange(0, (m_pModDoc->GetModType() & MOD_TYPE_IT) ? 64 : 256);
@@ -1551,7 +1551,7 @@
{
m_CbnPluginVelocityHandling.EnableWindow(FALSE);
m_CbnPluginVolumeHandling.EnableWindow(FALSE);
- wsprintf(pszText, "To enable, clear plugin volume command bug emulation flag from song properties");
+ wsprintf(pszText, "To enable, clear Plugin volume command bug emulation flag from Song Properties");
return TRUE;
}
else
@@ -1825,8 +1825,10 @@
MODINSTRUMENT *pIns = m_pSndFile->Instruments[m_nInstrument];
if ((!IsLocked()) && (pIns))
{
+ int minval = 0, maxval = 32767;
+ m_SpinFadeOut.GetRange(minval, maxval);
int nVol = GetDlgItemInt(IDC_EDIT7);
- nVol = CLAMP(nVol, 0, 32767);
+ nVol = CLAMP(nVol, minval, maxval);
if(nVol != (int)pIns->nFadeOut)
{
Modified: trunk/OpenMPT/mptrack/Ctrl_ins.h
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_ins.h 2011-03-25 18:36:23 UTC (rev 829)
+++ trunk/OpenMPT/mptrack/Ctrl_ins.h 2011-03-26 13:07:43 UTC (rev 830)
@@ -83,7 +83,7 @@
CSpinButtonCtrl m_SpinInstrument, m_SpinFadeOut, m_SpinGlobalVol, m_SpinPanning;
CSpinButtonCtrl m_SpinMidiPR, m_SpinPPS, m_SpinMidiBK;
CComboBox m_ComboNNA, m_ComboDCT, m_ComboDCA, m_ComboPPC, m_CbnMidiCh, m_CbnMixPlug, m_CbnResampling, m_CbnFilterMode, m_CbnPluginVelocityHandling, m_CbnPluginVolumeHandling;
- CEdit m_EditName, m_EditFileName, m_EditGlobalVol, m_EditPanning, m_EditPPS;
+ CEdit m_EditName, m_EditFileName, m_EditGlobalVol, m_EditPanning, m_EditPPS, m_EditFadeOut;
CButton m_CheckPanning, m_CheckCutOff, m_CheckResonance;
CSliderCtrl m_SliderVolSwing, m_SliderPanSwing, m_SliderCutSwing, m_SliderResSwing,
m_SliderCutOff, m_SliderResonance;
Modified: trunk/OpenMPT/mptrack/mptrack.rc
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.rc 2011-03-25 18:36:23 UTC (rev 829)
+++ trunk/OpenMPT/mptrack/mptrack.rc 2011-03-26 13:07:43 UTC (rev 830)
@@ -614,14 +614,14 @@
EDITTEXT IDC_SAMPLE_NAME,129,26,135,12,ES_AUTOHSCROLL
EDITTEXT IDC_SAMPLE_FILENAME,292,26,72,13,ES_AUTOHSCROLL
COMBOBOX IDC_COMBO1,130,54,45,46,CBS_DROPDOWNLIST | WS_TABSTOP
- EDITTEXT IDC_EDIT1,130,70,45,12,ES_NUMBER
+ EDITTEXT IDC_EDIT1,130,70,45,12,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "Spin1",IDC_SPIN1,"msctls_updown32",UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,169,69,11,11
- EDITTEXT IDC_EDIT2,130,83,45,12,ES_NUMBER
+ EDITTEXT IDC_EDIT2,130,83,45,12,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "Spin1",IDC_SPIN2,"msctls_updown32",UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,169,84,11,11
COMBOBOX IDC_COMBO2,212,54,45,46,CBS_DROPDOWNLIST | WS_TABSTOP
- EDITTEXT IDC_EDIT3,212,70,45,12,ES_NUMBER
+ EDITTEXT IDC_EDIT3,212,70,45,12,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "Spin1",IDC_SPIN3,"msctls_updown32",UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,253,70,11,11
- EDITTEXT IDC_EDIT4,212,83,45,12,ES_NUMBER
+ EDITTEXT IDC_EDIT4,212,83,45,12,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "Spin1",IDC_SPIN4,"msctls_updown32",UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,253,83,11,11
COMBOBOX IDC_COMBO3,275,59,47,70,CBS_DROPDOWNLIST | WS_TABSTOP
EDITTEXT IDC_EDIT15,327,59,32,12,ES_NUMBER
@@ -673,17 +673,17 @@
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
- EDITTEXT IDC_EDIT_INSTRUMENT,87,7,29,12,ES_AUTOHSCROLL | ES_NUMBER
+ EDITTEXT IDC_EDIT_INSTRUMENT,87,7,33,12,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "Spin1",IDC_SPIN_INSTRUMENT,"msctls_updown32",UDS_WRAP | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS | WS_TABSTOP,111,8,11,11
EDITTEXT IDC_SAMPLE_NAME,131,6,151,12,ES_AUTOHSCROLL
EDITTEXT IDC_SAMPLE_FILENAME,324,6,105,12,ES_AUTOHSCROLL
- EDITTEXT IDC_EDIT8,87,36,34,12,ES_NUMBER
+ EDITTEXT IDC_EDIT8,84,36,37,12,ES_NUMBER
CONTROL "Spin1",IDC_SPIN8,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,112,40,8,10
- EDITTEXT IDC_EDIT7,87,53,34,12,ES_NUMBER
- CONTROL "Spin1",IDC_SPIN7,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,112,57,8,10
- CONTROL "Pan",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,55,71,29,10
- EDITTEXT IDC_EDIT9,87,70,34,12,ES_NUMBER
- CONTROL "Spin1",IDC_SPIN9,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,112,74,8,11
+ EDITTEXT IDC_EDIT7,84,53,37,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_SPIN7,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,112,57,8,10
+ CONTROL "Set Pan",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,42,72,42,10
+ EDITTEXT IDC_EDIT9,84,70,37,12,ES_NUMBER
+ CONTROL "",IDC_SPIN9,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,112,74,8,11
EDITTEXT IDC_EDIT15,33,99,27,13
CONTROL "Spin1",IDC_SPIN12,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,61,103,7,11
COMBOBOX IDC_COMBO4,95,99,27,91,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
@@ -742,7 +742,6 @@
CTEXT "Cutoff",IDC_STATIC,136,133,33,13,SS_CENTERIMAGE,WS_EX_STATICEDGE
CTEXT "Reso",IDC_STATIC,136,151,33,13,SS_CENTERIMAGE,WS_EX_STATICEDGE
CTEXT "Resampling",IDC_STATIC,7,151,39,13,SS_CENTERIMAGE,WS_EX_STATICEDGE
- CONTROL "Highpass",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | BS_FLAT | NOT WS_VISIBLE | WS_TABSTOP,181,19,45,10
CTEXT "Mode",IDC_STATIC,135,70,23,13,SS_CENTERIMAGE,WS_EX_STATICEDGE
RTEXT "--",IDC_TEXT1,186,62,45,8
GROUPBOX "Pitch/Tempo Lock",IDC_STATIC,364,57,89,25
@@ -1159,7 +1158,7 @@
CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,59,126,83,18
LTEXT "High",IDC_STATIC,149,129,16,8
CTEXT "Pre-Amp",IDC_STATIC,197,78,35,8
- CONTROL "Slider2",IDC_SLIDER_PREAMP,"msctls_trackbar32",TBS_AUTOTICKS | TBS_VERT | TBS_BOTH | WS_TABSTOP,201,89,27,62
+ CONTROL "Slider2",IDC_SLIDER_PREAMP,"msctls_trackbar32",TBS_AUTOTICKS | TBS_VERT | TBS_BOTH | TBS_TOOLTIPS | WS_TABSTOP,201,89,27,62
COMBOBOX IDC_COMBO5,133,62,64,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "Reverse Stereo",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,133,80,62,10
CONTROL "Soft Panning",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,133,92,64,10
Modified: trunk/OpenMPT/mptrack/version.h
===================================================================
--- trunk/OpenMPT/mptrack/version.h 2011-03-25 18:36:23 UTC (rev 829)
+++ trunk/OpenMPT/mptrack/version.h 2011-03-26 13:07:43 UTC (rev 830)
@@ -15,7 +15,7 @@
#define VER_MAJORMAJOR 1
#define VER_MAJOR 19
#define VER_MINOR 00
-#define VER_MINORMINOR 30
+#define VER_MINORMINOR 31
//Creates version number from version parts that appears in version string.
//For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-03-25 18:36:30
|
Revision: 829
http://modplug.svn.sourceforge.net/modplug/?rev=829&view=rev
Author: saga-games
Date: 2011-03-25 18:36:23 +0000 (Fri, 25 Mar 2011)
Log Message:
-----------
[Fix] IT Saver: Non-existing envelopes are now replaced by a default (disabled) envelope, so that they can still be edited in Impulse Tracker.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_it.cpp
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2011-03-24 20:05:01 UTC (rev 828)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2011-03-25 18:36:23 UTC (rev 829)
@@ -237,9 +237,10 @@
return (value > 9) ? 9 : value;
}
+
// Convert MPT's internal nvelope format into an IT/MPTM envelope.
-void MPTEnvToIT(const INSTRUMENTENVELOPE *mptEnv, ITENVELOPE *itEnv, const BYTE envOffset)
-//----------------------------------------------------------------------------------------
+void MPTEnvToIT(const INSTRUMENTENVELOPE *mptEnv, ITENVELOPE *itEnv, const BYTE envOffset, const BYTE envDefault)
+//---------------------------------------------------------------------------------------------------------------
{
if(mptEnv->dwFlags & ENV_ENABLED) itEnv->flags |= 1;
if(mptEnv->dwFlags & ENV_LOOP) itEnv->flags |= 2;
@@ -251,15 +252,26 @@
itEnv->slb = (BYTE)mptEnv->nSustainStart;
itEnv->sle = (BYTE)mptEnv->nSustainEnd;
- // Attention: Full MPTM envelope is stored in extended instrument properties
- for (UINT ev = 0; ev < 25; ev++)
+ if(mptEnv->nNodes > 0)
{
- itEnv->data[ev * 3] = mptEnv->Values[ev] - envOffset;
- itEnv->data[ev * 3 + 1] = mptEnv->Ticks[ev] & 0xFF;
- itEnv->data[ev * 3 + 2] = mptEnv->Ticks[ev] >> 8;
+ // Attention: Full MPTM envelope is stored in extended instrument properties
+ for(size_t ev = 0; ev < 25; ev++)
+ {
+ itEnv->data[ev * 3] = mptEnv->Values[ev] - envOffset;
+ itEnv->data[ev * 3 + 1] = mptEnv->Ticks[ev] & 0xFF;
+ itEnv->data[ev * 3 + 2] = mptEnv->Ticks[ev] >> 8;
+ }
+ } else
+ {
+ // Fix non-existing envelopes so that they can still be edited in Impulse Tracker.
+ itEnv->num = 2;
+ MemsetZero(itEnv->data);
+ itEnv->data[0] = itEnv->data[3] = envDefault - envOffset;
+ itEnv->data[4] = 10;
}
}
+
// Convert IT/MPTM envelope data into MPT's internal envelope format - To be used by ITInstrToMPT()
void ITEnvToMPT(const ITENVELOPE *itEnv, INSTRUMENTENVELOPE *mptEnv, const BYTE envOffset, const int iEnvMax)
//-----------------------------------------------------------------------------------------------------------
@@ -282,6 +294,7 @@
}
}
+
//BOOL CSoundFile::ITInstrToMPT(const void *p, MODINSTRUMENT *pIns, UINT trkvers)
long CSoundFile::ITInstrToMPT(const void *p, MODINSTRUMENT *pIns, UINT trkvers) //rewbs.modularInstData
//-----------------------------------------------------------------------------
@@ -1569,11 +1582,11 @@
keyboardex[i] = (smp>>8);
} else keyboardex[i] = 0;
// Writing Volume envelope
- MPTEnvToIT(&pIns->VolEnv, &iti.volenv, 0);
+ MPTEnvToIT(&pIns->VolEnv, &iti.volenv, 0, 64);
// Writing Panning envelope
- MPTEnvToIT(&pIns->PanEnv, &iti.panenv, 32);
+ MPTEnvToIT(&pIns->PanEnv, &iti.panenv, 32, 32);
// Writing Pitch Envelope
- MPTEnvToIT(&pIns->PitchEnv, &iti.pitchenv, 32);
+ MPTEnvToIT(&pIns->PitchEnv, &iti.pitchenv, 32, 32);
if (pIns->PitchEnv.dwFlags & ENV_FILTER) iti.pitchenv.flags |= 0x80;
} else
// Save Empty Instrument
@@ -2164,11 +2177,11 @@
keyboardex[i] = (smp>>8);
} else keyboardex[i] = 0;
// Writing Volume envelope
- MPTEnvToIT(&pIns->VolEnv, &iti.volenv, 0);
+ MPTEnvToIT(&pIns->VolEnv, &iti.volenv, 0, 64);
// Writing Panning envelope
- MPTEnvToIT(&pIns->PanEnv, &iti.panenv, 32);
+ MPTEnvToIT(&pIns->PanEnv, &iti.panenv, 32, 32);
// Writing Pitch Envelope
- MPTEnvToIT(&pIns->PitchEnv, &iti.pitchenv, 32);
+ MPTEnvToIT(&pIns->PitchEnv, &iti.pitchenv, 32, 32);
if (pIns->PitchEnv.dwFlags & ENV_FILTER) iti.pitchenv.flags |= 0x80;
} else
// Save Empty Instrument
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2011-03-24 20:05:09
|
Revision: 828
http://modplug.svn.sourceforge.net/modplug/?rev=828&view=rev
Author: saga-games
Date: 2011-03-24 20:05:01 +0000 (Thu, 24 Mar 2011)
Log Message:
-----------
[Ref] Merged ProcessMidiMacro and ProcessSmoothMidiMacro into one function to avoid copypasta
[Ref] Project files: Moved mod loaders into own folder in the project tree
[Ref] Added Get[Vol]EffectLetter to mod specs.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/View_smp.cpp
trunk/OpenMPT/mptrack/Vstplug.cpp
trunk/OpenMPT/mptrack/mptrack.vcproj
trunk/OpenMPT/mptrack/mptrack_08.vcproj
trunk/OpenMPT/soundlib/Snd_fx.cpp
trunk/OpenMPT/soundlib/Sndfile.h
trunk/OpenMPT/soundlib/mod_specifications.cpp
trunk/OpenMPT/soundlib/mod_specifications.h
Modified: trunk/OpenMPT/mptrack/View_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_smp.cpp 2011-03-23 22:40:37 UTC (rev 827)
+++ trunk/OpenMPT/mptrack/View_smp.cpp 2011-03-24 20:05:01 UTC (rev 828)
@@ -1282,11 +1282,12 @@
if (pMainFrm && m_dwEndSel <= m_dwBeginSel)
{
- if(m_nSample > 0 && m_nSample < MAX_SAMPLES && x < pSndFile->Samples[m_nSample].nLength )
+ if(m_nSample > 0 && m_nSample < MAX_SAMPLES && x < pSndFile->Samples[m_nSample].nLength)
{
const DWORD xLow = (x / 0x100) % 0x100;
const DWORD xHigh = x / 0x10000;
- const char cOffsetChar = (pSndFile->TypeIsS3M_IT_MPT()) ? gszS3mCommands[CMD_OFFSET] : gszModCommands[CMD_OFFSET];
+
+ const char cOffsetChar = pSndFile->GetModSpecifications().GetEffectLetter(CMD_OFFSET);
const bool bHasHighOffset = (pSndFile->TypeIsS3M_IT_MPT() || (pSndFile->GetType() == MOD_TYPE_XM));
const char cHighOffsetChar = (pSndFile->TypeIsS3M_IT_MPT()) ? gszS3mCommands[CMD_S3MCMDEX] : gszModCommands[CMD_XFINEPORTAUPDOWN];
@@ -1299,7 +1300,9 @@
pMainFrm->SetInfoText(s);
}
else
+ {
pMainFrm->SetInfoText("");
+ }
}
} else UpdateIndicator(NULL);
if (m_dwStatus & SMPSTATUS_MOUSEDRAG)
Modified: trunk/OpenMPT/mptrack/Vstplug.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Vstplug.cpp 2011-03-23 22:40:37 UTC (rev 827)
+++ trunk/OpenMPT/mptrack/Vstplug.cpp 2011-03-24 20:05:01 UTC (rev 828)
@@ -18,7 +18,7 @@
#ifdef VST_USE_ALTERNATIVE_MAGIC //Pelya's plugin ID fix. Breaks fx presets, so let's avoid it for now.
#define ZLIB_WINAPI
#include "../zlib/zlib.h" //For CRC32 calculation (to detect plugins with same UID)
-#endif
+#endif // VST_USE_ALTERNATIVE_MAGIC
#define new DEBUG_NEW
@@ -52,7 +52,7 @@
return crc32(0, (BYTE *)fn, f);
}
-#endif
+#endif // VST_USE_ALTERNATIVE_MAGIC
VstIntPtr VSTCALLBACK CVstPluginManager::MasterCallBack(AEffect *effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void *ptr, float opt)
//----------------------------------------------------------------------------------------------------------------------------------------------
@@ -261,16 +261,16 @@
{
p->dwPluginId1 = CalculateCRC32fromFilename(p->szLibraryName); // Make Plugin ID unique for sure (for VSTs with same UID)
};
- #endif
+ #endif // VST_USE_ALTERNATIVE_MAGIC
#ifdef VST_LOG
Log("Plugin \"%s\" found in PluginCache\n", p->szLibraryName);
- #endif
+ #endif // VST_LOG
return p;
} else
{
#ifdef VST_LOG
Log("Plugin \"%s\" mismatch in PluginCache: \"%s\" [%s]=\"%s\"\n", s, pszDllPath, (LPCTSTR)IDs, (LPCTSTR)strFullPath);
- #endif
+ #endif // VST_LOG
}
}
}
@@ -278,20 +278,21 @@
HINSTANCE hLib = NULL;
- try {
+ try
+ {
hLib = LoadLibrary(pszDllPath);
//rewbs.VSTcompliance
#ifdef _DEBUG
- if (!hLib)
- {
- TCHAR szBuf[256];
- LPVOID lpMsgBuf;
- DWORD dw = GetLastError();
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );
- wsprintf(szBuf, "Warning: encountered problem when loading plugin dll. Error %d: %s", dw, lpMsgBuf);
- MessageBox(NULL, szBuf, "DEBUG: Error when loading plugin dll", MB_OK);
- LocalFree(lpMsgBuf);
- }
+ if (!hLib)
+ {
+ TCHAR szBuf[256];
+ LPVOID lpMsgBuf;
+ DWORD dw = GetLastError();
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );
+ wsprintf(szBuf, "Warning: encountered problem when loading plugin dll. Error %d: %s", dw, lpMsgBuf);
+ MessageBox(NULL, szBuf, "DEBUG: Error when loading plugin dll", MB_OK);
+ LocalFree(lpMsgBuf);
+ }
#endif //_DEBUG
//end rewbs.VSTcompliance
} catch(...)
@@ -304,7 +305,7 @@
PVSTPLUGENTRY pMainProc = (PVSTPLUGENTRY)GetProcAddress(hLib, "main");
#ifdef ENABLE_BUZZ
GET_INFO pBuzzGetInfo = (GET_INFO)GetProcAddress(hLib, "GetInfo");
- #endif
+ #endif // ENABLE_BUZZ
if (pMainProc)
{
PVSTPLUGINLIB p = new VSTPLUGINLIB;
@@ -329,9 +330,9 @@
pEffect->dispatcher(pEffect, effOpen, 0,0,0,0);
#ifdef VST_USE_ALTERNATIVE_MAGIC
p->dwPluginId1 = CalculateCRC32fromFilename(p->szLibraryName); // Make Plugin ID unique for sure
- #else
+ #else
p->dwPluginId1 = pEffect->magic;
- #endif
+ #endif // VST_USE_ALTERNATIVE_MAGIC
p->dwPluginId2 = pEffect->uniqueID;
if ((pEffect->flags & effFlagsIsSynth) || (!pEffect->numInputs)) p->bIsInstrument = TRUE;
#ifdef VST_LOG
@@ -342,7 +343,7 @@
pEffect->numInputs, pEffect->numOutputs,
pEffect->numPrograms, pEffect->numParams,
pEffect->flags, pEffect->realQualities, pEffect->offQualities);
- #endif
+ #endif // VST_LOG
pEffect->dispatcher(pEffect, effClose, 0,0,0,0);
bOk = TRUE;
}
@@ -406,7 +407,7 @@
{
#ifdef VST_LOG
Log("Entry point not found!\n");
- #endif
+ #endif // VST_LOG
}
try {
@@ -420,7 +421,7 @@
{
#ifdef VST_LOG
Log("LoadLibrary(%s) failed!\n", pszDllPath);
- #endif
+ #endif // VST_LOG
}
return NULL;
}
@@ -753,7 +754,7 @@
//---from here VST 2.0 extension opcodes------------------------------------------------------
- // <value> is a filter which is currently ignored
+ // <value> is a filter which is currently ignored - DEPRECATED in VST 2.4
// Herman Seib only processes Midi events for plugs that call this. Keep in mind.
case audioMasterWantMidi: return 1;
// returns const VstTimeInfo* (or 0 if not supported)
@@ -761,43 +762,53 @@
case audioMasterGetTime: {
CVstPlugin* pVstPlugin = (CVstPlugin*)effect->resvd1;
- memset(&timeInfo, 0, sizeof(timeInfo));
+ MemsetZero(timeInfo);
timeInfo.sampleRate = CMainFrame::GetMainFrame()->GetSampleRate();
- if (pVstPlugin) {
+ if (pVstPlugin)
+ {
CSoundFile* pSndFile = pVstPlugin->GetSoundFile();
- if (pVstPlugin->IsSongPlaying()) {
+ if (pVstPlugin->IsSongPlaying())
+ {
timeInfo.flags |= kVstTransportPlaying;
timeInfo.samplePos = CMainFrame::GetMainFrame()->GetTotalSampleCount();
if (timeInfo.samplePos == 0) //samplePos=0 means we just started playing
- timeInfo.flags |= kVstTransportChanged;
- } else {
+ {
+ timeInfo.flags |= kVstTransportChanged;
+ }
+ } else
+ {
timeInfo.flags |= kVstTransportChanged; //just stopped.
timeInfo.samplePos = 0;
}
- if ((value & kVstNanosValid)) {
+ if ((value & kVstNanosValid))
+ {
timeInfo.flags |= kVstNanosValid;
timeInfo.nanoSeconds = pVstPlugin->GetTimeAtStartOfProcess();
}
- if ((value & kVstPpqPosValid) && pSndFile) {
+ if ((value & kVstPpqPosValid) && pSndFile)
+ {
timeInfo.flags |= kVstPpqPosValid;
- if (timeInfo.flags & kVstTransportPlaying) {
+ if (timeInfo.flags & kVstTransportPlaying)
+ {
timeInfo.ppqPos = (timeInfo.samplePos/timeInfo.sampleRate)*(pSndFile->GetCurrentBPM()/60.0);
- } else {
+ } else
+ {
timeInfo.ppqPos = 0;
}
}
- if ((value & kVstTempoValid) && pSndFile) {
+ if ((value & kVstTempoValid) && pSndFile)
+ {
timeInfo.tempo = pSndFile->GetCurrentBPM();
- if (timeInfo.tempo) {
+ if (timeInfo.tempo)
+ {
timeInfo.flags |= kVstTempoValid;
}
}
- if ((value & kVstTimeSigValid) && pSndFile) {
- timeInfo.flags |= kVstTimeSigValid;
- //timeInfo.timeSigNumerator = pSndFile->m_nCurrentRowsPerBeat;
- //timeInfo.timeSigDenominator = pSndFile->m_nCurrentRowsPerMeasure;
+ if ((value & kVstTimeSigValid) && pSndFile)
+ {
+ timeInfo.flags |= kVstTimeSigValid;
// Time signature. numerator = rows per beats / rows pear measure (should sound somewhat logical to you).
// the denominator is a bit more tricky, since it cannot be set explicitely. so we just assume quarters for now.
@@ -811,27 +822,31 @@
// We don't support plugs that send VSTEvents to the host
case audioMasterProcessEvents:
Log("VST plugin to host: Process Events\n");
- break;
+ break;
+ // DEPRECATED in VST 2.4
case audioMasterSetTime:
Log("VST plugin to host: Set Time\n");
break;
- // returns tempo (in bpm * 10000) at sample frame location passed in <value>
+ // returns tempo (in bpm * 10000) at sample frame location passed in <value> - DEPRECATED in VST 2.4
case audioMasterTempoAt:
//Screw it! Let's just return the tempo at this point in time (might be a bit wrong).
- if (effect->resvd1) {
+ if (effect->resvd1)
+ {
CSoundFile *pSndFile = ((CVstPlugin*)effect->resvd1)->GetSoundFile();
- if (pSndFile) {
- return pSndFile->GetCurrentBPM()*10000;
- } else {
- return 125*10000;
+ if (pSndFile)
+ {
+ return (VstInt32)(pSndFile->GetCurrentBPM() * 10000);
+ } else
+ {
+ return (VstInt32)(125 * 10000);
}
}
return 125*10000;
- // parameters
+ // parameters - DEPRECATED in VST 2.4
case audioMasterGetNumAutomatableParameters:
Log("VST plugin to host: Get Num Automatable Parameters\n");
break;
- // Apparently, this one is broken in VST SDK anyway.
+ // Apparently, this one is broken in VST SDK anyway. - DEPRECATED in VST 2.4
case audioMasterGetParameterQuantization:
Log("VST plugin to host: Audio Master Get Parameter Quantization\n");
break;
@@ -839,7 +854,7 @@
case audioMasterIOChanged:
Log("VST plugin to host: IOchanged\n");
break;
- // plug needs idle calls (outside its editor window)
+ // plug needs idle calls (outside its editor window) - DEPRECATED in VST 2.4
case audioMasterNeedIdle:
if (effect && effect->resvd1)
{
@@ -880,16 +895,16 @@
VstIntPtr latency = CMainFrame::GetMainFrame()->m_nBufferLength * (CMainFrame::GetMainFrame()->GetSampleRate()/1000L);
return latency;
}
- // input pin in <value> (-1: first to come), returns cEffect*
+ // input pin in <value> (-1: first to come), returns cEffect* - DEPRECATED in VST 2.4
case audioMasterGetPreviousPlug:
Log("VST plugin to host: Get Previous Plug\n");
break;
- // output pin in <value> (-1: first to come), returns cEffect*
+ // output pin in <value> (-1: first to come), returns cEffect* - DEPRECATED in VST 2.4
case audioMasterGetNextPlug:
Log("VST plugin to host: Get Next Plug\n");
break;
// realtime info
- // returns: 0: not supported, 1: replace, 2: accumulate
+ // returns: 0: not supported, 1: replace, 2: accumulate - DEPRECATED in VST 2.4 (replace is default)
case audioMasterWillReplaceOrAccumulate:
return 1; //we replace.
case audioMasterGetCurrentProcessLevel:
@@ -924,16 +939,16 @@
case audioMasterOfflineGetCurrentMetaPass:
Log("VST plugin to host: OfflineGetCurrentMetapass\n");
break;
- // for variable i/o, sample rate in <opt>
+ // for variable i/o, sample rate in <opt> - DEPRECATED in VST 2.4
case audioMasterSetOutputSampleRate:
Log("VST plugin to host: Set Output Sample Rate\n");
break;
- // result in ret
+ // result in ret - DEPRECATED in VST 2.4
case audioMasterGetOutputSpeakerArrangement:
Log("VST plugin to host: Get Output Speaker Arrangement\n");
break;
case audioMasterGetVendorString:
- strcpy((char*)ptr, s_szHostVendorString);
+ strcpy((char *) ptr, s_szHostVendorString);
//strcpy((char*)ptr,"Steinberg");
//return 0;
return true;
@@ -941,13 +956,13 @@
return s_nHostVendorVersion;
//return 7000;
case audioMasterGetProductString:
- strcpy((char*)ptr, s_szHostProductString);
+ strcpy((char *) ptr, s_szHostProductString);
//strcpy((char*)ptr,"Cubase VST");
//return 0;
return true;
case audioMasterVendorSpecific:
return 0;
- // void* in <ptr>, format not defined yet
+ // void* in <ptr>, format not defined yet - DEPRECATED in VST 2.4
case audioMasterSetIcon:
Log("VST plugin to host: Set Icon\n");
break;
@@ -978,11 +993,11 @@
//
case audioMasterGetLanguage:
return kVstLangEnglish;
- // returns platform specific ptr
+ // returns platform specific ptr - DEPRECATED in VST 2.4
case audioMasterOpenWindow:
Log("VST plugin to host: Open Window\n");
break;
- // close window, platform specific handle in <ptr>
+ // close window, platform specific handle in <ptr> - DEPRECATED in VST 2.4
case audioMasterCloseWindow:
Log("VST plugin to host: Close Window\n");
break;
@@ -1026,19 +1041,19 @@
case audioMasterCloseFileSelector:
return VstFileSelector(opcode == audioMasterCloseFileSelector, (VstFileSelect *)ptr, effect);
- // open an editor for audio (defined by XML text in ptr) - DEPRECATED
+ // open an editor for audio (defined by XML text in ptr) - DEPRECATED in VST 2.4
case audioMasterEditFile:
Log("VST plugin to host: Edit File\n");
break;
// get the native path of currently loading bank or project
- // (called from writeChunk) void* in <ptr> (char[2048], or sizeof(FSSpec)) - DEPRECATED
+ // (called from writeChunk) void* in <ptr> (char[2048], or sizeof(FSSpec)) - DEPRECATED in VST 2.4
case audioMasterGetChunkFile:
Log("VST plugin to host: Get Chunk File\n");
break;
//---from here VST 2.3 extension opcodes------------------------------------------------------
- // result a VstSpeakerArrangement in ret - DEPRECATED
+ // result a VstSpeakerArrangement in ret - DEPRECATED in VST 2.4
case audioMasterGetInputSpeakerArrangement:
Log("VST plugin to host: Get Input Speaker Arrangement\n");
break;
Modified: trunk/OpenMPT/mptrack/mptrack.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.vcproj 2011-03-23 22:40:37 UTC (rev 827)
+++ trunk/OpenMPT/mptrack/mptrack.vcproj 2011-03-24 20:05:01 UTC (rev 828)
@@ -259,90 +259,6 @@
RelativePath=".\KeyConfigDlg.cpp">
</File>
<File
- RelativePath="..\soundlib\Load_669.cpp">
- </File>
- <File
- RelativePath="..\Soundlib\load_amf.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_ams.cpp">
- </File>
- <File
- RelativePath="..\soundlib\load_dbm.cpp">
- </File>
- <File
- RelativePath="..\soundlib\load_dmf.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_dsm.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_far.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_gdm.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_imf.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_it.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_itp.cpp">
- </File>
- <File
- RelativePath="..\soundlib\load_j2b.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_mdl.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_med.cpp">
- </File>
- <File
- RelativePath="..\soundlib\load_mid.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_mo3.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_mod.cpp">
- </File>
- <File
- RelativePath="..\Soundlib\load_mt2.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_mtm.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_okt.cpp">
- </File>
- <File
- RelativePath="..\Soundlib\load_psm.cpp">
- </File>
- <File
- RelativePath="..\soundlib\load_ptm.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_s3m.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_stm.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_ult.cpp">
- </File>
- <File
- RelativePath="..\Soundlib\Load_umx.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_wav.cpp">
- </File>
- <File
- RelativePath="..\soundlib\Load_xm.cpp">
- </File>
- <File
RelativePath=".\mainbar.cpp">
</File>
<File
@@ -804,9 +720,6 @@
RelativePath=".\KeyConfigDlg.h">
</File>
<File
- RelativePath="..\soundlib\Loaders.h">
- </File>
- <File
RelativePath=".\mainbar.h">
</File>
<File
@@ -992,6 +905,97 @@
RelativePath=".\test\test.h">
</File>
</Filter>
+ <Filter
+ Name="Module Loaders"
+ Filter="">
+ <File
+ RelativePath="..\soundlib\Load_669.cpp">
+ </File>
+ <File
+ RelativePath="..\Soundlib\load_amf.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_ams.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\load_dbm.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\load_dmf.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_dsm.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_far.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_gdm.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_imf.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_it.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_itp.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\load_j2b.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_mdl.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_med.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\load_mid.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_mo3.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_mod.cpp">
+ </File>
+ <File
+ RelativePath="..\Soundlib\load_mt2.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_mtm.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_okt.cpp">
+ </File>
+ <File
+ RelativePath="..\Soundlib\load_psm.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\load_ptm.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_s3m.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_stm.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_ult.cpp">
+ </File>
+ <File
+ RelativePath="..\Soundlib\Load_umx.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_wav.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_xm.cpp">
+ </File>
+ <File
+ RelativePath="..\soundlib\Loaders.h">
+ </File>
+ </Filter>
<File
RelativePath=".\mptrack.reg">
</File>
Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2011-03-23 22:40:37 UTC (rev 827)
+++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2011-03-24 20:05:01 UTC (rev 828)
@@ -349,118 +349,6 @@
>
</File>
<File
- RelativePath="..\soundlib\Load_669.cpp"
- >
- </File>
- <File
- RelativePath="..\Soundlib\load_amf.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_ams.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\load_dbm.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\load_dmf.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_dsm.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_far.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_gdm.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_imf.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_it.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_itp.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\load_j2b.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_mdl.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_med.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\load_mid.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_mo3.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_mod.cpp"
- >
- </File>
- <File
- RelativePath="..\Soundlib\load_mt2.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_mtm.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_okt.cpp"
- >
- </File>
- <File
- RelativePath="..\Soundlib\load_psm.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\load_ptm.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_s3m.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_stm.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_ult.cpp"
- >
- </File>
- <File
- RelativePath="..\Soundlib\Load_umx.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_wav.cpp"
- >
- </File>
- <File
- RelativePath="..\soundlib\Load_xm.cpp"
- >
- </File>
- <File
RelativePath=".\mainbar.cpp"
>
</File>
@@ -1067,10 +955,6 @@
>
</File>
<File
- RelativePath="..\soundlib\Loaders.h"
- >
- </File>
- <File
RelativePath=".\mainbar.h"
>
</File>
@@ -1319,6 +1203,126 @@
>
</File>
</Filter>
+ <Filter
+ Name="Module Loaders"
+ >
+ <File
+ RelativePath="..\soundlib\Load_669.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\Soundlib\load_amf.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_ams.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\load_dbm.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\load_dmf.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_dsm.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_far.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_gdm.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_imf.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_it.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_itp.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\load_j2b.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_mdl.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_med.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\load_mid.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_mo3.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_mod.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\Soundlib\load_mt2.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_mtm.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_okt.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\Soundlib\load_psm.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\load_ptm.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_s3m.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_stm.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_ult.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\Soundlib\Load_umx.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_wav.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Load_xm.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\soundlib\Loaders.h"
+ >
+ </File>
+ </Filter>
<File
RelativePath=".\res\built-inTunings.tc"
>
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-03-23 22:40:37 UTC (rev 827)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-03-24 20:05:01 UTC (rev 828)
@@ -1703,7 +1703,7 @@
break;
case VOLCMD_OFFSET: //rewbs.volOff
- if (m_nTickCount == nStartTick)
+ if (m_nTickCount == nStartTick)
SampleOffset(nChn, vol<<3, bPorta);
break;
}
@@ -2079,23 +2079,17 @@
}
break;
- // Midi Controller (on first tick only)
- case CMD_MIDI:
- if(!(m_dwSongFlags & SONG_FIRSTTICK)) break;
+ // Midi Controller
+ case CMD_MIDI: // Midi Controller (on first tick only)
+ case CMD_SMOOTHMIDI: // Midi Controller (smooth, i.e. on every tick)
+
+ if((cmd == CMD_MIDI) && !(m_dwSongFlags & SONG_FIRSTTICK)) break;
if (param < 0x80)
- ProcessMidiMacro(nChn, &m_MidiCfg.szMidiSFXExt[pChn->nActiveMacro << 5], param);
+ ProcessMidiMacro(nChn, (cmd == CMD_SMOOTHMIDI), &m_MidiCfg.szMidiSFXExt[pChn->nActiveMacro << 5], param);
else
- ProcessMidiMacro(nChn, &m_MidiCfg.szMidiZXXExt[(param & 0x7F) << 5], 0);
+ ProcessMidiMacro(nChn, (cmd == CMD_SMOOTHMIDI), &m_MidiCfg.szMidiZXXExt[(param & 0x7F) << 5], 0);
break;
- // Midi Controller (smooth, i.e. on every tick)
- case CMD_SMOOTHMIDI:
- if (param < 0x80)
- ProcessSmoothMidiMacro(nChn, &m_MidiCfg.szMidiSFXExt[pChn->nActiveMacro << 5], param);
- else
- ProcessSmoothMidiMacro(nChn, &m_MidiCfg.szMidiZXXExt[(param & 0x7F) << 5], 0);
- break;
-
// IMF Commands
case CMD_NOTESLIDEUP:
NoteSlide(pChn, param, 1);
@@ -3017,41 +3011,53 @@
}
-void CSoundFile::ProcessMidiMacro(UINT nChn, LPCSTR pszMidiMacro, UINT param)
-//---------------------------------------------------------------------------
+// Process a Midi Macro.
+// Parameters:
+// [in] nChn: Mod channel to apply macro on
+// [in] isSmooth: If true, internal macros are interpolated between two rows
+// [in] pszMidiMacro: Actual Midi Macro
+// [in] param: Parameter for parametric macros
+void CSoundFile::ProcessMidiMacro(UINT nChn, bool isSmooth, LPCSTR pszMidiMacro, UINT param)
+//------------------------------------------------------------------------------------------
{
MODCHANNEL *pChn = &Chn[nChn];
- DWORD dwMacro = (*((LPDWORD)pszMidiMacro)) & MACRO_MASK;
+ DWORD dwMacro = (*((DWORD *)pszMidiMacro)) & MACRO_MASK;
int nInternalCode;
// Not Internal Device ?
if (dwMacro != MACRO_INTERNAL && dwMacro != MACRO_INTERNALEX)
{
+ // we don't cater for external devices at tick resolution.
+ if(isSmooth && !(m_dwSongFlags & SONG_FIRSTTICK))
+ {
+ return;
+ }
+
UINT pos = 0, nNib = 0, nBytes = 0;
DWORD dwMidiCode = 0, dwByteCode = 0;
- while (pos+6 <= 32)
+ while (pos + 6 <= 32)
{
- CHAR cData = pszMidiMacro[pos++];
+ const CHAR cData = pszMidiMacro[pos++];
if (!cData) break;
- if ((cData >= '0') && (cData <= '9')) { dwByteCode = (dwByteCode<<4) | (cData-'0'); nNib++; } else
- if ((cData >= 'A') && (cData <= 'F')) { dwByteCode = (dwByteCode<<4) | (cData-'A'+10); nNib++; } else
- if ((cData >= 'a') && (cData <= 'f')) { dwByteCode = (dwByteCode<<4) | (cData-'a'+10); nNib++; } else
- if ((cData == 'z') || (cData == 'Z')) { dwByteCode = param & 0x7f; nNib = 2; } else
+ if ((cData >= '0') && (cData <= '9')) { dwByteCode = (dwByteCode << 4) | (cData - '0'); nNib++; } else
+ if ((cData >= 'A') && (cData <= 'F')) { dwByteCode = (dwByteCode << 4) | (cData - 'A' + 10); nNib++; } else
+ if ((cData >= 'a') && (cData <= 'f')) { dwByteCode = (dwByteCode << 4) | (cData - 'a' + 10); nNib++; } else
+ if ((cData == 'z') || (cData == 'Z')) { dwByteCode = param & 0x7F; nNib = 2; } else
if ((cData == 'x') || (cData == 'X')) { dwByteCode = param & 0x70; nNib = 2; } else
- if ((cData == 'y') || (cData == 'Y')) { dwByteCode = (param & 0x0f)<<3; nNib = 2; }
- if ((cData == 'k') || (cData == 'K')) { dwByteCode = (dwByteCode<<4) | GetBestMidiChan(pChn); nNib++; }
+ if ((cData == 'y') || (cData == 'Y')) { dwByteCode = (param & 0x0F) << 3; nNib = 2; }
+ if ((cData == 'k') || (cData == 'K')) { dwByteCode = (dwByteCode << 4) | GetBestMidiChan(pChn); nNib++; }
if (nNib >= 2)
{
nNib = 0;
- dwMidiCode |= dwByteCode << (nBytes*8);
+ dwMidiCode |= dwByteCode << (nBytes * 8);
dwByteCode = 0;
nBytes++;
if (nBytes >= 3)
{
- UINT nMasterCh = (nChn < m_nChannels) ? nChn+1 : pChn->nMasterChn;
+ UINT nMasterCh = (nChn < m_nChannels) ? nChn + 1 : pChn->nMasterChn;
if ((nMasterCh) && (nMasterCh <= m_nChannels))
{
// -> CODE#0015
@@ -3059,9 +3065,10 @@
UINT nPlug = GetBestPlugin(nChn, PRIORITISE_CHANNEL, EVEN_IF_MUTED);
if(pChn->dwFlags & CHN_NOFX) nPlug = 0;
// -! NEW_FEATURE#0015
- if ((nPlug) && (nPlug <= MAX_MIXPLUGINS)) {
- IMixPlugin *pPlugin = m_MixPlugins[nPlug-1].pMixPlugin;
- if ((pPlugin) && (m_MixPlugins[nPlug-1].pMixState))
+ if ((nPlug) && (nPlug <= MAX_MIXPLUGINS))
+ {
+ IMixPlugin *pPlugin = m_MixPlugins[nPlug - 1].pMixPlugin;
+ if ((pPlugin) && (m_MixPlugins[nPlug - 1].pMixState))
{
pPlugin->MidiSend(dwMidiCode);
}
@@ -3078,10 +3085,11 @@
}
// Internal device
- //HACK:
const bool extendedParam = (dwMacro == MACRO_INTERNALEX);
- pszMidiMacro += 4;
+ pszMidiMacro += 4; // skip the F0.F0 part of the macro
+ // Determine which internal device is called; every internal code looks like F0.F0.yy.xx,
+ // where yy is the "device" (cutoff, resonance, plugin parameter, etc.) and xx is the value.
nInternalCode = -256;
if ((pszMidiMacro[0] >= '0') && (pszMidiMacro[0] <= '9')) nInternalCode = (pszMidiMacro[0] - '0') << 4; else
if ((pszMidiMacro[0] >= 'A') && (pszMidiMacro[0] <= 'F')) nInternalCode = (pszMidiMacro[0] - 'A' + 0x0A) << 4;
@@ -3092,17 +3100,21 @@
{
CHAR cData1 = pszMidiMacro[2];
DWORD dwParam = 0;
+
if ((cData1 == 'z') || (cData1 == 'Z'))
{
+ // parametric macro
dwParam = param;
} else
{
+ // fixed macro
CHAR cData2 = pszMidiMacro[3];
if ((cData1 >= '0') && (cData1 <= '9')) dwParam += (cData1 - '0') << 4; else
if ((cData1 >= 'A') && (cData1 <= 'F')) dwParam += (cData1 - 'A' + 0x0A) << 4;
if ((cData2 >= '0') && (cData2 <= '9')) dwParam += (cData2 - '0'); else
if ((cData2 >= 'A') && (cData2 <= 'F')) dwParam += (cData2 - 'A' + 0x0A);
}
+
switch(nInternalCode)
{
// F0.F0.00.xx: Set CutOff
@@ -3111,16 +3123,30 @@
int oldcutoff = pChn->nCutOff;
if (dwParam < 0x80)
{
- pChn->nCutOff = dwParam;
+ if(!isSmooth)
+ {
+ pChn->nCutOff = dwParam;
+ } else
+ {
+ // on the first tick only, calculate step
+ if(m_dwSongFlags & SONG_FIRSTTICK)
+ {
+ pChn->m_nPlugInitialParamValue = pChn->nCutOff;
+ // (dwParam & 0x7F) extracts the actual value that we're going to pass
+ pChn->m_nPlugParamValueStep = (float)((int)dwParam - pChn->m_nPlugInitialParamValue) / (float)m_nMusicSpeed;
+ }
+ //update param on all ticks
+ pChn->nCutOff = (BYTE) (pChn->m_nPlugInitialParamValue + (m_nTickCount + 1 ) *pChn->m_nPlugParamValueStep + 0.5);
+ }
pChn->nRestoreCutoffOnNewNote = 0;
}
- #ifndef NO_FILTER
+#ifndef NO_FILTER
oldcutoff -= pChn->nCutOff;
if (oldcutoff < 0) oldcutoff = -oldcutoff;
if ((pChn->nVolume > 0) || (oldcutoff < 0x10)
- || (!(pChn->dwFlags & CHN_FILTER)) || (!(pChn->nLeftVol|pChn->nRightVol)))
+ || (!(pChn->dwFlags & CHN_FILTER)) || (!(pChn->nLeftVol|pChn->nRightVol)))
SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true);
- #endif // NO_FILTER
+#endif // NO_FILTER
}
break;
@@ -3129,191 +3155,68 @@
if (dwParam < 0x80)
{
pChn->nRestoreResonanceOnNewNote = 0;
- pChn->nResonance = dwParam;
- }
-
- #ifndef NO_FILTER
- SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true);
- #endif // NO_FILTER
- break;
-
- // F0.F0.02.xx: Set filter mode
- case 0x02:
- if (dwParam < 0x20)
- {
- pChn->nFilterMode = (dwParam>>4);
- #ifndef NO_FILTER
- SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true);
- #endif // NO_FILTER
- }
- break;
-
- // F0.F0.03.xx: Set plug dry/wet
- case 0x03:
- {
- UINT nPlug = GetBestPlugin(nChn, PRIORITISE_CHANNEL, EVEN_IF_MUTED);
- if ((nPlug) && (nPlug <= MAX_MIXPLUGINS)) {
- if (dwParam < 0x80)
- m_MixPlugins[nPlug-1].fDryRatio = 1.0-(static_cast<float>(dwParam)/127.0f);
- }
- }
- break;
-
-
- // F0.F0.{80|n}.xx: Set VST effect parameter n to xx
- default:
- if (nInternalCode & 0x80 || extendedParam)
- {
- UINT nPlug = GetBestPlugin(nChn, PRIORITISE_CHANNEL, EVEN_IF_MUTED);
- if ((nPlug) && (nPlug <= MAX_MIXPLUGINS))
+ if(!isSmooth)
{
- IMixPlugin *pPlugin = m_MixPlugins[nPlug-1].pMixPlugin;
- if ((pPlugin) && (m_MixPlugins[nPlug-1].pMixState))
+ pChn->nResonance = dwParam;
+ } else
+ {
+ // on the first tick only, calculate step
+ if(m_dwSongFlags & SONG_FIRSTTICK)
{
- pPlugin->SetZxxParameter(extendedParam?(0x80+nInternalCode):(nInternalCode&0x7F), dwParam & 0x7F);
+ pChn->m_nPlugInitialParamValue = pChn->nResonance;
+ // (dwParam & 0x7F) extracts the actual value that we're going to pass
+ pChn->m_nPlugParamValueStep = (float)((int)dwParam - pChn->m_nPlugInitialParamValue) / (float)m_nMusicSpeed;
}
+ //update param on all ticks
+ pChn->nResonance = (BYTE) (pChn->m_nPlugInitialParamValue + (m_nTickCount + 1) * pChn->m_nPlugParamValueStep + 0.5);
}
}
-
- } // end switch
- } // end internal device
-
-}
-
-//rewbs.smoothVST: begin tick resolution handling.
-void CSoundFile::ProcessSmoothMidiMacro(UINT nChn, LPCSTR pszMidiMacro, UINT param)
-//---------------------------------------------------------------------------
-{
- MODCHANNEL *pChn = &Chn[nChn];
- DWORD dwMacro = (*((LPDWORD)pszMidiMacro)) & MACRO_MASK;
- int nInternalCode;
- CHAR cData1; // rewbs.smoothVST:
- DWORD dwParam; // increased scope to fuction.
-
- if (dwMacro != MACRO_INTERNAL && dwMacro != MACRO_INTERNALEX)
- {
- // we don't cater for external devices at tick resolution.
- if(m_dwSongFlags & SONG_FIRSTTICK) {
- ProcessMidiMacro(nChn, pszMidiMacro, param);
- }
- return;
- }
-
- //HACK:
- const bool extendedParam = (dwMacro == MACRO_INTERNALEX);
-
- // not sure what we're doing here; some sort of info gathering from the macros
- pszMidiMacro += 4;
- nInternalCode = -256;
- if ((pszMidiMacro[0] >= '0') && (pszMidiMacro[0] <= '9')) nInternalCode = (pszMidiMacro[0] - '0') << 4; else
- if ((pszMidiMacro[0] >= 'A') && (pszMidiMacro[0] <= 'F')) nInternalCode = (pszMidiMacro[0] - 'A' + 0x0A) << 4;
- if ((pszMidiMacro[1] >= '0') && (pszMidiMacro[1] <= '9')) nInternalCode += (pszMidiMacro[1] - '0'); else
- if ((pszMidiMacro[1] >= 'A') && (pszMidiMacro[1] <= 'F')) nInternalCode += (pszMidiMacro[1] - 'A' + 0x0A);
-
- if (nInternalCode < 0) // not good plugin param macro. (?)
- return;
-
- cData1 = pszMidiMacro[2];
- dwParam = 0;
-
- if ((cData1 == 'z') || (cData1 == 'Z')) //parametric macro
- {
- dwParam = param;
- } else //fixed macro
- {
- CHAR cData2 = pszMidiMacro[3];
- if ((cData1 >= '0') && (cData1 <= '9')) dwParam += (cData1 - '0') << 4; else
- if ((cData1 >= 'A') && (cData1 <= 'F')) dwParam += (cData1 - 'A' + 0x0A) << 4;
- if ((cData2 >= '0') && (cData2 <= '9')) dwParam += (cData2 - '0'); else
- if ((cData2 >= 'A') && (cData2 <= 'F')) dwParam += (cData2 - 'A' + 0x0A);
- }
-
- switch(nInternalCode)
- {
- // F0.F0.00.xx: Set CutOff
- case 0x00:
- {
- int oldcutoff = pChn->nCutOff;
- if (dwParam < 0x80)
- {
- // on the fist tick only, calculate step
- if (m_dwSongFlags & SONG_FIRSTTICK)
- {
- pChn->m_nPlugInitialParamValue = pChn->nCutOff;
- // (dwParam & 0x7F) extracts the actual value that we're going to pass
- pChn->m_nPlugParamValueStep = (float)((int)dwParam-pChn->m_nPlugInitialParamValue)/(float)m_nMusicSpeed;
- }
- //update param on all ticks
- pChn->nCutOff = (BYTE) (pChn->m_nPlugInitialParamValue + (m_nTickCount+1)*pChn->m_nPlugParamValueStep + 0.5);
- pChn->nRestoreCutoffOnNewNote = 0;
- }
- #ifndef NO_FILTER
- oldcutoff -= pChn->nCutOff;
- if (oldcutoff < 0) oldcutoff = -oldcutoff;
- if ((pChn->nVolume > 0) || (oldcutoff < 0x10)
- || (!(pChn->dwFlags & CHN_FILTER)) || (!(pChn->nLeftVol|pChn->nRightVol)))
- SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true);
- #endif // NO_FILTER
- } break;
-
- // F0.F0.01.xx: Set Resonance
- case 0x01:
- if (dwParam < 0x80)
- {
- // on the fist tick only, calculate step
- if (m_dwSongFlags & SONG_FIRSTTICK)
- {
- pChn->m_nPlugInitialParamValue = pChn->nResonance;
- // (dwParam & 0x7F) extracts the actual value that we're going to pass
- pChn->m_nPlugParamValueStep = (float)((int)dwParam-pChn->m_nPlugInitialParamValue)/(float)m_nMusicSpeed;
- }
- //update param on all ticks
- pChn->nResonance = (BYTE) (pChn->m_nPlugInitialParamValue + (m_nTickCount+1)*pChn->m_nPlugParamValueStep + 0.5);
- pChn->nRestoreResonanceOnNewNote = 0;
- #ifndef NO_FILTER
- SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true);
- #endif // NO_FILTER
- }
-
+
+#ifndef NO_FILTER
+ SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true);
+#endif // NO_FILTER
break;
- // F0.F0.02.xx: Set filter mode
+ // F0.F0.02.xx: Set filter mode (high nibble determines filter mode)
case 0x02:
if (dwParam < 0x20)
{
- pChn->nFilterMode = (dwParam>>4);
- #ifndef NO_FILTER
+ pChn->nFilterMode = (dwParam >> 4);
+#ifndef NO_FILTER
SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true);
- #endif // NO_FILTER
+#endif // NO_FILTER
}
break;
// F0.F0.03.xx: Set plug dry/wet
case 0x03:
{
- UINT nPlug = GetBestPlugin(nChn, PRIORITISE_CHANNEL, EVEN_IF_MUTED);
- if ((nPlug) && (nPlug <= MAX_MIXPLUGINS)) {
- // on the fist tick only, calculate step
- if (m_dwSongFlags & SONG_FIRSTTICK)
+ const UINT nPlug = GetBestPlugin(nChn, PRIORITISE_CHANNEL, EVEN_IF_MUTED);
+ if ((nPlug) && (nPlug <= MAX_MIXPLUGINS) && dwParam < 0x80)
+ {
+ if(!isSmooth)
{
- pChn->m_nPlugInitialParamValue = m_MixPlugins[nPlug-1].fDryRatio;
- // (dwParam & 0x7F) extracts the actual value that we're going to pass
- pChn->m_nPlugParamValueStep = ((1-((float)(dwParam)/127.0f))-pChn->m_nPlugInitialParamValue)/(float)m_nMusicSpeed;
+ m_MixPlugins[nPlug - 1].fDryRatio = 1.0 - (static_cast<float>(dwParam) / 127.0f);
+ } else
+ {
+ // on the first tick only, calculate step
+ if(m_dwSongFlags & SONG_FIRSTTICK)
+ {
+ pChn->m_nPlugInitialParamValue = m_MixPlugins[nPlug - 1].fDryRatio;
+ // (dwParam & 0x7F) extracts the actual value that we're going to pass
+ pChn->m_nPlugParamValueStep = ((1 - ((float)(dwParam) / 127.0f)) - pChn->m_nPlugInitialParamValue) / (float)m_nMusicSpeed;
+ }
+ //update param on all ticks
+ m_MixPlugins[nPlug - 1].fDryRatio = pChn->m_nPlugInitialParamValue + (float)(m_nTickCount + 1) * pChn->m_nPlugParamValueStep;
}
- //update param on all ticks
- IMixPlugin *pPlugin = m_MixPlugins[nPlug-1].pMixPlugin;
- if ((pPlugin) && (m_MixPlugins[nPlug-1].pMixState)) {
- m_MixPlugins[nPlug-1].fDryRatio = pChn->m_nPlugInitialParamValue+(float)(m_nTickCount+1)*pChn->m_nPlugParamValueStep;
- }
-
}
}
break;
-
+
// F0.F0.{80|n}.xx: Set VST effect parameter n to xx
default:
- if (nInternalCode & 0x80 || extendedParam)
+ if (nInternalCode & 0x80 || extendedParam)
{
UINT nPlug = GetBestPlugin(nChn, PRIORITISE_CHANNEL, EVEN_IF_MUTED);
if ((nPlug) && (nPlug <= MAX_MIXPLUGINS))
@@ -3321,24 +3224,31 @@
IMixPlugin *pPlugin = m_MixPlugins[nPlug-1].pMixPlugin;
if ((pPlugin) && (m_MixPlugins[nPlug-1].pMixState))
{
- // on the fist tick only, calculate step
- if (m_dwSongFlags & SONG_FIRSTTICK)
+ if(!isSmooth)
{
- pChn->m_nPlugInitialParamValue = pPlugin->GetZxxParameter(extendedParam?(0x80+nInternalCode):(nInternalCode&0x7F));
- // (dwParam & 0x7F) extracts the actual value that we're going to pass
- pChn->m_nPlugParamValueStep = ((int)(dwParam & 0x7F)-pChn->m_nPlugInitialParamValue)/(float)m_nMusicSpeed;
+ pPlugin->SetZxxParameter(extendedParam ? (0x80 + nInternalCode) : (nInternalCode & 0x7F), dwParam & 0x7F);
+ } else
+ {
+ // on the first tick only, calculate step
+ if(m_dwSongFlags & SONG_FIRSTTICK)
+ {
+ pChn->m_nPlugInitialParamValue = pPlugin->GetZxxParameter(extendedParam ? (0x80 + nInternalCode) : (nInternalCode & 0x7F));
+ // (dwParam & 0x7F) extracts the actual value that we're going to pass
+ pChn->m_nPlugParamValueStep = ((int)(dwParam & 0x7F) - pChn->m_nPlugInitialParamValue) / (float)m_nMusicSpeed;
+ }
+ //update param on all ticks
+ pPlugin->SetZxxParameter(extendedParam ? (0x80 + nInternalCode) : (nInternalCode & 0x7F), (UINT) (pChn->m_nPlugInitialParamValue + (m_nTickCount + 1) * pChn->m_nPlugParamValueStep + 0.5));
}
- //update param on all ticks
- pPlugin->SetZxxParameter(extendedParam?(0x80+nInternalCode):(nInternalCode&0x7F), (UINT) (pChn->m_nPlugInitialParamValue + (m_nTickCount+1)*pChn->m_nPlugParamValueStep + 0.5));
}
}
+ }
- }
- } // end switch
+ } // end switch
+ } // end internal device
}
-//end rewbs.smoothVST
+
//rewbs.volOffset: moved offset code to own method as it will be used in several places now
void CSoundFile::SampleOffset(UINT nChn, UINT param, bool bPorta)
//---------------------------------------------------------------
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2011-03-23 22:40:37 UTC (rev 827)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2011-03-24 20:05:01 UTC (rev 828)
@@ -911,8 +911,7 @@
void ExtendedS3MCommands(UINT nChn, UINT param);
void ExtendedChannelEffect(MODCHANNEL *, UINT param);
inline void InvertLoop(MODCHANNEL* pChn);
- void ProcessMidiMacro(UINT nChn, LPCSTR pszMidiMacro, UINT param=0);
- void ProcessSmoothMidiMacro(UINT nChn, LPCSTR pszMidiMacro, UINT param=0); //rewbs.smoothVST
+ void ProcessMidiMacro(UINT nChn, bool isSmooth, LPCSTR pszMidiMacro, UINT param = 0);
void SetupChannelFilter(MODCHANNEL *pChn, bool bReset, int flt_modifier = 256) const;
// Low-Level effect processing
void DoFreqSlide(MODCHANNEL *pChn, LONG nFreqSlide);
Modified: trunk/OpenMPT/soundlib/mod_specifications.cpp
===================================================================
--- trunk/OpenMPT/soundlib/mod_specifications.cpp 2011-03-23 22:40:37 UTC (rev 827)
+++ trunk/OpenMPT/soundlib/mod_specifications.cpp 2011-03-24 20:05:01 UTC (rev 828)
@@ -38,4 +38,16 @@
return true;
}
+char CModSpecifications::GetVolEffectLetter(MODCOMMAND::VOLCMD volcmd) const
+//--------------------------------------------------------------------------
+{
+ if(volcmd >= MAX_VOLCMDS) return '?';
+ return volcommands[volcmd];
+}
+char CModSpecifications::GetEffectLetter(MODCOMMAND::COMMAND cmd) const
+//---------------------------------------------------------------------
+{
+ if(cmd >= MAX_EFFECTS) return '?';
+ return commands[cmd];
+}
Modified: trunk/OpenMPT/soundlib/mod_specifications.h
===================================================================
--- trunk/OpenMPT/soundlib/mod_specifications.h 2011-03-23 22:40:37 UTC (rev 827)
+++ trunk/OpenMPT/soundlib/mod_specifications.h 2011-03-24 20:05:01 UTC (rev 828)
@@ -14,6 +14,9 @@
bool HasNote(MODCOMMAND::NOTE note) const;
bool HasVolCommand(MODCOMMAND::VOLCMD volcmd) const;
bool HasCommand(MODCOMMAND::COMMAND cmd) const;
+ // Return corresponding effect letter for this format
+ char GetEffectLetter(MODCOMMAND::COMMAND cmd) const;
+ char GetVolEffectLetter(MODCOMMAND::VOLCMD cmd) const;
// NOTE: If changing order, update all initializations below.
char fileExtension[6]; // File extension without dot.
@@ -64,7 +67,7 @@
-savefile format and GUI methods can handle new values(might not be a small task :).
*/
"mptm", // File extension
- 1, // Minimum note index
+ NOTE_MIN, // Minimum note index
NOTE_MAX, // Maximum note index
true, // Has notecut.
true, // Has noteoff.
@@ -383,7 +386,7 @@
// TODO: Set correct values.
"it", // File extension
1, // Minimum note index
- NOTE_MAX, // Maximum note index
+ 120, // Maximum note index
true, // Has notecut.
true, // Has noteoff.
true, // Has notefade.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|