From: <re...@us...> - 2010-03-22 20:18:00
|
Revision: 544 http://modplug.svn.sourceforge.net/modplug/?rev=544&view=rev Author: rewbs Date: 2010-03-22 20:17:53 +0000 (Mon, 22 Mar 2010) Log Message: ----------- [Fix] Effect visualizer is now aware of PC notes (bug 3836). [Fix] Context menu command "Change Plugin" for PC notes now works when the PC note has a blank plugin (instrument) field. Modified Paths: -------------- trunk/OpenMPT/mptrack/EffectVis.cpp trunk/OpenMPT/mptrack/EffectVis.h trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/packageTemplate/extraKeymaps/UK_mpt_it2_hybrid_(rewbs).mkb Added Paths: ----------- trunk/OpenMPT/mptrack/res/vispcnode.bmp Modified: trunk/OpenMPT/mptrack/EffectVis.cpp =================================================================== --- trunk/OpenMPT/mptrack/EffectVis.cpp 2010-03-21 22:07:22 UTC (rev 543) +++ trunk/OpenMPT/mptrack/EffectVis.cpp 2010-03-22 20:17:53 UTC (rev 544) @@ -25,20 +25,22 @@ IMPLEMENT_DYNAMIC(CEffectVis, CDialog) CEffectVis::CEffectVis(CViewPattern *pViewPattern, UINT startRow, UINT endRow, UINT nchn, CModDoc* pModDoc, UINT pat) - //: CDialog(CEffectVis::IDD, pParent) { m_pViewPattern = pViewPattern; m_dwStatus = 0x00; m_nDragItem = -1; m_brushBlack.CreateSolidBrush(RGB(0, 0, 0)); m_boolForceRedraw = TRUE; + m_pModDoc = pModDoc; m_nRowToErase = -1; m_nParamToErase = -1; m_nLastDrawnRow = -1; + m_nLastDrawnY = -1; m_nOldPlayPos = -1; - m_nFillEffect=0; - m_nAction=kAction_Overwrite; //Overwrite + m_nFillEffect = m_pModDoc->GetIndexFromEffect(CMD_SMOOTHMIDI, 0); + m_nAction=kAction_OverwriteFX; + m_templatePCNote.Set(NOTE_PCS, 1, 0, 0); UpdateSelection(startRow, endRow, nchn, pModDoc, pat); } @@ -51,16 +53,9 @@ ON_WM_MOUSEMOVE() ON_WM_RBUTTONDOWN() ON_WM_RBUTTONUP() -// ON_WM_CHAR() -// ON_WM_KEYDOWN() -// ON_WM_KEYUP() -// ON_WM_MBUTTONDOWN() //{{AFX_MSG_MAP(CEffectVis) ON_COMMAND(ID_EDIT_UNDO, OnEditUndo) //}}AFX_MSG_MAP -//ON_STN_CLICKED(IDC_VISSTATUS, OnStnClickedVisstatus) -//ON_EN_CHANGE(IDC_VISSTATUS, OnEnChangeVisstatus) - ON_COMMAND(IDC_VISFILLBLANKS, OnFillBlanksCheck) ON_CBN_SELCHANGE(IDC_VISACTION, OnActionChanged) ON_CBN_SELCHANGE(IDC_VISEFFECTLIST, OnEffectChanged) END_MESSAGE_MAP() @@ -71,19 +66,14 @@ DDX_Control(pDX, IDC_VISSTATUS, m_edVisStatus); DDX_Control(pDX, IDC_VISEFFECTLIST, m_cmbEffectList); DDX_Control(pDX, IDC_VISACTION, m_cmbActionList); - DDX_Control(pDX, IDC_VISFILLBLANKS, m_btnFillCheck); } -void CEffectVis::OnFillBlanksCheck() -{ - m_bFillCheck = IsDlgButtonChecked(IDC_VISFILLBLANKS); -} - - void CEffectVis::OnActionChanged() { m_nAction = m_cmbActionList.GetItemData(m_cmbActionList.GetCurSel()); - if (m_nAction == (UINT)kAction_Preserve) + if (m_nAction == (UINT)kAction_FillPC + || m_nAction == (UINT)kAction_OverwritePC + || m_nAction == (UINT)kAction_Preserve) m_cmbEffectList.EnableWindow(FALSE); else m_cmbEffectList.EnableWindow(TRUE); @@ -106,21 +96,54 @@ } -BYTE CEffectVis::GetParam(UINT row) -{ MODCOMMAND *pcmd = m_pSndFile->Patterns[m_nPattern]; +uint16 CEffectVis::GetParam(UINT row) +{ + MODCOMMAND *pcmd = m_pSndFile->Patterns[m_nPattern]; + uint16 paramValue = 0; + if (pcmd) - return pcmd[row*m_pSndFile->m_nChannels + m_nChan].param; - else - return 0; + { + MODCOMMAND cmd = pcmd[row*m_pSndFile->m_nChannels + m_nChan]; + if (cmd.IsPcNote()) + { + paramValue = cmd.GetValueEffectCol(); + } + else + { + paramValue = cmd.param; + } + } + + return paramValue; } -void CEffectVis::SetParam(UINT row, BYTE param) +// Sets a row's param value based on the vertical cursor position. +// Sets either plain pattern effect parameter or PC note parameter +// as appropriate, depending on contents of row. +void CEffectVis::SetParamFromY(UINT row, long y) { MODCOMMAND *pcmd = m_pSndFile->Patterns[m_nPattern]; - BEGIN_CRITICAL(); - if (pcmd) - pcmd[row*m_pSndFile->m_nChannels + m_nChan].param = param; - END_CRITICAL(); + if (!pcmd) { + return; + } + + int offset = row*m_pSndFile->m_nChannels + m_nChan; + if (IsPcNote(row)) + { + uint16 param = ScreenYToPCParam(y); + BEGIN_CRITICAL(); + pcmd[offset].SetValueEffectCol(param); + END_CRITICAL(); + } + else + { + int param = ScreenYToFXParam(y); + // Cap the parameter value as appropriate, based on effect type (e.g. Zxx gets capped to [0x00,0x7F]) + m_pModDoc->GetEffectFromIndex(m_pModDoc->GetIndexFromEffect(pcmd[offset].command, param), param); + BEGIN_CRITICAL(); + pcmd[offset].param = static_cast<BYTE>(param); + END_CRITICAL(); + } } @@ -133,12 +156,21 @@ return 0; } -void CEffectVis::SetCommand(UINT row, BYTE cmd) +void CEffectVis::SetCommand(UINT row, BYTE command) { MODCOMMAND *pcmd = m_pSndFile->Patterns[m_nPattern]; BEGIN_CRITICAL(); - if (pcmd) - pcmd[row*m_pSndFile->m_nChannels + m_nChan].command = cmd; + if (pcmd) { + int offset = row*m_pSndFile->m_nChannels + m_nChan; + if (pcmd[offset].IsPcNote()) { + // Clear PC note + pcmd[offset].note = 0; + pcmd[offset].instr = 0; + pcmd[offset].volcmd = 0; + pcmd[offset].vol = 0; + } + pcmd[offset].command = command; + } END_CRITICAL(); } @@ -149,24 +181,66 @@ return -1; } -int CEffectVis::ParamToScreenY(BYTE param) + +int CEffectVis::RowToScreenY(UINT row) { + MODCOMMAND *pcmd = m_pSndFile->Patterns[m_nPattern]; + int screenY = -1; + + if (pcmd) + { + MODCOMMAND cmd = pcmd[row*m_pSndFile->m_nChannels + m_nChan]; + if (cmd.IsPcNote()) + { + uint16 paramValue = cmd.GetValueEffectCol(); + screenY = PCParamToScreenY(paramValue); + } + else + { + uint16 paramValue = cmd.param; + screenY = FXParamToScreenY(paramValue); + } + } + + return screenY; +} + +int CEffectVis::FXParamToScreenY(uint16 param) +{ if ((param >= 0x00) || (param <= 0xFF)) - return (int) (m_rcDraw.bottom - param*m_pixelsPerParam + 0.5); + return (int) (m_rcDraw.bottom - param*m_pixelsPerFXParam + 0.5); return -1; } -BYTE CEffectVis::ScreenYToParam(int y) +int CEffectVis::PCParamToScreenY(uint16 param) { - if (y<=ParamToScreenY(0xFF)) + if ((param >= 0x00) || (param <= MODCOMMAND::maxColumnValue)) + return (int) (m_rcDraw.bottom - param*m_pixelsPerPCParam + 0.5); + return -1; +} + +BYTE CEffectVis::ScreenYToFXParam(int y) +{ + if (y<=FXParamToScreenY(0xFF)) return 0xFF; - if (y>=ParamToScreenY(0x00)) + if (y>=FXParamToScreenY(0x00)) return 0x00; - return (BYTE)((m_rcDraw.bottom-y)/m_pixelsPerParam+0.5); + return (BYTE)((m_rcDraw.bottom-y)/m_pixelsPerFXParam+0.5); } +uint16 CEffectVis::ScreenYToPCParam(int y) +{ + if (y<=PCParamToScreenY(MODCOMMAND::maxColumnValue)) + return MODCOMMAND::maxColumnValue; + + if (y>=PCParamToScreenY(0x00)) + return 0x00; + + return (uint16)((m_rcDraw.bottom-y)/m_pixelsPerPCParam+0.5); +} + UINT CEffectVis::ScreenXToRow(int x) { if (x<=RowToScreenX(m_startRow)) @@ -184,14 +258,14 @@ if (m_pViewPattern) { m_pViewPattern->m_pEffectVis = NULL; - //m_pViewPattern = NULL; } } void CEffectVis::DrawGrid() { - //Lots of space for opti here. + // Lots of room for optimisation here. + // Draw vertical grid lines for (UINT row=m_startRow; row<=m_endRow; row++) { if (row % CMainFrame::m_nRowSpacing == 0) @@ -204,35 +278,31 @@ int x1 = RowToScreenX(row); m_dcGrid.MoveTo(x1, m_rcDraw.top); m_dcGrid.LineTo(x1, m_rcDraw.bottom); - //::DeletePen(CMainFrame::penScratch); } - - for (UINT i=0; i<256; i+=64) + // Draw horizontal grid lines + const UINT numHorizontalLines = 4; + for (UINT i=0; i<numHorizontalLines; i++) { - switch (i) + switch (i%4) { case 0: CMainFrame::penScratch = CMainFrame::penGray00; break; - case 64: CMainFrame::penScratch = CMainFrame::penGray40; break; - case 128: CMainFrame::penScratch = CMainFrame::penGray80; break; - case 192: CMainFrame::penScratch = CMainFrame::penGraycc; break; + case 1: CMainFrame::penScratch = CMainFrame::penGray40; break; + case 2: CMainFrame::penScratch = CMainFrame::penGray80; break; + case 3: CMainFrame::penScratch = CMainFrame::penGraycc; break; } m_dcGrid.SelectObject(CMainFrame::penScratch); - int y1 = ParamToScreenY((BYTE)i); + int y1 = m_rcDraw.bottom/numHorizontalLines * i; m_dcGrid.MoveTo(m_rcDraw.left+INNERLEFTBORDER, y1); m_dcGrid.LineTo(m_rcDraw.right-INNERRIGHTBORDER, y1); - //::DeletePen(CMainFrame::penScratch); } } void CEffectVis::SetPlayCursor(UINT nPat, UINT nRow) { - //TEMP: -// ::FillRect(m_dcPlayPos.m_hDC, &m_rcDraw, m_brushBlack); - int x1; //erase current playpos: if (m_nOldPlayPos>=m_startRow && m_nOldPlayPos<=m_endRow) @@ -362,12 +432,13 @@ //--------------------------------------- { //erase - if (m_nRowToErase<m_startRow || m_nParamToErase<0) + if (m_nRowToErase<m_startRow || m_nParamToErase < 0) + { ::FillRect(m_dcNodes.m_hDC, &m_rcDraw, m_brushBlack); + } else { int x = RowToScreenX(m_nRowToErase); - //int y = ParamToScreenY(m_nParamToErase); CRect r( x-NODEHALF-1, m_rcDraw.top, x-NODEHALF+NODESIZE+1, m_rcDraw.bottom); ::FillRect(m_dcNodes.m_hDC, r, m_brushBlack); } @@ -376,8 +447,8 @@ for (UINT row=m_startRow; row<=m_endRow; row++) { int x = RowToScreenX(row); - int y = ParamToScreenY(GetParam(row)); - DibBlt(m_dcNodes.m_hDC, x-NODEHALF, y-NODEHALF, NODESIZE, NODESIZE, 0, 0, CMainFrame::bmpVisNode); + int y = RowToScreenY(row); + DibBlt(m_dcNodes.m_hDC, x-NODEHALF, y-NODEHALF, NODESIZE, NODESIZE, 0, 0, IsPcNote(row)? CMainFrame::bmpVisPcNode : CMainFrame::bmpVisNode); } } @@ -433,7 +504,6 @@ VOID CEffectVis::DoClose() //------------------------ { - // delete fastDC; m_dcGrid.SelectObject(m_pbOldGrid); m_dcGrid.DeleteDC(); m_dcNodes.SelectObject(m_pbOldNodes); @@ -453,7 +523,6 @@ } m_hWnd = NULL; delete this; -// _CrtDumpMemoryLeaks(); } @@ -463,21 +532,16 @@ void CEffectVis::OnSize(UINT nType, int cx, int cy) { - //CDialog::OnSize(nType, cx, cy); - // TODO: Add your message handler code here GetClientRect(&m_rcFullWin); m_rcDraw.SetRect( m_rcFullWin.left + LEFTBORDER, m_rcFullWin.top + TOPBORDER, m_rcFullWin.right - RIGHTBORDER, m_rcFullWin.bottom - BOTTOMBORDER); #define INFOWIDTH 200 -#define CHECKBOXWIDTH 100 #define ACTIONLISTWIDTH 150 #define COMMANDLISTWIDTH 130 if (IsWindow(m_edVisStatus.m_hWnd)) - m_edVisStatus.SetWindowPos(this, m_rcFullWin.left, m_rcDraw.bottom, INFOWIDTH, m_rcFullWin.bottom-m_rcDraw.bottom, SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_SHOWWINDOW|SWP_NOZORDER); -// if (IsWindow(m_btnFillCheck)) -// m_btnFillCheck.SetWindowPos(this, m_rcFullWin.right-COMMANDLISTWIDTH-CHECKBOXWIDTH, m_rcDraw.bottom, CHECKBOXWIDTH, m_rcFullWin.bottom-m_rcDraw.bottom, SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_SHOWWINDOW|SWP_NOZORDER); + m_edVisStatus.SetWindowPos(this, m_rcFullWin.left, m_rcDraw.bottom, m_rcFullWin.right-COMMANDLISTWIDTH-ACTIONLISTWIDTH, m_rcFullWin.bottom-m_rcDraw.bottom, SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_SHOWWINDOW|SWP_NOZORDER); if (IsWindow(m_cmbActionList)) m_cmbActionList.SetWindowPos(this, m_rcFullWin.right-COMMANDLISTWIDTH-ACTIONLISTWIDTH, m_rcDraw.bottom, ACTIONLISTWIDTH, m_rcFullWin.bottom-m_rcDraw.bottom, SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_SHOWWINDOW|SWP_NOZORDER); if (IsWindow(m_cmbEffectList)) @@ -485,7 +549,8 @@ m_pixelsPerRow = (float)(m_rcDraw.Width()-INNERLEFTBORDER-INNERRIGHTBORDER)/(float)m_nRows; - m_pixelsPerParam = (float)(m_rcDraw.Height())/(float)0xFF; + m_pixelsPerFXParam = (float)(m_rcDraw.Height())/(float)0xFF; + m_pixelsPerPCParam = (float)(m_rcDraw.Height())/(float)MODCOMMAND::maxColumnValue; m_boolForceRedraw = TRUE; InvalidateRect(NULL, FALSE); //redraw everything } @@ -553,7 +618,7 @@ } m_pixelsPerRow = (float)(m_rcDraw.right - m_rcDraw.left)/(float)m_nRows; - m_pixelsPerParam = (float)(m_rcDraw.bottom - m_rcDraw.top)/(float)0xFF; + m_pixelsPerFXParam = (float)(m_rcDraw.bottom - m_rcDraw.top)/(float)0xFF; m_boolForceRedraw = TRUE; Update(); @@ -562,7 +627,6 @@ void CEffectVis::OnRButtonDown(UINT nFlags, CPoint point) { - // TODO: Add your message handler code here and/or call default if (!(m_dwStatus & FXVSTATUS_LDRAGGING)) { SetFocus(); @@ -574,7 +638,7 @@ for (UINT row=m_startRow; row<=m_endRow; row++) { int x = RowToScreenX(row); - int y = ParamToScreenY(GetParam(row)); + int y = RowToScreenY(row); rect.SetRect(x-NODEHALF, y-NODEHALF, x+NODEHALF+1, y+NODEHALF+1); if (rect.PtInRect(point)) { @@ -590,80 +654,87 @@ void CEffectVis::OnRButtonUp(UINT nFlags, CPoint point) { - // TODO: Add your message handler code here and/or call default ReleaseCapture(); m_dwStatus = 0x00; m_nDragItem = -1; - CDialog::OnLButtonUp(nFlags, point); - + CDialog::OnRButtonUp(nFlags, point); } void CEffectVis::OnMouseMove(UINT nFlags, CPoint point) { - // TODO: Add your message handler code here and/or call default CDialog::OnMouseMove(nFlags, point); m_pModDoc = m_pViewPattern->GetDocument(); if (!m_pModDoc) return; - UINT row= ScreenXToRow(point.x); - BYTE paramValue=ScreenYToParam(point.y); + UINT row = ScreenXToRow(point.x); if ((m_dwStatus & FXVSTATUS_RDRAGGING) && (m_nDragItem>=0) ) { m_nRowToErase = m_nDragItem; m_nParamToErase = GetParam(m_nDragItem); - MakeChange(m_nDragItem, paramValue); - m_pModDoc->SetModified(); - m_pModDoc->UpdateAllViews(NULL, HINT_PATTERNDATA | (m_nPattern << HINT_SHIFT_PAT), NULL); + MakeChange(m_nDragItem, point.y); } else if ((m_dwStatus & FXVSTATUS_LDRAGGING)) { - //Interpolate if there's a gap, but with no release of left mouse button. - if ((m_nLastDrawnRow>(int)m_startRow) && (row != m_nLastDrawnRow) && (row != m_nLastDrawnRow+1) && (row != m_nLastDrawnRow-1)) + // Interpolate if we detect that rows have been skipped but the left mouse button was not released. + // This ensures we produce a smooth curve even when we are not notified of mouse movements at a high frequency (e.g. if CPU usage is high) + if ((m_nLastDrawnRow>(int)m_startRow) && (row != m_nLastDrawnRow) && (row != m_nLastDrawnRow+1) && (row != m_nLastDrawnRow-1)) { - int diff = abs((long)row-(long)m_nLastDrawnRow); - ASSERT(diff!=0); - int sign = ((int)(row-m_nLastDrawnRow) > 0) ? 1 : -1; - float factor = (float)(paramValue-GetParam(m_nLastDrawnRow))/(float)diff + 0.5f; + int steps = abs((long)row-(long)m_nLastDrawnRow); + ASSERT(steps!=0); + int direction = ((int)(row-m_nLastDrawnRow) > 0) ? 1 : -1; + float factor = (float)(point.y - m_nLastDrawnY)/(float)steps + 0.5f; int currentRow; - - for (int i=1; i<=diff; i++) + for (int i=1; i<=steps; i++) { - currentRow = m_nLastDrawnRow+(sign*i); - int newParam = GetParam(m_nLastDrawnRow)+((float)i*factor+0.5f); - if (newParam>0xFF) newParam = 0xFF; if (newParam<0x00) newParam = 0x00; - MakeChange(currentRow, newParam); + currentRow = m_nLastDrawnRow+(direction*i); + int interpolatedY = m_nLastDrawnY+((float)i*factor+0.5f); + MakeChange(currentRow, interpolatedY); } - - m_nRowToErase = -1; //Don't use single value update + + //Don't use single value update + m_nRowToErase = -1; m_nParamToErase = -1; } else { - //m_nLastDrawnRow = row; m_nRowToErase = -1; - m_nParamToErase = -1; //GetParam(row); - MakeChange(row, paramValue); + m_nParamToErase = -1; + MakeChange(row, point.y); } + // Remember last modified point in case we need to interpolate m_nLastDrawnRow = row; - m_pModDoc->SetModified(); - m_pModDoc->UpdateAllViews(NULL, HINT_PATTERNDATA | (m_nPattern << HINT_SHIFT_PAT), NULL); + m_nLastDrawnY = point.y; + } + //update status bar + CHAR status[256]; + CHAR effectName[128]; + uint16 paramValue; + + if (IsPcNote(row)) + { + paramValue = ScreenYToPCParam(point.y); + wsprintf(effectName, "%s", "Param Control"); //TODO - show smooth & plug+param } - //update status bar - CHAR s[256]; - wsprintf(s, "Pat: %d\tChn: %d\tRow: %d\tVal: %02X", m_nPattern, m_nChan+1, row, paramValue); - m_edVisStatus.SetWindowText(s); + else + { + paramValue = ScreenYToFXParam(point.y); + m_pModDoc->GetEffectInfo(m_pModDoc->GetIndexFromEffect(GetCommand(row), GetParam(row)), effectName, true); + } + + wsprintf(status, "Pat: %d\tChn: %d\tRow: %d\tVal: %02X (%03d) [%s]", + m_nPattern, m_nChan+1, row, paramValue, paramValue, effectName); + m_edVisStatus.SetWindowText(status); } void CEffectVis::OnLButtonDown(UINT nFlags, CPoint point) { - // TODO: Add your message handler code here and/or call default if (!(m_dwStatus & FXVSTATUS_RDRAGGING)) { SetFocus(); @@ -678,74 +749,47 @@ void CEffectVis::OnLButtonUp(UINT nFlags, CPoint point) { - // TODO: Add your message handler code here and/or call default ReleaseCapture(); m_dwStatus = 0x00; CModControlDlg::OnLButtonUp(nFlags, point); m_nLastDrawnRow = -1; } -//void CEffectVis::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) -//{ -// // TODO: Add your message handler code here and/or call default -// CModControlDlg::OnChar(nChar, nRepCnt, nFlags); -// m_pViewPattern->OnChar(nChar, nRepCnt, nFlags); -//} -//void CEffectVis::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -//{ -// // TODO: Add your message handler code here and/or call default -// -// CModControlDlg::OnKeyDown(nChar, nRepCnt, nFlags); -// m_pViewPattern->OnKeyDown(nChar, nRepCnt, nFlags); -//} - -//void CEffectVis::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -//{ -// // TODO: Add your message handler code here and/or call default -// -// CModControlDlg::OnKeyUp(nChar, nRepCnt, nFlags); -// m_pViewPattern->OnKeyUp(nChar, nRepCnt, nFlags); -//} - -//void CEffectVis::OnMButtonDown(UINT nFlags, CPoint point) -//{ -// // TODO: Add your message handler code here and/or call default -// -// CModControlDlg::OnMButtonDown(nFlags, point); -//} - void CEffectVis::OnEditUndo() { CHAR s[64]; wsprintf(s, "Undo Through!"); ::MessageBox(NULL, s, NULL, MB_OK|MB_ICONEXCLAMATION); } -//void CEffectVis::OnStnClickedVisstatus() -//{ -// // TODO: Add your control notification handler code here -//} -//void CEffectVis::OnEnChangeVisstatus() -//{ -// // TODO: If this is a RICHEDIT control, the control will not -// // send this notification unless you override the CModControlDlg::OnInitDialog() -// // function and call CRichEditCtrl().SetEventMask() -// // with the ENM_CHANGE flag ORed into the mask. -// -// // TODO: Add your control notification handler code here -//} - BOOL CEffectVis::OnInitDialog() //-------------------------------- { CModControlDlg::OnInitDialog(); - m_bFillCheck=true; - m_btnFillCheck.SetCheck(m_bFillCheck); - m_nFillEffect=m_pModDoc->GetIndexFromEffect(GetCommand(m_startRow), GetParam(m_startRow)); - if (m_nFillEffect<0) - m_nFillEffect=28; + if (IsPcNote(m_startRow)) + { + // If first selected row is a PC Note, default to PC note overwrite mode + // and use it as a template for new PC notes that will be created via the visualiser. + m_nAction = kAction_OverwritePC; + MODCOMMAND *pcmd = m_pSndFile->Patterns[m_nPattern]; + if (pcmd) { + int offset = m_startRow*m_pSndFile->m_nChannels + m_nChan; + m_templatePCNote.Set(pcmd[offset].note, pcmd[offset].instr, pcmd[offset].GetValueVolCol(), 0); + } + m_cmbEffectList.EnableWindow(FALSE); + } + else + { + // Otherwise, default to FX overwrite and + // use effect of first selected row as default effect type + m_nAction = kAction_OverwriteFX; + m_nFillEffect = m_pModDoc->GetIndexFromEffect(GetCommand(m_startRow), GetParam(m_startRow)); + if (m_nFillEffect<0 || m_nFillEffect>=MAX_EFFECTS) + m_nFillEffect = m_pModDoc->GetIndexFromEffect(CMD_SMOOTHMIDI, 0); + } + CHAR s[128]; UINT numfx = m_pModDoc->GetNumEffects(); m_cmbEffectList.ResetContent(); @@ -762,44 +806,91 @@ } m_cmbActionList.ResetContent(); - m_cmbActionList.SetItemData(m_cmbActionList.AddString("Overwrite FX type with:"), kAction_Overwrite); - m_cmbActionList.SetItemData(m_cmbActionList.AddString("Fill blanks with:"),kAction_Fill); - m_cmbActionList.SetItemData(m_cmbActionList.AddString("Keep FX type."),kAction_Preserve); + m_cmbActionList.SetItemData(m_cmbActionList.AddString("Overwrite with effect:"), kAction_OverwriteFX); + m_cmbActionList.SetItemData(m_cmbActionList.AddString("Fill blanks with effect:"), kAction_FillFX); + m_cmbActionList.SetItemData(m_cmbActionList.AddString("Overwrite with PC note"), kAction_OverwritePC); + m_cmbActionList.SetItemData(m_cmbActionList.AddString("Fill blanks with PC note"), kAction_FillPC); + m_cmbActionList.SetItemData(m_cmbActionList.AddString("Never change effect type"), kAction_Preserve); + m_cmbActionList.SetCurSel(m_nAction); return true; } -void CEffectVis::MakeChange(int currentRow, int newParam) +void CEffectVis::MakeChange(int row, long y) { - int currentCommand=GetCommand(currentRow); + MODCOMMAND *pcmd = m_pSndFile->Patterns[m_nPattern]; + if (!pcmd) { + return; + } + int offset = row*m_pSndFile->m_nChannels + m_nChan; + switch (m_nAction) { - case kAction_Preserve: - if (currentCommand) { //Only set param if we have an effect type here - m_pModDoc->GetEffectFromIndex(m_pModDoc->GetIndexFromEffect(currentCommand, m_nParamToErase), newParam); - SetParam(currentRow, newParam); + case kAction_FillFX: + // Only set command if there isn't a command already at this row and it's not a PC note + if (!GetCommand(row) && !IsPcNote(row)) + { + SetCommand(row, m_pModDoc->GetEffectFromIndex(m_nFillEffect)); } + // Always set param + SetParamFromY(row, y); break; + + case kAction_OverwriteFX: + // Always set command and param. Blows away any PC notes. + SetCommand(row, m_pModDoc->GetEffectFromIndex(m_nFillEffect)); + SetParamFromY(row, y); + break; - case kAction_Fill: - if (currentCommand) { //If we have an effect type here, just set param - m_pModDoc->GetEffectFromIndex(m_pModDoc->GetIndexFromEffect(currentCommand, m_nParamToErase), newParam); - SetParam(currentRow, newParam); - } - else //Else set command and param + case kAction_FillPC: + // Fill only empty slots with PC notes - leave other slots alone. + if (pcmd[offset].IsEmpty()) { - SetCommand(currentRow, m_pModDoc->GetEffectFromIndex(m_nFillEffect, newParam)); - SetParam(currentRow, newParam); + SetPcNote(row); } + // Always set param + SetParamFromY(row, y); break; - case kAction_Overwrite: - //Always set command and param - SetCommand(currentRow, m_pModDoc->GetEffectFromIndex(m_nFillEffect, newParam)); - SetParam(currentRow, newParam); + case kAction_OverwritePC: + // Always convert to PC Note and set param value + SetPcNote(row); + SetParamFromY(row, y); + break; + + case kAction_Preserve: + if (GetCommand(row) || IsPcNote(row)) { + // Only set param if we have an effect type or if this is a PC note. + // Never change the effect type. + SetParamFromY(row, y); + } + break; + } - return; + m_pModDoc->SetModified(); + m_pModDoc->UpdateAllViews(NULL, HINT_PATTERNDATA | (m_nPattern << HINT_SHIFT_PAT), NULL); } +void CEffectVis::SetPcNote(int row) +{ + MODCOMMAND *pcmd = m_pSndFile->Patterns[m_nPattern]; + if (!pcmd) { + return; + } + + int offset = row*m_pSndFile->m_nChannels + m_nChan; + BEGIN_CRITICAL(); + pcmd[offset].Set(m_templatePCNote.note, m_templatePCNote.instr, m_templatePCNote.GetValueVolCol(), 0); + END_CRITICAL(); +} + +bool CEffectVis::IsPcNote(int row) +{ + MODCOMMAND *pcmd = m_pSndFile->Patterns[m_nPattern]; + if (pcmd) + return pcmd[row*m_pSndFile->m_nChannels + m_nChan].IsPcNote(); + else + return false; +} \ No newline at end of file Modified: trunk/OpenMPT/mptrack/EffectVis.h =================================================================== --- trunk/OpenMPT/mptrack/EffectVis.h 2010-03-21 22:07:22 UTC (rev 543) +++ trunk/OpenMPT/mptrack/EffectVis.h 2010-03-22 20:17:53 UTC (rev 544) @@ -8,19 +8,21 @@ //#define FXVSTATUS_NCLBTNDOWN 0x02 //#define INSSTATUS_SPLITCURSOR 0x04 -enum -{ - kAction_Overwrite=0, - kAction_Fill, - kAction_Preserve -}; - // EffectVis dialog class CEffectVis : public CModControlDlg { DECLARE_DYNAMIC(CEffectVis) public: + enum + { + kAction_OverwriteFX=0, + kAction_FillFX, + kAction_OverwritePC, + kAction_FillPC, + kAction_Preserve + }; + CEffectVis(CViewPattern *pViewPattern, UINT startRow, UINT endRow, UINT nchn, CModDoc* pModDoc, UINT pat); virtual ~CEffectVis(); //{{AFX_VIRTUAL(CEffectVis) @@ -47,15 +49,13 @@ RECT invalidated; int m_nLastDrawnRow; // for interpolation + long m_nLastDrawnY; // for interpolation int m_nRowToErase; int m_nParamToErase; UINT m_nOldPlayPos; + MODCOMMAND m_templatePCNote; - -// int m_nRectWidth, m_nRectHeight; -// CRect m_rectDraw; -// CRect m_rectOwner; CBrush m_brushBlack; public: @@ -71,18 +71,23 @@ DWORD m_dwStatus; void InvalidateRow(int row); - float m_pixelsPerRow, m_pixelsPerParam; + float m_pixelsPerRow, m_pixelsPerFXParam, m_pixelsPerPCParam; void UpdateSelection(UINT startRow, UINT endRow, UINT nchn, CModDoc* m_pModDoc, UINT pats); void Update(); int RowToScreenX(UINT row); - int ParamToScreenY(BYTE param); - BYTE GetParam(UINT row); + int RowToScreenY(UINT row); + int PCParamToScreenY(uint16 param); + int FXParamToScreenY(uint16 param); + uint16 GetParam(UINT row); BYTE GetCommand(UINT row); - void SetParam(UINT row, BYTE param); + void SetParamFromY(UINT row, long y); void SetCommand(UINT row, BYTE cmd); - BYTE ScreenYToParam(int y); + BYTE ScreenYToFXParam(int y); + uint16 ScreenYToPCParam(int y); UINT ScreenXToRow(int x); void SetPlayCursor(UINT nPat, UINT nRow); + bool IsPcNote(int row); + void SetPcNote(int row); CSoundFile* m_pSndFile; CModDoc* m_pModDoc; @@ -90,8 +95,6 @@ CRect m_rcFullWin; CComboBox m_cmbEffectList, m_cmbActionList; - CButton m_btnFillCheck; - bool m_bFillCheck; CEdit m_edVisStatus; virtual VOID OnOK(); @@ -116,18 +119,13 @@ afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnRButtonDown(UINT nFlags, CPoint point); afx_msg void OnRButtonUp(UINT nFlags, CPoint point); - afx_msg void OnFillBlanksCheck(); afx_msg void OnEffectChanged(); afx_msg void OnActionChanged(); -// afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); -// afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); -// afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); -// afx_msg void OnMButtonDown(UINT nFlags, CPoint point); //{{AFX_MSG(CEffectVis) afx_msg void OnEditUndo(); //}}AFX_MSG private: - void MakeChange(int currentRow, int newParam); + void MakeChange(int currentRow, long newY); }; Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2010-03-21 22:07:22 UTC (rev 543) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2010-03-22 20:17:53 UTC (rev 544) @@ -246,7 +246,8 @@ LPMODPLUGDIB CMainFrame::bmpPatterns = NULL; LPMODPLUGDIB CMainFrame::bmpNotes = NULL; LPMODPLUGDIB CMainFrame::bmpVUMeters = NULL; -LPMODPLUGDIB CMainFrame::bmpVisNode = NULL; //rewbs.fxVis +LPMODPLUGDIB CMainFrame::bmpVisNode = NULL; +LPMODPLUGDIB CMainFrame::bmpVisPcNode = NULL; HPEN CMainFrame::gpenVuMeter[NUM_VUMETER_PENS*2]; COLORREF CMainFrame::rgbCustomColors[MAX_MODCOLORS] = { @@ -772,7 +773,8 @@ bmpPatterns = LoadDib(MAKEINTRESOURCE(IDB_PATTERNS)); bmpNotes = LoadDib(MAKEINTRESOURCE(IDB_PATTERNVIEW)); bmpVUMeters = LoadDib(MAKEINTRESOURCE(IDB_VUMETERS)); - bmpVisNode = LoadDib(MAKEINTRESOURCE(IDB_VISNODE)); //rewbs.fxVis + bmpVisNode = LoadDib(MAKEINTRESOURCE(IDB_VISNODE)); + bmpVisPcNode = LoadDib(MAKEINTRESOURCE(IDB_VISPCNODE)); UpdateColors(); // Toolbars EnableDocking(CBRS_ALIGN_ANY); @@ -849,6 +851,11 @@ delete bmpVisNode; bmpVisNode = NULL; } + if (bmpVisPcNode) + { + delete bmpVisPcNode; + bmpVisPcNode = NULL; + } // Kill GDI Objects DeleteGDIObject(brushGray); Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2010-03-21 22:07:22 UTC (rev 543) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2010-03-22 20:17:53 UTC (rev 544) @@ -442,7 +442,7 @@ 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; static COLORREF rgbCustomColors[MAX_MODCOLORS]; - static LPMODPLUGDIB bmpPatterns, bmpNotes, bmpVUMeters, bmpVisNode; + static LPMODPLUGDIB bmpPatterns, bmpNotes, bmpVUMeters, bmpVisNode, bmpVisPcNode; static HPEN gpenVuMeter[NUM_VUMETER_PENS*2]; // key config static TCHAR m_szKbdFile[_MAX_PATH]; Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2010-03-21 22:07:22 UTC (rev 543) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2010-03-22 20:17:53 UTC (rev 544) @@ -2224,6 +2224,17 @@ return gFXInfo[ndx].dwEffect; } + +UINT CModDoc::GetEffectFromIndex(UINT ndx) +//---------------------------------------- +{ + if (ndx >= MAX_FXINFO) { + return 0; + } + + return gFXInfo[ndx].dwEffect; +} + UINT CModDoc::GetEffectMaskFromIndex(UINT ndx) //------------------------------------------------------- { Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2010-03-21 22:07:22 UTC (rev 543) +++ trunk/OpenMPT/mptrack/Moddoc.h 2010-03-22 20:17:53 UTC (rev 544) @@ -193,6 +193,7 @@ bool GetEffectInfo(UINT ndx, LPSTR s, bool bXX = false, DWORD *prangeMin=NULL, DWORD *prangeMax=NULL); LONG GetIndexFromEffect(UINT command, UINT param); UINT GetEffectFromIndex(UINT ndx, int &refParam); + UINT GetEffectFromIndex(UINT ndx); UINT GetEffectMaskFromIndex(UINT ndx); bool GetEffectNameEx(LPSTR pszName, UINT ndx, UINT param); BOOL IsExtendedEffect(UINT ndx) const; Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2010-03-21 22:07:22 UTC (rev 543) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2010-03-22 20:17:53 UTC (rev 544) @@ -2481,7 +2481,8 @@ p = pSndFile->Patterns[m_nPattern] + r * pSndFile->m_nChannels + c; // If a note or an instr is present on the row, do the change, if required. // Do not set instr if note and instr are both blank. - if ( ((p->note > 0 && p->note < NOTE_MIN_SPECIAL) ||p->instr) && (p->instr!=nIns) ) { + // Do set instr if note is a PC note and instr is blank. + if ( ((p->note > 0 && p->note < NOTE_MIN_SPECIAL) || MODCOMMAND::IsPcNote(p->note) || p->instr) && (p->instr!=nIns) ) { p->instr = nIns; bModified = TRUE; } Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2010-03-21 22:07:22 UTC (rev 543) +++ trunk/OpenMPT/mptrack/mptrack.rc 2010-03-22 20:17:53 UTC (rev 544) @@ -13,7 +13,7 @@ #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// -// Deutsch (Deutschland) resources +// German (Germany) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) #ifdef _WIN32 @@ -207,12 +207,12 @@ END #endif // APSTUDIO_INVOKED -#endif // Deutsch (Deutschland) resources +#endif // German (Germany) resources ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// -// Englisch (USA) resources +// English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 @@ -1302,17 +1302,16 @@ PUSHBUTTON "Save",IDC_BUTTON2,193,39,36,14 END -IDD_EFFECTVISUALIZER DIALOGEX 0, 0, 385, 108 -STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +IDD_EFFECTVISUALIZER DIALOGEX 0, 0, 422, 109 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME EXSTYLE WS_EX_TOOLWINDOW | WS_EX_CLIENTEDGE CAPTION "Param Editor" FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - EDITTEXT IDC_VISSTATUS,4,91,162,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_STATICEDGE - CONTROL "Fill blanks with:",IDC_VISFILLBLANKS,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,188,92,63,10 + EDITTEXT IDC_VISSTATUS,4,92,162,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_STATICEDGE COMBOBOX IDC_VISEFFECTLIST,299,89,76,158,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_VISACTION,221,90,76,158,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "",IDC_RENDERZONE,4,3,377,84,NOT WS_VISIBLE + LTEXT "",IDC_RENDERZONE,4,3,414,84,NOT WS_VISIBLE END IDD_SOUNDBANK_INFO1 DIALOGEX 0, 0, 271, 167 @@ -1722,9 +1721,9 @@ IDD_EFFECTVISUALIZER, DIALOG BEGIN LEFTMARGIN, 4 - RIGHTMARGIN, 381 + RIGHTMARGIN, 418 TOPMARGIN, 3 - BOTTOMMARGIN, 103 + BOTTOMMARGIN, 104 END IDD_SOUNDBANK_INFO1, DIALOG @@ -1851,6 +1850,7 @@ IDB_ENVTOOLBAR BITMAP "res\\envbar.bmp" IDB_SMPTOOLBAR BITMAP "res\\smptoolb.bmp" IDB_VISNODE BITMAP "res\\bitmap1.bmp" +IDB_VISPCNODE BITMAP "res\\vispcnode.bmp" ///////////////////////////////////////////////////////////////////////////// // @@ -2378,12 +2378,12 @@ IDS_SOUNDTOUCH_LOADFAILURE "Unable to load OpenMPT_soundtouch_i16.dll." END -#endif // Englisch (USA) resources +#endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// -// Englisch (GB) resources +// English (U.K.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) #ifdef _WIN32 @@ -2752,7 +2752,7 @@ // IDR_BUILTIN_TUNINGS TUNING "res\\built-inTunings.tc" -#endif // Englisch (GB) resources +#endif // English (U.K.) resources ///////////////////////////////////////////////////////////////////////////// Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2010-03-21 22:07:22 UTC (rev 543) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2010-03-22 20:17:53 UTC (rev 544) @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="Windows-1252"?> <VisualStudioProject ProjectType="Visual C++" - Version="9,00" + Version="9.00" Name="mptrack" ProjectGUID="{21D95071-FB97-4E69-B3B1-050D0D4A5021}" RootNamespace="mptrack" @@ -49,7 +49,7 @@ Name="VCCLCompilerTool" AdditionalOptions="/EHsc" Optimization="0" - AdditionalIncludeDirectories="..\unlha,..\unzip,..\unrar,..\soundlib,..\include,..\xsoundlib,..\" + AdditionalIncludeDirectories="..\unlha;..\unzip;..\unrar;..\soundlib;..\include;..\xsoundlib;..\" PreprocessorDefinitions="_DEBUG,WIN32,_WINDOWS,ENABLE_EQ,MODPLUG_TRACKER,NO_PACKING,HAVE_DOT_NET,ENABLE_AMD,ENABLE_SSE,ENABLE_AMDNOW,ENABLE_MMX" StringPooling="true" BasicRuntimeChecks="3" @@ -922,6 +922,14 @@ > </File> <File + RelativePath=".\res\visnode1.bmp" + > + </File> + <File + RelativePath=".\res\vispcnode.bmp" + > + </File> + <File RelativePath=".\res\vumeters.bmp" > </File> Added: trunk/OpenMPT/mptrack/res/vispcnode.bmp =================================================================== (Binary files differ) Property changes on: trunk/OpenMPT/mptrack/res/vispcnode.bmp ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2010-03-21 22:07:22 UTC (rev 543) +++ trunk/OpenMPT/mptrack/resource.h 2010-03-22 20:17:53 UTC (rev 544) @@ -103,6 +103,8 @@ #define IDB_SPLASHTEST 432 #define IDB_SPLASHNOFOLDFIN 435 #define IDR_VSTMENU 436 +#define IDB_VISNODE1 436 +#define IDB_VISPCNODE 436 #define IDD_DEFAULTPLUGINEDITOR 438 #define IDD_CHANNELMANAGER 440 #define IDD_SOUNDBANK_INFO1 441 Modified: trunk/OpenMPT/packageTemplate/extraKeymaps/UK_mpt_it2_hybrid_(rewbs).mkb =================================================================== --- trunk/OpenMPT/packageTemplate/extraKeymaps/UK_mpt_it2_hybrid_(rewbs).mkb 2010-03-21 22:07:22 UTC (rev 543) +++ trunk/OpenMPT/packageTemplate/extraKeymaps/UK_mpt_it2_hybrid_(rewbs).mkb 2010-03-22 20:17:53 UTC (rev 544) @@ -119,9 +119,9 @@ 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 +1 A: N (KeyDown) -3:1074:0:74:1 //Base octave +1 A#: J (KeyDown) -3:1075:0:77:1 //Base octave +1 B: M (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:1077:0:50:1 //Base octave +1 C#: 2 (KeyDown) 3:1078:0:87:1 //Base octave +1 D: W (KeyDown) @@ -131,9 +131,9 @@ 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 +2 A: Y (KeyDown) -3:1086:0:55:1 //Base octave +2 A#: 7 (KeyDown) -3:1087:0:85:1 //Base octave +2 B: U (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) @@ -151,11 +151,13 @@ 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 (KeyDown) -3:1200:0:49:1 //Note cut: 1 (KeyDown) -3:1201:0:223:1 //Note off: ` (KeyDown) -3:1201:0:187:1 //Note off: = (KeyDown) -3:1667:1:49:1 //Note cut (don't remember instrument): Shift+1 (KeyDown) -3:1668:1:223:1 //Note off (don't remember instrument): Shift+` (KeyDown) +3:1200:0:49:1 //Note Cut: 1 (KeyDown) +3:1201:0:223:1 //Note Off: ` (KeyDown) +3:1201:0:187:1 //Note Off: = (KeyDown) +3:1667:1:49:1 //Note Cut (don't remember instrument): Shift+1 (KeyDown) +3:1668:1:223:1 //Note Off (don't remember instrument): Shift+` (KeyDown) +3:1788:1:222:1 //Parameter control(MPTm only): Shift+# (KeyDown) +3:1789:0:222:1 //Parameter control(smooth)(MPTm only): # (KeyDown) //----( Pattern Context [bottom] - Ins Col (4) )------------ 4:1202:0:96:1 //Set instrument digit 0: NUM 0 (KeyDown) @@ -314,6 +316,6 @@ 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 PLUS (KeyDown|KeyHold) -19:1817:0:187:5 //Increase pattern index : + (KeyDown|KeyHold) +19:1817:0:187:5 //Increase pattern index : = (KeyDown|KeyHold) 19:1818:0:109:1 //Decrease pattern index: NUM SUB (KeyDown) 19:1818:0:189:1 //Decrease pattern index: - (KeyDown) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |