From: <sag...@us...> - 2009-08-20 20:44:03
|
Revision: 336 http://modplug.svn.sourceforge.net/modplug/?rev=336&view=rev Author: saga-games Date: 2009-08-20 20:43:52 +0000 (Thu, 20 Aug 2009) Log Message: ----------- [Ref] Dabbling with order limits (especially in the module loaders) so that... [Fix] ...Inserting more than 128 orders in MOD format is not possible anymore. [Fix] More order overflow checks [Fix] Fixed checks when Instruments or Samples were created. Also added test checks for those numbers. [Mod] Moved tagging.h into the appropriate "folder" of the project file. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Ctrl_pat.cpp trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/test/test.cpp trunk/OpenMPT/mptrack/typedefs.h trunk/OpenMPT/soundlib/LOAD_AMF.CPP trunk/OpenMPT/soundlib/LOAD_DBM.CPP trunk/OpenMPT/soundlib/LOAD_DMF.CPP trunk/OpenMPT/soundlib/LOAD_DSM.CPP trunk/OpenMPT/soundlib/Load_ams.cpp trunk/OpenMPT/soundlib/Load_far.cpp trunk/OpenMPT/soundlib/Load_imf.cpp trunk/OpenMPT/soundlib/Load_mdl.cpp trunk/OpenMPT/soundlib/Load_med.cpp trunk/OpenMPT/soundlib/Load_mid.cpp trunk/OpenMPT/soundlib/Load_mod.cpp trunk/OpenMPT/soundlib/Load_mt2.cpp trunk/OpenMPT/soundlib/Load_okt.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/Load_wav.cpp trunk/OpenMPT/soundlib/Sndfile.cpp Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -1503,7 +1503,7 @@ } BOOL bFirst = (pSndFile->m_nInstruments) ? FALSE : TRUE; LONG ins = m_pModDoc->InsertInstrument(0); - if (ins > 0) + if (ins != INSTRUMENTINDEX_INVALID) { SetCurrentInstrument(ins); m_pModDoc->UpdateAllViews(NULL, (ins << HINT_SHIFT_INS) | HINT_INSTRUMENT | HINT_INSNAMES | HINT_ENVELOPE); @@ -1525,7 +1525,7 @@ { BOOL bFirst = (pSndFile->m_nInstruments) ? FALSE : TRUE; LONG ins = m_pModDoc->InsertInstrument(0, m_nInstrument); - if (ins > 0) + if (ins != INSTRUMENTINDEX_INVALID) { SetCurrentInstrument(ins); m_pModDoc->UpdateAllViews(NULL, (ins << HINT_SHIFT_INS) | HINT_INSTRUMENT | HINT_INSNAMES | HINT_ENVELOPE); Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -877,6 +877,8 @@ ORD_SELECTION selection = m_OrderList.GetCurSel(false); ORDERINDEX nInsertCount = selection.nOrdHi - selection.nOrdLo; ORDERINDEX nInsertWhere = selection.nOrdLo + nInsertCount + 1; + if (nInsertWhere >= pSndFile->GetModSpecifications().ordersMax) + return; bool bSuccess = false; // has this pattern been duplicated already? (for multiselect) vector<PATTERNINDEX> pReplaceIndex; @@ -917,14 +919,15 @@ nNewPat = pReplaceIndex[nCurPat]; // take care of patterns that have been duplicated before else nNewPat= pSndFile->Order[selection.nOrdLo + i]; - pSndFile->Order[selection.nOrdLo + i + nInsertCount + 1] = nNewPat; + if (selection.nOrdLo + i + nInsertCount + 1 < pSndFile->Order.GetCount()) + pSndFile->Order[selection.nOrdLo + i + nInsertCount + 1] = nNewPat; } } if(bSuccess) { m_OrderList.InvalidateRect(NULL, FALSE); m_OrderList.SetCurSel(nInsertWhere); - SetCurrentPattern(pSndFile->Order[nInsertWhere]); + SetCurrentPattern(pSndFile->Order[min(nInsertWhere, pSndFile->Order.GetCount()-1)]); m_pModDoc->SetModified(); m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE|HINT_PATNAMES, this); if(selection.nOrdHi != selection.nOrdLo) m_OrderList.m_nScrollPos2nd = nInsertWhere + nInsertCount; Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -570,15 +570,12 @@ s[0] = 0; if ((nOrder >= 0) && (rect.left + m_cxFont - 4 <= rcClient.right)) { - if (nOrder == pSndFile->Order.GetInvalidPatIndex()) strcpy(s, "---"); //Print the 'dots' - else + if (nIndex < pSndFile->Order.GetCount()) { - if (nOrder < pSndFile->Patterns.Size()) wsprintf(s, "%d", nOrder); - else - { - if(nOrder == pSndFile->Order.GetIgnoreIndex()) strcpy(s, "+++"); - else strcpy(s, "???"); - } + if (nOrder == pSndFile->Order.GetInvalidPatIndex()) strcpy(s, "---"); + else if (nOrder == pSndFile->Order.GetIgnoreIndex()) strcpy(s, "+++"); + else if (nOrder < pSndFile->Patterns.Size()) wsprintf(s, "%d", nOrder); + else strcpy(s, "???"); } } dc.SetTextColor((bHighLight) ? colorTextSel : colorText); @@ -912,7 +909,7 @@ ORD_SELECTION selection = GetCurSel(false); ORDERINDEX nInsertCount = selection.nOrdHi - selection.nOrdLo, nInsertEnd = selection.nOrdHi; - for(int i = 0; i <= nInsertCount; i++) + for(ORDERINDEX i = 0; i <= nInsertCount; i++) { //Checking whether there is some pattern at the end of orderlist. @@ -922,7 +919,7 @@ pSndFile->Order.push_back(pSndFile->Order.GetInvalidPatIndex()); } - for (int i=pSndFile->Order.size() - 1; i>nInsertEnd; i--) pSndFile->Order[i] = pSndFile->Order[i - 1]; + for(int j = pSndFile->Order.size() - 1; j > nInsertEnd; j--) pSndFile->Order[j] = pSndFile->Order[j - 1]; } // now that there is enough space in the order list, overwrite the orders for(ORDERINDEX i = 0; i <= nInsertCount; i++) @@ -930,8 +927,8 @@ if(nInsertEnd + i + 1 < pSndFile->GetModSpecifications().ordersMax) pSndFile->Order[nInsertEnd + i + 1] = pSndFile->Order[nInsertEnd - nInsertCount + i]; } - m_nScrollPos = nInsertEnd + 1; - m_nScrollPos2nd = m_nScrollPos + nInsertCount; + m_nScrollPos = min(nInsertEnd + 1, pSndFile->Order.GetCount() - 1); + m_nScrollPos2nd = min(m_nScrollPos + nInsertCount, pSndFile->Order.GetCount() - 1); InvalidateRect(NULL, FALSE); m_pModDoc->SetModified(); m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this); Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -884,7 +884,7 @@ //------------------------------ { LONG smp = m_pModDoc->InsertSample(TRUE); - if (smp > 0) + if (smp != SAMPLEINDEX_INVALID) { if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -1987,7 +1987,7 @@ //---------------------------- { LONG smp = InsertSample(); - if (smp >= 0) ViewSample(smp); + if (smp != SAMPLEINDEX_INVALID) ViewSample(smp); } @@ -1995,7 +1995,7 @@ //-------------------------------- { LONG ins = InsertInstrument(); - if (ins >= 0) ViewInstrument(ins); + if (ins != INSTRUMENTINDEX_INVALID) ViewInstrument(ins); } Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-08-20 20:43:52 UTC (rev 336) @@ -199,7 +199,7 @@ PATTERNINDEX InsertPattern(ORDERINDEX nOrd = -1, ROWINDEX nRows = 64); SAMPLEINDEX InsertSample(bool bLimit = false); - INSTRUMENTINDEX InsertInstrument(LONG lSample=0, LONG lDuplicate=0); + INSTRUMENTINDEX InsertInstrument(LONG lSample = 0, LONG lDuplicate = 0); void InitializeInstrument(MODINSTRUMENT *pIns, UINT nsample=0); bool RemoveOrder(ORDERINDEX n); bool RemovePattern(PATTERNINDEX n); Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -1661,10 +1661,10 @@ } } if (((bLimit) && (i >= 200) && (!m_SndFile.m_nInstruments)) - || (i >= MAX_SAMPLES)) + || (i >= m_SndFile.GetModSpecifications().samplesMax)) { ErrorBox(IDS_ERR_TOOMANYSMP, CMainFrame::GetMainFrame()); - return -1; + return SAMPLEINDEX_INVALID; } if (!m_SndFile.m_szNames[i][0]) strcpy(m_SndFile.m_szNames[i], "untitled"); MODSAMPLE *pSmp = &m_SndFile.Samples[i]; @@ -1690,7 +1690,8 @@ //----------------------------------------------------------- { MODINSTRUMENT *pDup = NULL; - if ((m_SndFile.m_nType != MOD_TYPE_XM) && !(m_SndFile.m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT))) return -1; + INSTRUMENTINDEX nInstrumentMax = m_SndFile.GetModSpecifications().instrumentsMax - 1; + if ((m_SndFile.m_nType != MOD_TYPE_XM) && !(m_SndFile.m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT))) return INSTRUMENTINDEX_INVALID; if ((lDuplicate > 0) && (lDuplicate <= (LONG)m_SndFile.m_nInstruments)) { pDup = m_SndFile.Instruments[lDuplicate]; @@ -1702,7 +1703,7 @@ if (n == IDYES) { UINT nInstruments = m_SndFile.m_nSamples; - if (nInstruments >= MAX_INSTRUMENTS) nInstruments = MAX_INSTRUMENTS-1; + if (nInstruments > nInstrumentMax) nInstruments = nInstrumentMax; for (UINT smp=1; smp<=nInstruments; smp++) { m_SndFile.Samples[smp].uFlags &= ~CHN_MUTE; @@ -1721,7 +1722,7 @@ } m_SndFile.m_nInstruments = nInstruments; } else - if (n != IDNO) return -1; + if (n != IDNO) return INSTRUMENTINDEX_INVALID; } UINT newins = 0; for (UINT i=1; i<=m_SndFile.m_nInstruments; i++) @@ -1734,10 +1735,10 @@ } if (!newins) { - if (m_SndFile.m_nInstruments >= MAX_INSTRUMENTS-1) + if (m_SndFile.m_nInstruments >= nInstrumentMax) { ErrorBox(IDS_ERR_TOOMANYINS, CMainFrame::GetMainFrame()); - return -1; + return INSTRUMENTINDEX_INVALID; } newins = ++m_SndFile.m_nInstruments; } @@ -1745,7 +1746,7 @@ if (pIns) { UINT newsmp = 0; - if ((lSample > 0) && (lSample < MAX_SAMPLES)) + if ((lSample > 0) && (lSample < m_SndFile.GetModSpecifications().samplesMax)) { newsmp = lSample; } else @@ -1762,7 +1763,7 @@ if (!newsmp) { int inssmp = InsertSample(); - if (inssmp > 0) newsmp = inssmp; + if (inssmp != SAMPLEINDEX_INVALID) newsmp = inssmp; } } BEGIN_CRITICAL(); @@ -1784,7 +1785,7 @@ } else { ErrorBox(IDS_ERR_OUTOFMEMORY, CMainFrame::GetMainFrame()); - return -1; + return INSTRUMENTINDEX_INVALID; } return newins; } Modified: trunk/OpenMPT/mptrack/mptrack.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack.vcproj 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/mptrack/mptrack.vcproj 2009-08-20 20:43:52 UTC (rev 336) @@ -481,9 +481,6 @@ RelativePath=".\tagging.cpp"> </File> <File - RelativePath=".\tagging.h"> - </File> - <File RelativePath=".\view_com.cpp"> </File> <File @@ -870,6 +867,9 @@ RelativePath=".\StdAfx.h"> </File> <File + RelativePath=".\tagging.h"> + </File> + <File RelativePath=".\typedefs.h"> </File> <File Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-08-20 20:43:52 UTC (rev 336) @@ -645,10 +645,6 @@ > </File> <File - RelativePath=".\tagging.h" - > - </File> - <File RelativePath=".\view_com.cpp" > </File> @@ -1151,6 +1147,10 @@ > </File> <File + RelativePath=".\tagging.h" + > + </File> + <File RelativePath=".\typedefs.h" > </File> Modified: trunk/OpenMPT/mptrack/test/test.cpp =================================================================== --- trunk/OpenMPT/mptrack/test/test.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/mptrack/test/test.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -163,6 +163,9 @@ VERIFY_EQUAL(ROWINDEX_MAX, (std::numeric_limits<ROWINDEX>::max)()); VERIFY_EQUAL(ORDERINDEX_MAX, (std::numeric_limits<ORDERINDEX>::max)()); + VERIFY_EQUAL(PATTERNINDEX_MAX, (std::numeric_limits<PATTERNINDEX>::max)()); + VERIFY_EQUAL(SAMPLEINDEX_MAX, (std::numeric_limits<SAMPLEINDEX>::max)()); + VERIFY_EQUAL(INSTRUMENTINDEX_MAX, (std::numeric_limits<INSTRUMENTINDEX>::max)()); } Modified: trunk/OpenMPT/mptrack/typedefs.h =================================================================== --- trunk/OpenMPT/mptrack/typedefs.h 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/mptrack/typedefs.h 2009-08-20 20:43:52 UTC (rev 336) @@ -43,7 +43,11 @@ typedef uint8 PLUGINDEX; typedef uint16 TEMPO; typedef uint16 SAMPLEINDEX; + const SAMPLEINDEX SAMPLEINDEX_MAX = uint16_max; + const SAMPLEINDEX SAMPLEINDEX_INVALID = SAMPLEINDEX_MAX; typedef uint16 INSTRUMENTINDEX; + const SAMPLEINDEX INSTRUMENTINDEX_MAX = uint16_max; + const SAMPLEINDEX INSTRUMENTINDEX_INVALID = INSTRUMENTINDEX_MAX; typedef uint32 MODTYPE; Modified: trunk/OpenMPT/soundlib/LOAD_AMF.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-08-20 20:43:52 UTC (rev 336) @@ -191,10 +191,7 @@ m_nSamples = 31; m_nDefaultTempo = 125; m_nDefaultSpeed = 6; - for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++) - { - Order[iOrd] = (iOrd < numorders) ? lpStream[dwMemPos+iOrd] : Order.GetInvalidPatIndex(); - } + Order.ReadAsByte(lpStream + dwMemPos, numorders, dwMemLength - dwMemPos); dwMemPos = 294; // ??? for (UINT iSmp=0; iSmp<numsamples; iSmp++) { @@ -307,21 +304,18 @@ dwMemPos += 2; } // Setup sequence list - for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++) + Order.resize(pfh->numorders, Order.GetInvalidPatIndex()); + for (UINT iOrd=0; iOrd < pfh->numorders; iOrd++) { - Order[iOrd] = Order.GetInvalidPatIndex(); - if (iOrd < pfh->numorders) + Order[iOrd] = iOrd; + Patterns[iOrd].Resize(64); + if (pfh->version >= 14) { - Order[iOrd] = iOrd; - Patterns[iOrd].Resize(64); - if (pfh->version >= 14) - { - Patterns[iOrd].Resize(LittleEndianW(*(USHORT *)(lpStream+dwMemPos))); - dwMemPos += 2; - } - ptracks[iOrd] = (USHORT *)(lpStream+dwMemPos); - dwMemPos += m_nChannels * sizeof(USHORT); + Patterns[iOrd].Resize(LittleEndianW(*(USHORT *)(lpStream+dwMemPos))); + dwMemPos += 2; } + ptracks[iOrd] = (USHORT *)(lpStream+dwMemPos); + dwMemPos += m_nChannels * sizeof(USHORT); } if (dwMemPos + m_nSamples * (sizeof(AMFSAMPLE)+8) > dwMemLength) return true; // Read Samples Modified: trunk/OpenMPT/soundlib/LOAD_DBM.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_DBM.CPP 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/LOAD_DBM.CPP 2009-08-20 20:43:52 UTC (rev 336) @@ -120,10 +120,11 @@ if (m_nChannels > 64) m_nChannels = 64; memcpy(m_szNames[0], (pfh->songname[0]) ? pfh->songname : pfh->songname2, 32); m_szNames[0][31] = 0; + Order.resize(nOrders, Order.GetInvalidPatIndex()); for (UINT iOrd=0; iOrd < nOrders; iOrd++) { - Order[iOrd] = lpStream[dwMemPos+iOrd*2+1]; - if (iOrd >= MAX_ORDERS-2) break; + if (iOrd >= MAX_ORDERS) break; + Order[iOrd] = (PATTERNINDEX)BigEndianW(*((WORD *)(lpStream + dwMemPos + iOrd * 2))); } dwMemPos += 2*nOrders; while (dwMemPos + 10 < dwMemLength) Modified: trunk/OpenMPT/soundlib/LOAD_DMF.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2009-08-20 20:43:52 UTC (rev 336) @@ -145,8 +145,9 @@ { UINT nseq = sequ->seqsize >> 1; if (nseq >= MAX_ORDERS-1) nseq = MAX_ORDERS-1; + Order.resize(nseq, Order.GetInvalidPatIndex()); if (sequ->loopstart < nseq) m_nRestartPos = sequ->loopstart; - for (UINT i=0; i<nseq; i++) Order[i] = (BYTE)sequ->sequ[i]; + for (UINT i = 0; i < nseq; i++) Order[i] = (PATTERNINDEX)sequ->sequ[i]; } dwMemPos += sequ->seqsize + 8; break; Modified: trunk/OpenMPT/soundlib/LOAD_DSM.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_DSM.CPP 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/LOAD_DSM.CPP 2009-08-20 20:43:52 UTC (rev 336) @@ -110,10 +110,8 @@ m_nDefaultGlobalVolume = psong->globalvol << 2; if ((!m_nDefaultGlobalVolume) || (m_nDefaultGlobalVolume > 256)) m_nDefaultGlobalVolume = 256; m_nSamplePreAmp = psong->mastervol & 0x7F; - for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++) - { - Order[iOrd] = (BYTE)((iOrd < psong->numord) ? psong->orders[iOrd] : 0xFF); - } + Order.ReadAsByte(psong->orders, psong->numord, sizeof(psong->orders)); + for (UINT iPan=0; iPan<16; iPan++) { ChnSettings[iPan].nPan = 0x80; Modified: trunk/OpenMPT/soundlib/Load_ams.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_ams.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/Load_ams.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -103,8 +103,12 @@ for (UINT cNam=0; cNam<m_nChannels; cNam++) { if (dwMemPos + 32 >= dwMemLength) return true; - tmp = lpStream[dwMemPos++]; - dwMemPos += tmp; + BYTE chnnamlen = lpStream[dwMemPos++]; + if ((chnnamlen) && (chnnamlen < MAX_CHANNELNAME)) + { + memcpy(ChnSettings[cNam].szName, lpStream + dwMemPos + 1, chnnamlen); + } + dwMemPos += chnnamlen; } // Read Pattern Names m_lpszPatternNames = new char[pfh->patterns * 32]; @@ -132,10 +136,10 @@ dwMemPos += tmp; } // Read Order List - for (UINT iOrd=0; iOrd<pfh->orders; iOrd++, dwMemPos += 2) + Order.resize(pfh->orders, Order.GetInvalidPatIndex()); + for (UINT iOrd=0; iOrd < pfh->orders; iOrd++, dwMemPos += 2) { - UINT n = *((WORD *)(lpStream+dwMemPos)); - Order[iOrd] = n; + Order[iOrd] = (PATTERNINDEX)*((WORD *)(lpStream + dwMemPos)); } // Read Patterns for (UINT iPat=0; iPat<pfh->patterns; iPat++) @@ -459,15 +463,12 @@ } // Order List { - for (UINT i=0; i<MAX_ORDERS; i++) + if ((dwMemPos + 2 * psh->orders) >= dwMemLength) return TRUE; + Order.resize(psh->orders, Order.GetInvalidPatIndex()); + for (UINT iOrd = 0; iOrd < psh->orders; iOrd++) { - Order[i] = Order.GetInvalidPatIndex(); - if (dwMemPos + 2 >= dwMemLength) return TRUE; - if (i < psh->orders) - { - Order[i] = lpStream[dwMemPos]; - dwMemPos += 2; - } + Order[iOrd] = (PATTERNINDEX)*((WORD *)(lpStream + dwMemPos)); + dwMemPos += 2; } } // Pattern Data Modified: trunk/OpenMPT/soundlib/Load_far.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_far.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/Load_far.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -114,10 +114,8 @@ pmh2 = &farHeader2; dwMemPos += sizeof(FARHEADER2); if (dwMemPos >= dwMemLength) return true; - for (UINT iorder=0; iorder<MAX_ORDERS; iorder++) - { - Order[iorder] = (iorder <= pmh2->snglen) ? pmh2->orders[iorder] : Order.GetInvalidPatIndex(); - } + + Order.ReadAsByte(pmh2->orders, pmh2->snglen, sizeof(pmh2->orders)); m_nRestartPos = pmh2->loopto; // Reading Patterns dwMemPos += headerlen - (869 + pmh1->stlen); Modified: trunk/OpenMPT/soundlib/Load_imf.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_imf.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/Load_imf.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -329,8 +329,9 @@ } if(!m_nChannels) return false; + Order.resize(hdr.ordnum); for (ORDERINDEX nOrd = 0; nOrd < hdr.ordnum; nOrd++) - Order[nOrd] = ((hdr.orderlist[nOrd] == 0xff) ? Order.GetIgnoreIndex() : hdr.orderlist[nOrd]); + Order[nOrd] = ((hdr.orderlist[nOrd] == 0xff) ? Order.GetIgnoreIndex() : (PATTERNINDEX)hdr.orderlist[nOrd]); // read patterns for (PATTERNINDEX nPat = 0; nPat < hdr.patnum; nPat++) Modified: trunk/OpenMPT/soundlib/Load_mdl.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -245,7 +245,7 @@ else m_nChannels = i+1; } - for (j=0; j<norders; j++) Order[j] = pmib->seq[j]; + Order.ReadAsByte(pmib->seq, norders, sizeof(pmib->seq)); break; // ME: song message case 0x454D: Modified: trunk/OpenMPT/soundlib/Load_med.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_med.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/Load_med.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -670,19 +670,20 @@ UINT n = BigEndianW(pmps->length); if (pseq+n <= dwMemLength) { + Order.resize(nOrders++); for (UINT i=0; i<n; i++) { - UINT seqval = pmps->seq[i] >> 8; + WORD seqval = BigEndian(pmps->seq[i]); if ((seqval < wNumBlocks) && (nOrders < MAX_ORDERS-1)) { - Order[nOrders++] = seqval; + Order[nOrders++] = (ORDERINDEX)seqval; } } } } } playtransp = pmsh2->playtransp; - while (nOrders < MAX_ORDERS) Order[nOrders++] = 0xFF; + while (nOrders < MAX_ORDERS) Order[nOrders++] = Order.GetInvalidPatIndex(); } // Reading Expansion structure if (pmex) Modified: trunk/OpenMPT/soundlib/Load_mid.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mid.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/Load_mid.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -563,7 +563,7 @@ Log("%d tracks, tempo = %dus, division = %04X TickFactor=%d\n", tracks, nTempoUsec, ((UINT)division) & 0xFFFF, nTickMultiplier); #endif // Initializing - Order.assign(Order.size(), Order.GetInvalidPatIndex()); + Order.resize(MAX_ORDERS, Order.GetInvalidPatIndex()); memset(chnstate, 0, sizeof(chnstate)); memset(miditracks, 0, sizeof(miditracks)); memset(midichstate, 0, sizeof(midichstate)); Modified: trunk/OpenMPT/soundlib/Load_mod.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mod.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/Load_mod.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -291,7 +291,6 @@ pMagic = (PMODMAGIC)(lpStream+dwMemPos); dwMemPos += sizeof(MODMAGIC); if (m_nSamples == 15) dwMemPos -= 4; - Order.assign(Order.size(), 0); Order.ReadAsByte(pMagic->Orders, 128, 128); UINT nbp, nbpbuggy, nbpbuggy2, norders; @@ -315,7 +314,7 @@ } if (i >= nbpbuggy2) nbpbuggy2 = i+1; } - for (UINT iend=norders; iend<MAX_ORDERS; iend++) Order[iend] = Order.GetInvalidPatIndex(); + for (UINT iend = norders; iend < 0x80; iend++) Order[iend] = Order.GetInvalidPatIndex(); norders--; m_nRestartPos = pMagic->nRestartPos; if (m_nRestartPos >= 0x78) m_nRestartPos = 0; Modified: trunk/OpenMPT/soundlib/Load_mt2.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -204,9 +204,10 @@ { m_nDefaultTempo = 110250 / pfh->wSamplesPerTick; } - for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++) + Order.resize(pfh->nOrders, Order.GetInvalidPatIndex()); + for (UINT iOrd=0; iOrd < pfh->nOrders; iOrd++) { - Order[iOrd] = (BYTE)((iOrd < pfh->nOrders) ? pfh->Orders[iOrd] : 0xFF); + Order[iOrd] = (PATTERNINDEX)pfh->Orders[iOrd]; } memcpy(m_szNames[0], pfh->szSongName, 32); m_szNames[0][31] = 0; Modified: trunk/OpenMPT/soundlib/Load_okt.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_okt.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/Load_okt.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -107,6 +107,7 @@ { UINT orderlen = norders; if (orderlen >= MAX_ORDERS) orderlen = MAX_ORDERS-1; + Order.resize(orderlen); for (UINT i=0; i<orderlen; i++) Order[i] = lpStream[dwMemPos+10+i]; for (UINT j=orderlen; j>1; j--) { if (Order[j-1]) break; Order[j-1] = 0xFF; } dwMemPos += BigEndian(*((DWORD *)(lpStream + dwMemPos + 4))) + 8; Modified: trunk/OpenMPT/soundlib/Load_psm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -15,8 +15,8 @@ //#define PSM_LOG -#define PSM_ID_NEW 0x204d5350 -#define PSM_ID_OLD 0xfe4d5350 +#define PSM_ID_NEW 0x204d5350 // "PSM " +#define PSM_ID_OLD 0xfe4d5350 // "PSM\xFE" #define IFFID_FILE 0x454c4946 #define IFFID_TITL 0x4c544954 #define IFFID_SDFT 0x54464453 @@ -226,6 +226,7 @@ } } UINT iOrd = 0; + Order.resize(MAX_ORDERS, Order.GetInvalidPatIndex()); while ((pos+5<len) && (iOrd < MAX_ORDERS)) { DWORD dwName = *(DWORD *)(pdata+pos); Modified: trunk/OpenMPT/soundlib/Load_wav.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_wav.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/Load_wav.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -50,8 +50,8 @@ m_nDefaultSpeed = 8; m_nDefaultTempo = 125; m_dwSongFlags |= SONG_LINEARSLIDES; // For no resampling + Order.resize(MAX_ORDERS, Order.GetInvalidPatIndex()); Order[0] = 0; - Order[1] = 0xFF; bool fail = Patterns.Insert(0, 64); fail = Patterns.Insert(1, 64); if(fail) return true; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-20 16:46:12 UTC (rev 335) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-20 20:43:52 UTC (rev 336) @@ -508,7 +508,8 @@ memset(ChnMix, 0, sizeof(ChnMix)); memset(Chn, 0, sizeof(Chn)); memset(Instruments, 0, sizeof(Instruments)); - Order.assign(MAX_ORDERS, Order.GetInvalidPatIndex()); + //Order.assign(MAX_ORDERS, Order.GetInvalidPatIndex()); + Order.resize(1, Order.GetInvalidPatIndex()); Patterns.ClearPatterns(); memset(m_szNames, 0, sizeof(m_szNames)); memset(m_MixPlugins, 0, sizeof(m_MixPlugins)); @@ -706,7 +707,7 @@ if ((m_nRestartPos >= Order.size()) || (Order[m_nRestartPos] >= Patterns.Size())) m_nRestartPos = 0; // Load plugins only when m_pModDoc != 0. (can be == 0 for example when examining module samples in treeview. - CString sNotFound; + string sNotFound; bool bSearchIDs[MAX_MIXPLUGINS] = {false}; UINT iShowNotFound = 0; @@ -757,7 +758,7 @@ sNotFound = "The following plugins have not been found:\n\n" + sNotFound + "\nDo you want to search for them on KVRAudio?" "\nWARNING: A browser window / tab is opened for every plugin. If you do not want that, you can visit http://www.kvraudio.com/search.php"; } - if (::MessageBox(0, sNotFound, "OpenMPT - Plugins missing", MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION) == IDYES) + if (::MessageBox(0, sNotFound.c_str(), "OpenMPT - Plugins missing", MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION) == IDYES) for (UINT iPlug = 0; iPlug < MAX_MIXPLUGINS; iPlug++) if (bSearchIDs[iPlug] == true) { @@ -774,6 +775,7 @@ if (m_nType) { SetModSpecsPointer(m_pModSpecs, m_nType); + Order.resize(GetModSpecifications().ordersMax, Order.GetInvalidPatIndex()); return TRUE; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-08-22 22:48:10
|
Revision: 338 http://modplug.svn.sourceforge.net/modplug/?rev=338&view=rev Author: saga-games Date: 2009-08-22 22:47:59 +0000 (Sat, 22 Aug 2009) Log Message: ----------- [Fix] Macro config: "Show All" FX display starts at 1 instead of 0, like all other FX enumerations [Imp] PSM Loader: Several improvements; Near-perfect effect conversion. [Imp] XM Loader: Detecting MPT-Made XM files more reliably [Imp] Playback: If restart position is 0 and a subtune is played (i.e. a tune separated with a "---" pattern), OpenMPT will now try to jump back to the first order of this subtune instead. Modified Paths: -------------- trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-08-22 10:21:22 UTC (rev 337) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-08-22 22:47:59 UTC (rev 338) @@ -2096,7 +2096,7 @@ { pVstPlugin->GetParamName(param, s, 256); paramName = s; - line.Format("FX%d: %s\t Param %d (%x): %s\n", plug, plugName, param, param+80, paramName); + line.Format("FX%d: %s\t Param %d (%x): %s\n", plug + 1, plugName, param, param+80, paramName); message += line; } } Modified: trunk/OpenMPT/soundlib/Load_psm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-22 10:21:22 UTC (rev 337) +++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-22 22:47:59 UTC (rev 338) @@ -6,12 +6,14 @@ * and partly reverse-engineered. * * What's playing? - * - Epic Pinball - Seems to be working perfectly, apart from some portas? (esp. Deep Sea, Shareware Info - Linear freq slides needed!?) + * - Epic Pinball - Seems to be working perfectly with linear freq slides enabled * - Extreme Pinball - Default tempo / speed / restart position of subtunes is missing. * I'm using the last default values, restart position is still completely missing - * - Jazz Jackrabbit - Hmm, I don't like some of the portas, but apart from that it's great. (same problem as Epic Pinball) + * - Jazz Jackrabbit - Hmm, I don't like some of the portas (BONUS.PSM - the guitar portamento is too "deep"), but apart from that it's great. * - One Must Fall! - Perfect! (I modelled the volume slide and portamento conversion after this, as I got the original MTM files) * - Silverball - Currently not supported (old PSM16 format) + * + * Effect conversion should be about right, however I have my doubts wheter linear freq slides are used or not. */ #include "stdafx.h" @@ -55,7 +57,7 @@ struct PSMSAMPLEHEADER // Use this instead { BYTE flags; - CHAR sampleFormat[8]; + CHAR fileName[8]; DWORD sampleID; // INS0...INS9 (only last digit of sample ID, i.e. sample 1 and sample 11 are equal) CHAR sampleName[33]; CHAR unknown1[6]; // 00 00 00 00 00 FF @@ -72,13 +74,6 @@ #pragma pack() -BYTE convert_psm_param(BYTE param) -{ - // special conversion of some PSM parameters. is this done correctly? - return param >> 1; - //return (param + 1) >> 1; -} - bool CSoundFile::ReadPSM(const LPCBYTE lpStream, const DWORD dwMemLength) //----------------------------------------------------------------------- { @@ -97,7 +92,7 @@ // Yep, this seems to be a valid file. m_nType = MOD_TYPE_PSM; - //m_dwSongFlags |= SONG_LINEARSLIDES; // TODO + m_dwSongFlags |= SONG_LINEARSLIDES; // Seems to be correct for Epic Pinball and Jazz Jackrabbit? m_nChannels = 0; dwMemPos += 12; @@ -142,8 +137,11 @@ // Pattern ID (something like "P0 " or "P13 ") follows if(memcmp(lpStream + dwMemPos + 4, "P", 1)) return false; + char patternID[4]; + memcpy(patternID, lpStream + dwMemPos + 5, 3); + patternID[3] = 0; patternOffsets.push_back(dwMemPos + 8); - patternIDs.push_back(*(DWORD *)(lpStream + dwMemPos + 4)); + patternIDs.push_back(atoi(patternID)); numPatterns++; // Convert later as we have to know how many channels there are. @@ -177,12 +175,12 @@ { case 0x45544144: // "DATE" - Song date (YYMMDD) if(subChunkSize < 6) break; + CHAR cDate[7]; memcpy(cDate, lpStream + dwChunkPos, 6); cDate[6] = 0; sComment += "\r\nDate: "; sComment += cDate; - // We don't care about the date. break; case 0x484C504F: // "OPLH" - Order list, channel + module settings @@ -199,12 +197,20 @@ { switch(lpStream[dwSettingsOffset]) { + case 0x00: // Seems to be the End item + dwSettingsOffset += 1; + break; + case 0x01: // Order list item if(dwSettingsOffset - dwChunkPos + 5 > subChunkSize) return false; // Pattern name follows - find pattern (this is the orderlist) for(PATTERNINDEX i = 0; i < patternIDs.size(); i++) { - if(patternIDs[i] == *(DWORD *)(lpStream + dwSettingsOffset + 1)) + char patternID[4]; + memcpy(patternID, lpStream + dwSettingsOffset + 2, 3); + patternID[3] = 0; + DWORD nPattern = atoi(patternID); + if(patternIDs[i] == nPattern) { Order.push_back(i); break; @@ -213,9 +219,17 @@ dwSettingsOffset += 5; break; - case 0x04: // "end?" "04 03 00 00" in most cases (not Extreme Pinball - maybe restart positions are dumped here?) - if(dwSettingsOffset - dwChunkPos + 4 > subChunkSize) return false; - dwSettingsOffset += 4; + case 0x04: + /* It looks like the 2nd number of this chunk could be the restart position, + where position = ((number < 15) ? 0 : (number - 15)) */ + #ifdef DEBUG + { + char s[32]; + wsprintf(s, " - restart %d", (lpStream[dwSettingsOffset + 1] < 15) ? 0 : lpStream[dwSettingsOffset + 1] - 15); + sComment += s; + dwSettingsOffset += 3; + } + #endif break; case 0x07: // Default Speed @@ -243,12 +257,8 @@ if(dwSettingsOffset - dwChunkPos + 3 > subChunkSize) break; dwSettingsOffset += 3; break; - - case 0x00: // "end?" - dwSettingsOffset += 1; - break; - default: // How the hell should this happen? I've listened through all existing PSM files. :) + default: // How the hell should this happen? I've listened through all existing (original) PSM files. :) CString s; s.Format("Please report to the OpenMPT team: Unknown chunk %d found at position %d (in the OPLH chunk of this PSM file)", lpStream[dwSettingsOffset], dwSettingsOffset); MessageBox(NULL, s, TEXT("OpenMPT PSM import"), MB_ICONERROR); @@ -288,7 +298,9 @@ SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1); m_nSamples = max(m_nSamples, smp); memcpy(m_szNames[smp], pSample->sampleName, 31); - m_szNames[0][31] = 0; + m_szNames[smp][31] = 0; + memcpy(Samples[smp].filename, pSample->fileName, 8); + Samples[smp].filename[8] = 0; Samples[smp].nGlobalVol = 0x40; Samples[smp].nC5Speed = LittleEndianW(pSample->C5Freq); @@ -317,7 +329,6 @@ if(m_nChannels == 0) return false; - // Now that we know the number of channels, we can go through all the patterns. for(PATTERNINDEX i = 0; i < numPatterns; i++) { @@ -350,7 +361,7 @@ if(dwRowOffset + 1 > dwMemLength) return false; BYTE mask = lpStream[dwRowOffset]; // Point to the correct channel - MODCOMMAND *m = row_data + min(m_nChannels, lpStream[dwRowOffset + 1]); + MODCOMMAND *m = row_data + min(m_nChannels - 1, lpStream[dwRowOffset + 1]); dwRowOffset += 2; if(mask & 0x80) @@ -358,7 +369,10 @@ if(dwRowOffset + 1 > dwMemLength) return false; // Note present BYTE bNote = lpStream[dwRowOffset]; - bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13; + if(bNote == 0xFF) + bNote = NOTE_NOTECUT; + else + bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13; m->note = bNote; dwRowOffset++; } @@ -376,7 +390,7 @@ if(dwRowOffset + 1 > dwMemLength) return false; // Volume present m->volcmd = VOLCMD_VOLUME; - m->vol = (min(lpStream[dwRowOffset], 127)) >> 1; + m->vol = (min(lpStream[dwRowOffset], 127) + 1) >> 1; dwRowOffset++; } @@ -409,29 +423,29 @@ // Portamento case 0x0B: // fine portamento up command = CMD_PORTAMENTOUP; - param = 0xF0 | convert_psm_param(param); + param = 0xF0 | (param >> 1); break; case 0x0C: // portamento up command = CMD_PORTAMENTOUP; - param = convert_psm_param(param); + param >>= 1; break; case 0x0D: // fine portamento down command = CMD_PORTAMENTODOWN; - param = 0xF0 | convert_psm_param(param); + param = 0xF0 | (param >> 1); break; case 0x0E: // portamento down command = CMD_PORTAMENTODOWN; - param = convert_psm_param(param); + param >>= 1; break; case 0x0F: // tone portamento command = CMD_TONEPORTAMENTO; - param = convert_psm_param(param); + param >>= 2; break; - case 0x10: // glissando control + case 0x11: // glissando control command = CMD_S3MCMDEX; param = 0x10 | (param & 0x01); break; - case 0x11: // tone portamento + volslide up + case 0x10: // tone portamento + volslide up command = CMD_TONEPORTAVOL; param = param & 0xF0; break; @@ -472,9 +486,8 @@ param = lpStream[dwRowOffset + 2]; dwRowOffset += 2; break; - case 0x2A: // set finetune - command = CMD_S3MCMDEX; - param = 0x40 | (param & 0x0F); + case 0x2A: // retrigger + command = CMD_RETRIG; break; case 0x2B: // note cut command = CMD_S3MCMDEX; @@ -488,9 +501,11 @@ // Position change case 0x33: // position jump command = CMD_POSITIONJUMP; + param >>= 1; break; case 0x34: // pattern break command = CMD_PATTERNBREAK; + param >>= 1; break; case 0x35: // loop pattern command = CMD_S3MCMDEX; @@ -514,16 +529,22 @@ command = CMD_ARPEGGIO; break; case 0x48: // set finetune - command = CMD_MODCMDEX; - param = 0x50 | (param & 0x0F); + command = CMD_S3MCMDEX; + param = 0x20 | (param & 0x0F); break; case 0x49: // set balance command = CMD_S3MCMDEX; param = 0x80 | (param & 0x0F); break; + case CMD_MODCMDEX: + // for some strange home-made tunes + command = CMD_S3MCMDEX; + break; + default: - //ASSERT(false); + ASSERT(false); + //command = CMD_NONE; break; } Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-22 10:21:22 UTC (rev 337) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-22 22:47:59 UTC (rev 338) @@ -95,14 +95,22 @@ BYTE samples_used[(MAX_SAMPLES+7)/8]; UINT unused_samples; - bool bMadeWithModPlug = false; + bool bMadeWithModPlug = false, bProbablyMadeWithModPlug = false; // set this here already because XMs compressed with BoobieSqueezer will exit the function early SetModFlag(MSF_COMPATIBLE_PLAY, true); m_nChannels = 0; if ((!lpStream) || (dwMemLength < 0xAA)) return false; // the smallest XM I know is 174 Bytes if (_strnicmp((LPCSTR)lpStream, "Extended Module", 15)) return false; + memcpy(m_szNames[0], lpStream + 17, 20); + // look for null-terminated song name - that's most likely a tune made with modplug + for(int i = 0; i < 20; i++) + if(lpStream[17 + i] == 0) bProbablyMadeWithModPlug = true; + + if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true; + if (!memcmp((LPCSTR)lpStream + 0x26, "Open ModPlug Tracker", 20)) bMadeWithModPlug = true; + dwHdrSize = LittleEndian(*((DWORD *)(lpStream+60))); norders = LittleEndianW(*((WORD *)(lpStream+64))); if ((!norders) || (norders > MAX_ORDERS)) return false; @@ -328,6 +336,7 @@ min(ihsize - sizeof(XMINSTRUMENTHEADER), sizeof(XMSAMPLEHEADER))); xmsh.shsize = LittleEndian(xmsh.shsize); + if(xmsh.shsize == 0 && bProbablyMadeWithModPlug) bMadeWithModPlug = true; for (int i = 0; i < 24; ++i) { xmsh.venv[i] = LittleEndianW(xmsh.venv[i]); Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-22 10:21:22 UTC (rev 337) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-22 22:47:59 UTC (rev 338) @@ -645,6 +645,21 @@ if (!m_nRepeatCount) return FALSE; + ORDERINDEX nRestartPosOverride = m_nRestartPos; + if(!m_nRestartPos && m_nCurrentPattern <= Order.size()) + { + // if we're in a subtune and there's no restart position, go to the first order of the subtune + for(ORDERINDEX iOrd = m_nCurrentPattern - 1; iOrd > 0; iOrd--) + { + if(Order[iOrd] == Order.GetInvalidPatIndex()) + { + // Jump back to first order of this subtune + nRestartPosOverride = iOrd + 1; + break; + } + } + } + if(CMainFrame::GetMainFrame()) { // If channel resetting is disabled, we will emulate a pattern break @@ -652,7 +667,7 @@ m_dwSongFlags |= SONG_BREAKTOROW; } - if (!m_nRestartPos && !(m_dwSongFlags & SONG_BREAKTOROW)) + if (!nRestartPosOverride && !(m_dwSongFlags & SONG_BREAKTOROW)) { //rewbs.instroVSTi: stop all VSTi at end of song, if looping. StopAllVsti(); @@ -690,7 +705,7 @@ //Handle Repeat position if (m_nRepeatCount > 0) m_nRepeatCount--; - m_nCurrentPattern = m_nRestartPos; + m_nCurrentPattern = nRestartPosOverride; //m_nRow = 0; m_dwSongFlags &= ~SONG_BREAKTOROW; //If restart pos points to +++, move along This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-08-24 11:44:05
|
Revision: 340 http://modplug.svn.sourceforge.net/modplug/?rev=340&view=rev Author: saga-games Date: 2009-08-24 11:43:54 +0000 (Mon, 24 Aug 2009) Log Message: ----------- [Fix] IT Loader: Unset release env nodes for IT files made with IT 1.x, fix fadeout values [Imp] PSM Loader: Several fixes for "new new" PSM format, channel panning, etc. [Imp] S3M Loader: Don't write unnecessary invalid order items in the order table [Imp] LHA Decoder: Several fixes (patch by kode54) Modified Paths: -------------- trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/Load_s3m.cpp trunk/OpenMPT/unlha/EXTRACT.CPP trunk/OpenMPT/unlha/HUF.CPP trunk/OpenMPT/unlha/LHEXT.CPP trunk/OpenMPT/unlha/SLIDE.CPP trunk/OpenMPT/unlha/SLIDEHUF.H trunk/OpenMPT/unlha/UNLHA32.H trunk/OpenMPT/unlha/Unlha.cpp Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-08-23 21:07:17 UTC (rev 339) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-08-24 11:43:54 UTC (rev 340) @@ -230,7 +230,7 @@ const ITOLDINSTRUMENT *pis = (const ITOLDINSTRUMENT *)p; memcpy(pIns->name, pis->name, 26); memcpy(pIns->filename, pis->filename, 12); - pIns->nFadeOut = pis->fadeout << 6; + pIns->nFadeOut = pis->fadeout << 7; pIns->nGlobalVol = 64; for (UINT j=0; j<NOTE_MAX; j++) { @@ -260,6 +260,10 @@ pIns->nNNA = pis->nna; pIns->nDCT = pis->dnc; pIns->nPan = 0x80; + + pIns->VolEnv.nReleaseNode = ENV_RELEASE_NODE_UNSET; + pIns->PanEnv.nReleaseNode = ENV_RELEASE_NODE_UNSET; + pIns->PitchEnv.nReleaseNode = ENV_RELEASE_NODE_UNSET; } else { const ITINSTRUMENT *pis = (const ITINSTRUMENT *)p; @@ -276,7 +280,7 @@ } if (pis->mbank<=128) pIns->wMidiBank = pis->mbank; - pIns->nFadeOut = pis->fadeout << 5; + pIns->nFadeOut = pis->fadeout << 5; // should be 6? pIns->nGlobalVol = pis->gbv >> 1; if (pIns->nGlobalVol > 64) pIns->nGlobalVol = 64; for (UINT j=0; j<NOTE_MAX; j++) @@ -1281,7 +1285,7 @@ } // Load instrument and song extensions. - if(mptStartPos >= dwMemPos) + if(mptStartPos >= dwMemPos && mptStartPos < dwMemLength) { LPCBYTE ptr = LoadExtendedInstrumentProperties(lpStream + dwMemPos, lpStream + mptStartPos, &interpretModplugmade); LoadExtendedSongProperties(GetType(), ptr, lpStream, mptStartPos, &interpretModplugmade); @@ -2001,7 +2005,7 @@ //if (pIns->nDCT<DCT_PLUGIN) iti.dct = pIns->nDCT; else iti.dct =0; iti.dct = pIns->nDCT; //rewbs.instroVSTi: will other apps barf if they get an unknown DCT? iti.dca = pIns->nDNA; - iti.fadeout = pIns->nFadeOut >> 5; + iti.fadeout = pIns->nFadeOut >> 5; // should be 6? iti.pps = pIns->nPPS; iti.ppc = pIns->nPPC; iti.gbv = (BYTE)(pIns->nGlobalVol << 1); Modified: trunk/OpenMPT/soundlib/Load_psm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-23 21:07:17 UTC (rev 339) +++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-24 11:43:54 UTC (rev 340) @@ -38,7 +38,7 @@ }; -struct PSMSAMPLEHEADER // Regular sample header +struct PSMOLDSAMPLEHEADER // Regular sample header { BYTE flags; CHAR fileName[8]; // Filename of the original module (without extension) @@ -49,14 +49,15 @@ DWORD sampleLength; DWORD loopStart; DWORD loopEnd; // FF FF FF FF = end of sample - WORD unknown3; + BYTE unknown3; + BYTE defaulPan; // unused? BYTE defaultVolume; DWORD unknown4; WORD C5Freq; CHAR unknown5[21]; // 00 ... 00 }; -struct PSMSAMPLEHEADERSINARIA // Sinaria sample header +struct PSMNEWSAMPLEHEADER // Sinaria sample header (and possibly other games) { BYTE flags; CHAR fileName[8]; // Filename of the original module (without extension) @@ -68,20 +69,25 @@ DWORD loopStart; DWORD loopEnd; WORD unknown3; - BYTE unknown4; + BYTE defaultPan; // unused? BYTE defaultVolume; - DWORD unknown5; + DWORD unknown4; WORD C5Freq; - CHAR unknown6[16]; // 00 ... 00 + CHAR unknown5[16]; // 00 ... 00 }; #pragma pack() -BYTE convert_psm_effect(BYTE param, bool bIsSinaria) +BYTE convert_psm_porta(BYTE param, bool bNewFormat) { - if(bIsSinaria) + if(bNewFormat) + { return param; + } else - return (param >> 2); + { + if(param < 4) return param | 0xF0; + else return (param >> 2); + } } bool CSoundFile::ReadPSM(const LPCBYTE lpStream, const DWORD dwMemLength) @@ -91,7 +97,7 @@ if( dwMemPos > dwMemLength || x > dwMemLength - dwMemPos ) return false; DWORD dwMemPos = 0; - bool bIsSinaria = false; // The game "Sinaria" uses a slightly modified PSM structure + bool bNewFormat = false; // The game "Sinaria" uses a slightly modified PSM structure ASSERT_CAN_READ(12); PSMHEADER shdr; @@ -148,11 +154,11 @@ // Pattern ID (something like "P0 " or "P13 ") follows if(memcmp(lpStream + dwMemPos + 4, "P", 1)) return false; - if(!memcmp(lpStream + dwMemPos + 4, "PATT", 4)) bIsSinaria = true; + if(!memcmp(lpStream + dwMemPos + 4, "PATT", 4)) bNewFormat = true; char patternID[4]; - memcpy(patternID, lpStream + dwMemPos + 5 + (bIsSinaria ? 3 : 0), 3); + memcpy(patternID, lpStream + dwMemPos + 5 + (bNewFormat ? 3 : 0), 3); patternID[3] = 0; - patternOffsets.push_back(dwMemPos + 8 + (bIsSinaria ? 4 : 0)); + patternOffsets.push_back(dwMemPos + 8 + (bNewFormat ? 4 : 0)); patternIDs.push_back(atoi(patternID)); numPatterns++; @@ -185,23 +191,46 @@ switch(subChunkID) { - case 0x45544144: // "DATE" - Song date (YYMMDD) - if(subChunkSize < 6) break; + case 0x45544144: // "DATE" - Conversion date (YYMMDD) + if(subChunkSize != 6) break; + { + int version; + for(DWORD i = 0; i < subChunkSize; i++) + { + if(lpStream[dwChunkPos + i] >= '0' && lpStream[dwChunkPos + i] <= '9') + { + version = (version * 10) + (lpStream[dwChunkPos + i] - '0'); + } else + { + version = 0; + break; + } + } + if(version == 800211 || version == 940902 || version == 940903 || + version == 940906 || version == 940914 || version == 941213) + bNewFormat = true; + } + #ifdef DEBUG CHAR cDate[7]; memcpy(cDate, lpStream + dwChunkPos, 6); cDate[6] = 0; - sComment += " - Date: "; + sComment += " - Build Date: "; sComment += cDate; + if(bNewFormat) sComment += " (New Format)"; + else sComment += " (Old Format)"; + #endif break; case 0x484C504F: // "OPLH" - Order list, channel + module settings { if(subChunkSize < 9) return false; - // First two bytes = "Memory alloc, roughly ordlen + 10, if too small, song freezes" + // First two bytes = Number of chunks that follow + //WORD nTotalChunks = LittleEndian(*(WORD *)(lpStream + dwChunkPos)); // Now, the interesting part begins! DWORD dwSettingsOffset = dwChunkPos + 2; + WORD nChunkCount = 0, nFirstOrderChunk = (WORD)-1; while(dwSettingsOffset - dwChunkPos + 1 < subChunkSize) { switch(lpStream[dwSettingsOffset]) @@ -216,7 +245,7 @@ for(PATTERNINDEX i = 0; i < patternIDs.size(); i++) { char patternID[4]; - memcpy(patternID, lpStream + dwSettingsOffset + 2 + (bIsSinaria ? 3 : 0), 3); + memcpy(patternID, lpStream + dwSettingsOffset + 2 + (bNewFormat ? 3 : 0), 3); patternID[3] = 0; DWORD nPattern = atoi(patternID); if(patternIDs[i] == nPattern) @@ -225,23 +254,25 @@ break; } } - dwSettingsOffset += 5 + (bIsSinaria ? 4 : 0); + if(nFirstOrderChunk == (WORD)-1) nFirstOrderChunk = nChunkCount; + dwSettingsOffset += 5 + (bNewFormat ? 4 : 0); break; - case 0x04: - /* It looks like the 2nd number of this chunk could be the restart position, - where position = ((number < 15) ? 0 : (number - 15)) */ - - //uint32 pos = lpStream[dwSettingsOffset + 1] | (lpStream[dwSettingsOffset + 2] << 8); - - // NOTE: This should not be global! (Extreme Pinball!!!) - #ifdef DEBUG + case 0x04: // Restart position { - char s[32]; - wsprintf(s, " - restart %d", (lpStream[dwSettingsOffset + 1] < 15) ? 0 : lpStream[dwSettingsOffset + 1] - 15); - sComment += s; + // NOTE: This should not be global! (Extreme Pinball!!!) + WORD nRestartChunk = LittleEndian(*(WORD *)(lpStream + dwSettingsOffset + 1)); + ORDERINDEX nRestartPosition = 0; + if(nRestartChunk == 0) nRestartPosition = 0; + else if(nRestartChunk >= nFirstOrderChunk) nRestartPosition = (ORDERINDEX)(nRestartChunk - nFirstOrderChunk); + #ifdef DEBUG + { + char s[32]; + wsprintf(s, " - restart pos %d", nRestartPosition); + sComment += s; + } + #endif } - #endif dwSettingsOffset += 3; break; @@ -277,7 +308,7 @@ switch(lpStream[dwSettingsOffset + 3]) { case 0: - ChnSettings[nChn].nPan = lpStream[dwSettingsOffset + 2]; + ChnSettings[nChn].nPan = lpStream[dwSettingsOffset + 2] ^ 128; break; case 2: @@ -309,6 +340,7 @@ break; } + nChunkCount++; } Order.push_back(Order.GetInvalidPatIndex()); } @@ -322,7 +354,7 @@ switch(lpStream[dwChunkPos + i]) { case 0: - ChnSettings[i >> 1].nPan = lpStream[dwChunkPos + i + 1] - 128; + ChnSettings[i >> 1].nPan = lpStream[dwChunkPos + i + 1] ^ 128; break; case 2: @@ -357,10 +389,10 @@ break; case 0x504D5344: // DSMP - Samples - if(!bIsSinaria) + if(!bNewFormat) { - if(chunkSize < sizeof(PSMSAMPLEHEADER)) return false; - PSMSAMPLEHEADER *pSample = (PSMSAMPLEHEADER *)(lpStream + dwMemPos); + if(chunkSize < sizeof(PSMOLDSAMPLEHEADER)) return false; + PSMOLDSAMPLEHEADER *pSample = (PSMOLDSAMPLEHEADER *)(lpStream + dwMemPos); SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1); m_nSamples = max(m_nSamples, smp); memcpy(m_szNames[smp], pSample->sampleName, 31); @@ -379,12 +411,12 @@ if(Samples[smp].nLoopEnd == 0xFFFFFF) Samples[smp].nLoopEnd = Samples[smp].nLength; // Delta-encoded samples - ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMSAMPLEHEADER)), Samples[smp].nLength); + ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMOLDSAMPLEHEADER)), Samples[smp].nLength); } else { // Sinaria uses a slightly different sample header - if(chunkSize < sizeof(PSMSAMPLEHEADERSINARIA)) return false; - PSMSAMPLEHEADERSINARIA *pSample = (PSMSAMPLEHEADERSINARIA *)(lpStream + dwMemPos); + if(chunkSize < sizeof(PSMNEWSAMPLEHEADER)) return false; + PSMNEWSAMPLEHEADER *pSample = (PSMNEWSAMPLEHEADER *)(lpStream + dwMemPos); SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1); m_nSamples = max(m_nSamples, smp); memcpy(m_szNames[smp], pSample->sampleName, 31); @@ -403,7 +435,7 @@ if(Samples[smp].nLoopEnd == 0xFFFFFF) Samples[smp].nLoopEnd = Samples[smp].nLength; // Delta-encoded samples - ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMSAMPLEHEADERSINARIA)), Samples[smp].nLength); + ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMNEWSAMPLEHEADER)), Samples[smp].nLength); } break; @@ -419,24 +451,24 @@ if(m_nChannels == 0) return false; // Now that we know the number of channels, we can go through all the patterns. - for(PATTERNINDEX i = 0; i < numPatterns; i++) + for(PATTERNINDEX nPat = 0; nPat < numPatterns; nPat++) { - DWORD dwPatternOffset = patternOffsets[i]; + DWORD dwPatternOffset = patternOffsets[nPat]; if(dwPatternOffset + 2 > dwMemLength) return false; WORD patternSize = LittleEndianW(*(WORD *)(lpStream + dwPatternOffset)); dwPatternOffset += 2; - if(Patterns.Insert(i, patternSize)) + if(Patterns.Insert(nPat, patternSize)) { CString s; - s.Format(TEXT("Allocating patterns failed starting from pattern %u"), i); + s.Format(TEXT("Allocating patterns failed starting from pattern %u"), nPat); MessageBox(NULL, s, TEXT("OpenMPT PSM import"), MB_ICONERROR); break; } // Read pattern. MODCOMMAND *row_data; - row_data = Patterns[i]; + row_data = Patterns[nPat]; for(int nRow = 0; nRow < patternSize; nRow++) { @@ -458,15 +490,15 @@ if(dwRowOffset + 1 > dwMemLength) return false; // Note present BYTE bNote = lpStream[dwRowOffset]; - if(!bIsSinaria) + if(!bNewFormat) { if(bNote == 0xFF) bNote = NOTE_NOTECUT; else - bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13; + if(bNote < 129) bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13; } else { - bNote += 36; + if(bNote < 85) bNote += 36; } m->note = bNote; dwRowOffset++; @@ -500,41 +532,45 @@ // Volslides case 0x01: // fine volslide up command = CMD_VOLUMESLIDE; - param = (param << 3) | 0x0F; + if (bNewFormat) param = (param << 4) | 0x0F; + else param = ((param & 0x1E) << 3) | 0x0F; break; case 0x02: // volslide up command = CMD_VOLUMESLIDE; - param = (param << 3); + if (bNewFormat) param = 0xF0 & (param << 4); + else param = 0xF0 & (param << 3); break; case 0x03: // fine volslide down command = CMD_VOLUMESLIDE; - param = 0xF0 | (param >> 1); + if (bNewFormat) param |= 0xF0; + else param = 0xF0 | (param >> 1); break; case 0x04: // volslide down command = CMD_VOLUMESLIDE; - param >>= 1; + if (bNewFormat) param &= 0x0F; + else param = (param >> 1) & 0x0F; break; // Portamento case 0x0B: // fine portamento up command = CMD_PORTAMENTOUP; - param = 0xF0 | convert_psm_effect(param, bIsSinaria); + param = 0xF0 | convert_psm_porta(param, bNewFormat); break; case 0x0C: // portamento up command = CMD_PORTAMENTOUP; - param = convert_psm_effect(param, bIsSinaria); + param = convert_psm_porta(param, bNewFormat); break; case 0x0D: // fine portamento down command = CMD_PORTAMENTODOWN; - param = 0xF0 | convert_psm_effect(param, bIsSinaria); + param = 0xF0 | convert_psm_porta(param, bNewFormat); break; case 0x0E: // portamento down command = CMD_PORTAMENTODOWN; - param = convert_psm_effect(param, bIsSinaria); + param = convert_psm_porta(param, bNewFormat); break; case 0x0F: // tone portamento command = CMD_TONEPORTAMENTO; - param = convert_psm_effect(param, bIsSinaria); + if(!bNewFormat) param >>= 2; break; case 0x11: // glissando control command = CMD_S3MCMDEX; Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-23 21:07:17 UTC (rev 339) +++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-24 11:43:54 UTC (rev 340) @@ -513,10 +513,9 @@ //TODO: Check whether the 0xF0 mask is correct. // (there are two bytes reserved from the header, so why 0xF0 mask?). //nbo = (GetNumPatterns() + 15) & 0xF0; - nbo = Order.GetLengthTailTrimmed() + 15; + nbo = Order.GetLengthTailTrimmed(); if(nbo > 0xF0) nbo = 0xF0; - nbo = nbo & 0xF0; - if (!nbo) nbo = 16; + if (!nbo) nbo = 1; header[0x20] = nbo & 0xFF; header[0x21] = nbo >> 8; nbi = m_nInstruments; Modified: trunk/OpenMPT/unlha/EXTRACT.CPP =================================================================== --- trunk/OpenMPT/unlha/EXTRACT.CPP 2009-08-23 21:07:17 UTC (rev 339) +++ trunk/OpenMPT/unlha/EXTRACT.CPP 2009-08-24 11:43:54 UTC (rev 340) @@ -16,7 +16,7 @@ switch (method) { case 0: - case 8: + case 10: { int len1 = m_dwOutputLen - (int)(outfp - m_lpOutputFile); int len2 = m_dwStreamLen - infp; @@ -30,14 +30,22 @@ crc = 0; } break; - case 6: // -lzs- + case 8: // -lzs- LzInterface.dicbit = 11; decode(&LzInterface); break; case 1: // -lh1- case 4: // -lh4- - case 7: // -lz5- + case 9: // -lz5- LzInterface.dicbit = 12; + decode(&LzInterface); + break; + case 6: // -lh6- + LzInterface.dicbit = 15; + decode(&LzInterface); + break; + case 7: // -lh7- + LzInterface.dicbit = 16; default: decode(&LzInterface); } Modified: trunk/OpenMPT/unlha/HUF.CPP =================================================================== --- trunk/OpenMPT/unlha/HUF.CPP 2009-08-23 21:07:17 UTC (rev 339) +++ trunk/OpenMPT/unlha/HUF.CPP 2009-08-24 11:43:54 UTC (rev 340) @@ -4,7 +4,7 @@ #define NP (MAX_DICBIT + 1) #define NT (USHRT_BIT + 3) -#define PBIT 4 /* smallest integer such that (1 << PBIT) > NP */ +//#define PBIT 4 /* smallest integer such that (1 << PBIT) > NP */ #define TBIT 5 /* smallest integer such that (1 << TBIT) > NT */ #define NPT 0x80 @@ -16,8 +16,10 @@ t_freq[2 * NT - 1]; } HUFDATA; -HUFDATA *gpHufData = NULL; +//HUFDATA *gpHufData = NULL; +#define gpHufData (*((HUFDATA **)&m_pHufData)) + VOID CLhaArchive::InitHufTables() { gpHufData = (HUFDATA *)(m_pDecoderData + 4096); @@ -104,7 +106,7 @@ blocksize = getbits(16); read_pt_len(NT, TBIT, 3); read_c_len(); - read_pt_len(NP, PBIT, -1); + read_pt_len(np, pbit, -1); } blocksize--; j = gpHufData->c_table[bitbuf >> 4]; @@ -125,21 +127,28 @@ unsigned short j, mask; j = gpHufData->pt_table[bitbuf >> (16 - 8)]; - if (j < NP) fillbuf(gpHufData->pt_len[j]); + if (j < np) fillbuf(gpHufData->pt_len[j]); else { fillbuf(8); mask = 1 << (16 - 1); do { j = (bitbuf & mask) ? right[j] : left[j]; mask >>= 1; - } while (j >= NP); + } while (j >= np); fillbuf(gpHufData->pt_len[j] - 8); } if (j != 0) j = (1 << (j - 1)) + getbits(j - 1); return j; } -void CLhaArchive::decode_start_st1() +void CLhaArchive::decode_start_st1(int dicbit) { + switch (dicbit) + { + case 12: + case 13: pbit = 4; np = 14; break; + case 15: pbit = 5; np = 16; break; + case 16: pbit = 5; np = 17; break; + } init_getbits(); blocksize = 0; } Modified: trunk/OpenMPT/unlha/LHEXT.CPP =================================================================== --- trunk/OpenMPT/unlha/LHEXT.CPP 2009-08-23 21:07:17 UTC (rev 339) +++ trunk/OpenMPT/unlha/LHEXT.CPP 2009-08-24 11:43:54 UTC (rev 340) @@ -26,10 +26,10 @@ } -const char *methods[10] = +const char *methods[12] = { - "-lh0-", "-lh1-", "-lh2-", "-lh3-", "-lh4-", - "-lh5-", "-lzs-", "-lz5-", "-lz4-", NULL + "-lh0-", "-lh1-", "-lh2-", "-lh3-", "-lh4-", "-lh5-", + "-lh6-", "-lh7-", "-lzs-", "-lz5-", "-lz4-", NULL }; Modified: trunk/OpenMPT/unlha/SLIDE.CPP =================================================================== --- trunk/OpenMPT/unlha/SLIDE.CPP 2009-08-23 21:07:17 UTC (rev 339) +++ trunk/OpenMPT/unlha/SLIDE.CPP 2009-08-24 11:43:54 UTC (rev 340) @@ -43,17 +43,19 @@ { case 1: decode_start_dyn(); break; case 2: decode_start_st0(); break; - case 3: decode_start_st1(); break; - case 4: decode_start_st1(); break; - case 5: decode_start_lzs(); break; - case 6: decode_start_lz5(text); break; + case 3: decode_start_st1(12); break; + case 4: decode_start_st1(13); break; + case 5: decode_start_st1(15); break; + case 6: decode_start_st1(16); break; + case 7: decode_start_lzs(); break; + case 8: decode_start_lz5(text); break; default: decode_start_fix(); break; } #ifdef LHADEBUG Log("Starting Decode (original size=%d)...\n", pinterface->original); #endif dicsiz1 = dicsiz - 1; - offset = (pinterface->method == 6) ? 0x100 - 2 : 0x100 - 3; + offset = (pinterface->method == 8) ? 0x100 - 2 : 0x100 - 3; count = 0; loc = 0; while (count < pinterface->original) @@ -64,8 +66,10 @@ case 2: c = decode_c_st0(); break; case 3: c = decode_c_st1(); break; case 4: c = decode_c_st1(); break; - case 5: c = decode_c_lzs(); break; - case 6: c = decode_c_lz5(); break; + case 5: c = decode_c_st1(); break; + case 6: c = decode_c_st1(); break; + case 7: c = decode_c_lzs(); break; + case 8: c = decode_c_lz5(); break; default: c = decode_c_dyn(); break; } if (c <= 255) @@ -86,8 +90,10 @@ case 2: d = decode_p_st0(); break; case 3: d = decode_p_st1(); break; case 4: d = decode_p_st1(); break; - case 5: d = decode_p_lzs(); break; - case 6: d = decode_p_lz5(); break; + case 5: d = decode_p_st1(); break; + case 6: d = decode_p_st1(); break; + case 7: d = decode_p_lzs(); break; + case 8: d = decode_p_lz5(); break; default: d = decode_p_st0(); break; } int j = c - offset; Modified: trunk/OpenMPT/unlha/SLIDEHUF.H =================================================================== --- trunk/OpenMPT/unlha/SLIDEHUF.H 2009-08-23 21:07:17 UTC (rev 339) +++ trunk/OpenMPT/unlha/SLIDEHUF.H 2009-08-24 11:43:54 UTC (rev 340) @@ -11,7 +11,7 @@ /* from slide.c */ -#define MAX_DICBIT 13 +#define MAX_DICBIT 16 // 13 #define MAX_DICSIZ (1 << MAX_DICBIT) #define MATCHBIT 8 /* bits for MAXMATCH - THRESHOLD */ Modified: trunk/OpenMPT/unlha/UNLHA32.H =================================================================== --- trunk/OpenMPT/unlha/UNLHA32.H 2009-08-23 21:07:17 UTC (rev 339) +++ trunk/OpenMPT/unlha/UNLHA32.H 2009-08-24 11:43:54 UTC (rev 340) @@ -72,9 +72,10 @@ unsigned short *freq; unsigned char *buf; unsigned short bufsiz, blocksize; - unsigned int np; + unsigned int np, pbit; + void * m_pHufData; int flag, flagcnt, matchpos, prev_char; - unsigned short dicsiz, dicbit, maxmatch, loc; + unsigned int dicsiz, dicbit, maxmatch, loc; unsigned short left[2 * NC - 1], right[2 * NC - 1]; protected: @@ -113,7 +114,7 @@ protected: // huf.cpp VOID InitHufTables(); - void decode_start_st1(); + void decode_start_st1(int dicbit); void read_pt_len(short nn, short nbit, short i_special); void read_c_len(); unsigned short decode_c_st1(); Modified: trunk/OpenMPT/unlha/Unlha.cpp =================================================================== --- trunk/OpenMPT/unlha/Unlha.cpp 2009-08-23 21:07:17 UTC (rev 339) +++ trunk/OpenMPT/unlha/Unlha.cpp 2009-08-24 11:43:54 UTC (rev 340) @@ -69,6 +69,8 @@ m_lpOutputFile = 0; m_dwOutputLen = 0; m_pDecoderData = NULL; + + gpHufData = NULL; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-08-24 20:58:07
|
Revision: 341 http://modplug.svn.sourceforge.net/modplug/?rev=341&view=rev Author: saga-games Date: 2009-08-24 20:57:36 +0000 (Mon, 24 Aug 2009) Log Message: ----------- [Fix] MOD / XM Loading / Saving: More intelligent conversion of Speed / Tempo commands [Fix] MOD Loading: Last pattern was not loading in .MODs that have no samples [Ref] Made some CSoundFile functions private Modified Paths: -------------- trunk/OpenMPT/mptrack/typedefs.h trunk/OpenMPT/soundlib/Load_mod.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/typedefs.h =================================================================== --- trunk/OpenMPT/mptrack/typedefs.h 2009-08-24 11:43:54 UTC (rev 340) +++ trunk/OpenMPT/mptrack/typedefs.h 2009-08-24 20:57:36 UTC (rev 341) @@ -34,6 +34,8 @@ typedef uint32 ROWINDEX; const ROWINDEX ROWINDEX_MAX = uint32_max; typedef uint16 CHANNELINDEX; + const CHANNELINDEX CHANNELINDEX_MAX = uint16_max; + const CHANNELINDEX CHANNELINDEX_INVALID = CHANNELINDEX_MAX; typedef uint16 ORDERINDEX; const ORDERINDEX ORDERINDEX_MAX = uint16_max; const ORDERINDEX ORDERINDEX_INVALID = ORDERINDEX_MAX; Modified: trunk/OpenMPT/soundlib/Load_mod.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mod.cpp 2009-08-24 11:43:54 UTC (rev 340) +++ trunk/OpenMPT/soundlib/Load_mod.cpp 2009-08-24 20:57:36 UTC (rev 341) @@ -41,7 +41,7 @@ case 0x0D: command = CMD_PATTERNBREAK; param = ((param >> 4) * 10) + (param & 0x0F); break; case 0x0E: command = CMD_MODCMDEX; break; case 0x0F: command = (param <= (UINT)((m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) ? 0x1F : 0x20)) ? CMD_SPEED : CMD_TEMPO; - if ((param == 0xFF) && (m_nSamples == 15)) command = 0; break; //<rewbs> what the hell is this?! :) //<jojo> it's the "stop tune" command! :-P + if ((param == 0xFF) && (m_nSamples == 15) && (m_nType & MOD_TYPE_MOD)) command = 0; break; //<rewbs> what the hell is this?! :) //<jojo> it's the "stop tune" command! :-P // Extension for XM extended effects case 'G' - 55: command = CMD_GLOBALVOLUME; break; //16 case 'H' - 55: command = CMD_GLOBALVOLSLIDE; if (param & 0xF0) param &= 0xF0; break; @@ -97,16 +97,24 @@ case CMD_TREMOLO: command = 0x07; break; case CMD_PANNING8: command = 0x08; - if (bXM) + if(m_nType & MOD_TYPE_S3M) { - if (!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (m_nType != MOD_TYPE_XM) && (param <= 0x80)) + if(param <= 0x80) { - param <<= 1; - if (param > 255) param = 255; + param = min(param << 1, 0xFF); } - } else - { - if ((m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) || (m_nType == MOD_TYPE_XM)) param >>= 1; + else if(param == 0xA4) + { + if(bCompatibilityExport || !bXM) + { + command = param = 0; + } + else + { + command = 'X' - 55; + param = 91; + } + } } break; case CMD_OFFSET: command = 0x09; break; @@ -115,8 +123,8 @@ case CMD_VOLUME: command = 0x0C; break; case CMD_PATTERNBREAK: command = 0x0D; param = ((param / 10) << 4) | (param % 10); break; case CMD_MODCMDEX: command = 0x0E; break; - case CMD_SPEED: command = 0x0F; if (param > 0x20) param = 0x20; break; - case CMD_TEMPO: if (param >= 0x20) { command = 0x0F; break; } + case CMD_SPEED: command = 0x0F; param = min(param, (bXM) ? 0x1F : 0x20); break; + case CMD_TEMPO: command = 0x0F; param = max(param, (bXM) ? 0x20 : 0x21); break; case CMD_GLOBALVOLUME: command = 'G' - 55; break; case CMD_GLOBALVOLSLIDE: command = 'H' - 55; break; case CMD_KEYOFF: command = 'K' - 55; break; @@ -355,7 +363,7 @@ if (ipat < MAX_PATTERNS) { if(Patterns.Insert(ipat, 64)) break; - if (dwMemPos + m_nChannels*256 >= dwMemLength) break; + if (dwMemPos + m_nChannels * 256 > dwMemLength) break; MODCOMMAND *m = Patterns[ipat]; LPCBYTE p = lpStream + dwMemPos; for (UINT j=m_nChannels*64; j; m++,p+=4,j--) @@ -371,18 +379,21 @@ } dwMemPos += m_nChannels*256; } - // Reading instruments + + // Reading samples DWORD dwErrCheck = 0; - for (UINT ismp=1; ismp<=m_nSamples; ismp++) if (Samples[ismp].nLength) + for (UINT ismp = 1; ismp <= m_nSamples; ismp++) if (Samples[ismp].nLength) { - LPSTR p = (LPSTR)(lpStream+dwMemPos); + LPSTR p = (LPSTR)(lpStream + dwMemPos); UINT flags = 0; - if (dwMemPos + 5 >= dwMemLength) break; - if (!_strnicmp(p, "ADPCM", 5)) + if (dwMemPos + 5 <= dwMemLength) { - flags = 3; - p += 5; - dwMemPos += 5; + if (!_strnicmp(p, "ADPCM", 5)) + { + flags = 3; + p += 5; + dwMemPos += 5; + } } DWORD dwSize = ReadSample(&Samples[ismp], flags, p, dwMemLength - dwMemPos); if (dwSize) @@ -394,7 +405,7 @@ #ifdef MODPLUG_TRACKER return true; #else - return (dwErrCheck) ? TRUE : FALSE; + return (dwErrCheck) ? true : false; #endif } Modified: trunk/OpenMPT/soundlib/Load_psm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-24 11:43:54 UTC (rev 340) +++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-24 20:57:36 UTC (rev 341) @@ -77,17 +77,9 @@ }; #pragma pack() -BYTE convert_psm_porta(BYTE param, bool bNewFormat) +inline BYTE convert_psm_porta(BYTE param, bool bNewFormat) { - if(bNewFormat) - { - return param; - } - else - { - if(param < 4) return param | 0xF0; - else return (param >> 2); - } + return ((bNewFormat) ? (param) : ((param < 4) ? (param | 0xF0) : (param >> 2))); } bool CSoundFile::ReadPSM(const LPCBYTE lpStream, const DWORD dwMemLength) @@ -109,7 +101,6 @@ // Yep, this seems to be a valid file. m_nType = MOD_TYPE_PSM; - //m_dwSongFlags |= SONG_LINEARSLIDES; // TODO m_nChannels = 0; dwMemPos += 12; @@ -207,6 +198,7 @@ break; } } + // Sinaria song dates if(version == 800211 || version == 940902 || version == 940903 || version == 940906 || version == 940914 || version == 941213) bNewFormat = true; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-24 11:43:54 UTC (rev 340) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-24 20:57:36 UTC (rev 341) @@ -3040,3 +3040,152 @@ return *p; } +/* Try to write an (volume) effect in a given channel or any channel of a pattern in a specific row. + Usage: nPat - Pattern that should be modified + nRow - Row that should be modified + nEffect - (Volume) Effect that should be written + nParam - Effect that should be written + bIsVolumeEffect - Indicates whether the given effect is a volume effect or not + nChn - Channel that should be modified - use CHANNELINDEX_INVALID to allow all channels of the given row + bAllowMultipleEffects - If false, No effect will be written if an effect of the same type is already present in the channel(s) + bAllowNextRow - Indicates whether it is allowed to use the next row if there's no space for the effect + bRetry - For internal use only. Indicates whether an effect "rewrite" has already taken place (for recursive calls) +*/ +bool CSoundFile::TryWriteEffect(PATTERNINDEX nPat, ROWINDEX nRow, BYTE nEffect, BYTE nParam, bool bIsVolumeEffect, CHANNELINDEX nChn, bool bAllowMultipleEffects, bool bAllowNextRow, bool bRetry) +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +{ + // NOTE: Effect remapping is only implemented for a few basic effects. + CHANNELINDEX nScanChnMin = nChn, nScanChnMax = nChn; + MODCOMMAND *p = Patterns[nPat], *m; + + // Scan all channels + if(nChn == CHANNELINDEX_INVALID) + { + nScanChnMin = 0; + nScanChnMax = m_nChannels - 1; + } + + // Scan channel(s) for same effect type - if an effect of the same type is already present, exit. + if(bAllowMultipleEffects == false) + { + for(CHANNELINDEX i = nScanChnMin; i <= nScanChnMax; i++) + { + m = p + nRow * m_nChannels + i; + if(!bIsVolumeEffect && m->command == nEffect) + return true; + if(bIsVolumeEffect && m->volcmd == nEffect) + return true; + } + } + + // Easy case: check if there's some space left to put the effect somewhere + for(CHANNELINDEX i = nScanChnMin; i <= nScanChnMax; i++) + { + m = p + nRow * m_nChannels + i; + if(!bIsVolumeEffect && m->command == CMD_NONE) + { + m->command = nEffect; + m->param = nParam; + return true; + } + if(bIsVolumeEffect && m->volcmd == VOLCMD_NONE) + { + m->volcmd = nEffect; + m->vol = nParam; + return true; + } + } + + // Ok, apparently there's no space. If we haven't tried already, try to map it to the volume column or effect column instead. + if(bRetry == true) { + // Move some effects that also work in the volume column, so there's place for our new effect. + if(!bIsVolumeEffect) + { + for(CHANNELINDEX i = nScanChnMin; i <= nScanChnMax; i++) + { + m = p + nRow * m_nChannels + i; + switch(m->command) + { + case CMD_VOLUME: + m->volcmd = VOLCMD_VOLUME; + m->vol = m->param; + m->command = nEffect; + m->param = nParam; + return true; + + case CMD_PANNING8: + if(m_nType & MOD_TYPE_S3M && nParam > 0x80) + break; + + m->volcmd = VOLCMD_VOLUME; + m->command = nEffect; + + if(m_nType & MOD_TYPE_S3M) + { + m->vol = m->param >> 1; + } + else + { + m->vol = (m->param >> 2) + 1; + } + + m->param = nParam; + return true; + } + } + } + + // Let's try it again by writing into the "other" effect column. + BYTE nNewEffect = CMD_NONE; + if(bIsVolumeEffect) + { + switch(nEffect) + { + case VOLCMD_PANNING: + nNewEffect = CMD_PANNING8; + if(m_nType & MOD_TYPE_S3M) + nParam <<= 1; + else + nParam = min(nParam << 2, 0xFF); + break; + case VOLCMD_VOLUME: + nNewEffect = CMD_VOLUME; + break; + } + } else + { + switch(nEffect) + { + case CMD_PANNING8: + nNewEffect = VOLCMD_PANNING; + if(m_nType & MOD_TYPE_S3M) + { + if(nParam <= 0x80) + nParam >>= 1; + else + nNewEffect = CMD_NONE; + } + else + { + nParam = (nParam >> 2) + 1; + } + break; + case CMD_VOLUME: + nNewEffect = CMD_VOLUME; + break; + } + } + if(nNewEffect != CMD_NONE) + { + if(TryWriteEffect(nPat, nRow, nNewEffect, nParam, !bIsVolumeEffect, nChn, bAllowMultipleEffects, bAllowNextRow, false) == true) return true; + } + } + + // Try in the next row if possible (this may also happen if we already retried) + if(bAllowNextRow && (nRow + 1 < Patterns[nPat].GetNumRows())) + { + return TryWriteEffect(nPat, nRow + 1, nEffect, nParam, bIsVolumeEffect, nChn, bAllowMultipleEffects, bAllowNextRow, bRetry); + } + + return false; +} Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-08-24 11:43:54 UTC (rev 340) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-08-24 20:57:36 UTC (rev 341) @@ -1148,7 +1148,15 @@ void CheckNNA(UINT nChn, UINT instr, int note, BOOL bForceCut); void NoteChange(UINT nChn, int note, BOOL bPorta=FALSE, BOOL bResetEnv=TRUE, BOOL bManual=FALSE); void InstrumentChange(MODCHANNEL *pChn, UINT instr, BOOL bPorta=FALSE,BOOL bUpdVol=TRUE,BOOL bResetEnv=TRUE); + // Channel Effects + void KeyOff(UINT nChn); + // Global Effects + void SetTempo(UINT param, bool setAsNonModcommand = false); + void SetSpeed(UINT param); + +private: + // Channel Effects void PortamentoUp(MODCHANNEL *pChn, UINT param, const bool fineAsRegular = false); void PortamentoDown(MODCHANNEL *pChn, UINT param, const bool fineAsRegular = false); void MidiPortamento(MODCHANNEL *pChn, int param); @@ -1170,7 +1178,6 @@ void RetrigNote(UINT nChn, UINT param, UINT offset=0); //rewbs.volOffset: added last param void SampleOffset(UINT nChn, UINT param, bool bPorta); //rewbs.volOffset: moved offset code to own method void NoteCut(UINT nChn, UINT nTick); - void KeyOff(UINT nChn); int PatternLoop(MODCHANNEL *, UINT param); void ExtendedMODCommands(UINT nChn, UINT param); void ExtendedS3MCommands(UINT nChn, UINT param); @@ -1180,12 +1187,14 @@ void SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier=256) const; // Low-Level effect processing void DoFreqSlide(MODCHANNEL *pChn, LONG nFreqSlide); - // Global Effects - void SetTempo(UINT param, bool setAsNonModcommand = false); - void SetSpeed(UINT param); void GlobalVolSlide(UINT param, UINT * nOldGlobalVolSlide); DWORD IsSongFinished(UINT nOrder, UINT nRow) const; BOOL IsValidBackwardJump(UINT nStartOrder, UINT nStartRow, UINT nJumpOrder, UINT nJumpRow) const; +public: + + // Write pattern effect functions + bool TryWriteEffect(PATTERNINDEX nPat, ROWINDEX nRow, BYTE nEffect, BYTE nParam, bool bIsVolumeEffect, CHANNELINDEX nChn = CHANNELINDEX_INVALID, bool bAllowMultipleEffects = true, bool bAllowNextRow = false, bool bRetry = true); + // Read/Write sample functions char GetDeltaValue(char prev, UINT n) const { return (char)(prev + CompressionTable[n & 0x0F]); } UINT PackSample(int &sample, int next); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-08-25 01:18:28
|
Revision: 342 http://modplug.svn.sourceforge.net/modplug/?rev=342&view=rev Author: saga-games Date: 2009-08-25 01:18:21 +0000 (Tue, 25 Aug 2009) Log Message: ----------- [Fix] IT Compatibility: Don't reset Tremolo on new note, don't ignore tremolo if note volume is 0 [Fix] IT Compatibility: Fixed Tremolo, Vibrato and Panbrello tables [Fix] IT Compatibility: Ignore S[345]x with x > 3 [Imp] XM Loader: detect a very old MPT version Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndmix.cpp trunk/OpenMPT/soundlib/Tables.cpp Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-24 20:57:36 UTC (rev 341) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-25 01:18:21 UTC (rev 342) @@ -2742,6 +2742,11 @@ case 0x30: // vibrato waveform case 0x40: // tremolo waveform case 0x50: // panbrello waveform + if(((param & 0x0F) > 0x03) && m_SndFile.IsCompatibleMode(TRK_IMPULSETRACKER)) + { + strcpy(s, "ignore"); + break; + } switch(param & 0x0F) { case 0x00: case 0x04: case 0x08: case 0x0C: strcpy(s, "sine wave"); break; Modified: trunk/OpenMPT/soundlib/Load_psm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-24 20:57:36 UTC (rev 341) +++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-25 01:18:21 UTC (rev 342) @@ -186,18 +186,10 @@ if(subChunkSize != 6) break; { - int version; - for(DWORD i = 0; i < subChunkSize; i++) - { - if(lpStream[dwChunkPos + i] >= '0' && lpStream[dwChunkPos + i] <= '9') - { - version = (version * 10) + (lpStream[dwChunkPos + i] - '0'); - } else - { - version = 0; - break; - } - } + CHAR cversion[7]; + memcpy(cversion, lpStream + dwChunkPos, 6); + cversion[6] = 0; + int version = atoi(cversion); // Sinaria song dates if(version == 800211 || version == 940902 || version == 940903 || version == 940906 || version == 940914 || version == 941213) Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-24 20:57:36 UTC (rev 341) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-25 01:18:21 UTC (rev 342) @@ -108,9 +108,6 @@ for(int i = 0; i < 20; i++) if(lpStream[17 + i] == 0) bProbablyMadeWithModPlug = true; - if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true; - if (!memcmp((LPCSTR)lpStream + 0x26, "OpenMPT ", 8)) bMadeWithModPlug = true; - dwHdrSize = LittleEndian(*((DWORD *)(lpStream+60))); norders = LittleEndianW(*((WORD *)(lpStream+64))); if ((!norders) || (norders > MAX_ORDERS)) return false; @@ -121,6 +118,23 @@ // if ((!channels) || (channels > 64)) return false; if ((!channels) || (channels > MAX_BASECHANNELS)) return false; // -! BEHAVIOUR_CHANGE#0006 + + if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true; + if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v 2.00 ", 20)) + { + bMadeWithModPlug = true; + m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 00, 00, 00); + } + + if (!memcmp((LPCSTR)lpStream + 0x26, "OpenMPT ", 8)) + { + //bMadeWithModPlug = true; // Don't set it - it's also used by compatibility export + CHAR sVersion[13]; + memcpy(sVersion, lpStream + 0x26 + 8, 12); + sVersion[12] = 0; + m_dwLastSavedWithVersion = MptVersion::ToNum(sVersion); + } + m_nType = MOD_TYPE_XM; m_nMinPeriod = 27; m_nMaxPeriod = 54784; @@ -637,7 +651,7 @@ if(bMadeWithModPlug) { SetModFlag(MSF_COMPATIBLE_PLAY, false); - m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 16, 00, 00); + if(!m_dwLastSavedWithVersion) m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 16, 00, 00); } // -> CODE#0027 Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-24 20:57:36 UTC (rev 341) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-25 01:18:21 UTC (rev 342) @@ -718,7 +718,7 @@ pChn->nPos = 0; pChn->nPosLo = 0; if (pChn->nVibratoType < 4) pChn->nVibratoPos = ((m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))) ? 0x10 : 0; - if (pChn->nTremoloType < 4) pChn->nTremoloPos = 0; + if(!IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->nTremoloType < 4) pChn->nTremoloPos = 0; } if (pChn->nPos >= pChn->nLength) pChn->nPos = pChn->nLoopStart; } @@ -2541,11 +2541,11 @@ if (pChn->nPeriod) pChn->nPeriod = GetPeriodFromNote(pChn->nNote, pChn->nFineTune, pChn->nC5Speed); break; // S3x: Set Vibrato WaveForm - case 0x30: pChn->nVibratoType = param & 0x07; break; + case 0x30: if(((param & 0x0F) < 0x04) || !IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nVibratoType = param & 0x07; break; // S4x: Set Tremolo WaveForm - case 0x40: pChn->nTremoloType = param & 0x07; break; + case 0x40: if(((param & 0x0F) < 0x04) || !IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nTremoloType = param & 0x07; break; // S5x: Set Panbrello WaveForm - case 0x50: pChn->nPanbrelloType = param & 0x07; break; + case 0x50: if(((param & 0x0F) < 0x04) || !IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPanbrelloType = param & 0x07; break; // S6x: Pattern Delay for x frames case 0x60: m_nFrameDelay = param; break; // S7x: Envelope Control Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-24 20:57:36 UTC (rev 341) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-25 01:18:21 UTC (rev 342) @@ -1190,6 +1190,7 @@ Chn[j].nCommand = 0; Chn[j].nPatternLoopCount = 0; Chn[j].nPatternLoop = 0; + Chn[j].nVibratoPos = Chn[j].nTremoloPos = Chn[j].nPanbrelloPos = 0; //IT compatibility 15. Retrigger if(IsCompatibleMode(TRK_IMPULSETRACKER)) { @@ -1482,6 +1483,7 @@ Chn[i].nNewLeftVol = Chn[i].nNewRightVol = 0; Chn[i].nLeftRamp = Chn[i].nRightRamp = 0; Chn[i].nVolume = 256; + Chn[i].nVibratoPos = Chn[i].nTremoloPos = Chn[i].nPanbrelloPos = 0; //-->Custom tuning related Chn[i].m_ReCalculateFreqOnFirstTick = false; Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-24 20:57:36 UTC (rev 341) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-25 01:18:21 UTC (rev 342) @@ -68,6 +68,9 @@ extern short int ModRampDownTable[64]; extern short int ModSquareTable[64]; extern short int ModRandomTable[64]; +extern short int ITSinusTable[64]; +extern short int ITRampDownTable[64]; +extern short int ITSquareTable[64]; extern DWORD LinearSlideUpTable[256]; extern DWORD LinearSlideDownTable[256]; extern DWORD FineLinearSlideUpTable[16]; @@ -983,16 +986,16 @@ if (pChn->dwFlags & CHN_TREMOLO) { UINT trempos = pChn->nTremoloPos & 0x3F; - if (vol > 0) + if (vol > 0 || IsCompatibleMode(TRK_IMPULSETRACKER)) { int tremattn = (m_nType & MOD_TYPE_XM) ? 5 : 6; switch (pChn->nTremoloType & 0x03) { case 1: - vol += (ModRampDownTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn; + vol += ((IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[trempos] : ModRampDownTable[trempos]) * (int)pChn->nTremoloDepth) >> tremattn; break; case 2: - vol += (ModSquareTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn; + vol += ((IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[trempos] : ModSquareTable[trempos]) * (int)pChn->nTremoloDepth) >> tremattn; break; case 3: //IT compatibility 19. Use random values @@ -1002,12 +1005,12 @@ vol += (ModRandomTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn; break; default: - vol += (ModSinusTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn; + vol += ((IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[trempos] : ModSinusTable[trempos]) * (int)pChn->nTremoloDepth) >> tremattn; } } if ((m_nTickCount) || ((m_nType & (MOD_TYPE_STM|MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS)))) { - pChn->nTremoloPos = (trempos + pChn->nTremoloSpeed) & 0x3F; + pChn->nTremoloPos = (pChn->nTremoloPos + pChn->nTremoloSpeed) & 0x3F; } } @@ -1337,13 +1340,10 @@ switch (pChn->nVibratoType & 0x03) { case 1: - if(IsCompatibleMode(TRK_ALLTRACKERS)) - vdelta = -ModRampDownTable[(vibpos+16) % 64]; - else - vdelta = ModRampDownTable[vibpos]; + vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[(vibpos + 48) % 64] : ModRampDownTable[vibpos]; break; case 2: - vdelta = ModSquareTable[vibpos]; + vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[(vibpos + 48) % 64] : ModSquareTable[vibpos]; break; case 3: //IT compatibility 19. Use random values @@ -1353,7 +1353,7 @@ vdelta = ModRandomTable[vibpos]; break; default: - vdelta = ModSinusTable[vibpos]; + vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[(vibpos + 48) % 64] : ModSinusTable[vibpos]; } if(m_nType == MOD_TYPE_MPT && pChn->pModInstrument && pChn->pModInstrument->pTuning) @@ -1385,11 +1385,14 @@ if (l & 0x03) vdelta += _muldiv(period, FineLinearSlideUpTable[l & 0x03], 0x10000) - period; } } - period += vdelta; + if(IsCompatibleMode(TRK_ALLTRACKERS)) + period -= vdelta; + else + period += vdelta; } if ((m_nTickCount) || ((m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS)))) { - pChn->nVibratoPos = (vibpos + pChn->nVibratoSpeed) & 0x3F; + pChn->nVibratoPos = (pChn->nVibratoPos + pChn->nVibratoSpeed) & 0x3F; } } // Panbrello @@ -1400,10 +1403,10 @@ switch (pChn->nPanbrelloType & 0x03) { case 1: - pdelta = ModRampDownTable[panpos]; + pdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[panpos] : ModRampDownTable[panpos]; break; case 2: - pdelta = ModSquareTable[panpos]; + pdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[panpos] : ModSquareTable[panpos]; break; case 3: //IT compatibility 19. Use random values @@ -1413,10 +1416,10 @@ pdelta = ModRandomTable[panpos]; break; default: - pdelta = ModSinusTable[panpos]; + pdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[panpos] : ModSinusTable[panpos]; } pChn->nPanbrelloPos += pChn->nPanbrelloSpeed; - pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> 3; + pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> (IsCompatibleMode(TRK_IMPULSETRACKER) ? 4 : 3); pdelta += pChn->nRealPan; pChn->nRealPan = CLAMP(pdelta, 0, 256); Modified: trunk/OpenMPT/soundlib/Tables.cpp =================================================================== --- trunk/OpenMPT/soundlib/Tables.cpp 2009-08-24 20:57:36 UTC (rev 341) +++ trunk/OpenMPT/soundlib/Tables.cpp 2009-08-25 01:18:21 UTC (rev 342) @@ -154,7 +154,35 @@ 42,-34,89,-4,-51,-72,21,-29,112,123,84,-101,-92,98,-54,-95 }; +// Impulse Tracker tables +// Sinus table +short int ITSinusTable[64] = +{ + 0,12,25,37,49,60,71,81,90,98,106,112,117,122,125,126, + 127,126,125,122,117,112,106,98,90,81,71,60,49,37,25,12, + 0,-12,-25,-37,-49,-60,-71,-81,-90,-98,-106,-112,-117,-122,-125,-126, + -127,-126,-125,-122,-117,-112,-106,-98,-90,-81,-71,-60,-49,-37,-25,-12 +}; + +// Triangle wave table (ramp down) +short int ITRampDownTable[64] = +{ + 127,123,119,115,111,107,103,99,95,91,87,83,79,75,71,67, + 63,59,55,51,47,43,39,35,31,27,23,19,15,11,7,3, + 0,-4,-8,-12,-16,-20,-24,-28,-32,-36,-40,-44,-48,-52,-56,-60, + -64,-68,-72,-76,-80,-84,-88,-92,-96,-100,-104,-108,-112,-116,-120,-124 +}; + +// Square wave table +short int ITSquareTable[64] = +{ + 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, + 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + // volume fade tables for Retrig Note: signed char retrigTable1[16] = { 0, 0, 0, 0, 0, 0, 10, 8, 0, 0, 0, 0, 0, 0, 24, 32 }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-08-26 20:40:41
|
Revision: 344 http://modplug.svn.sourceforge.net/modplug/?rev=344&view=rev Author: relabsoluness Date: 2009-08-26 20:40:27 +0000 (Wed, 26 Aug 2009) Log Message: ----------- [New] MIDI mapping: Editing a plug param in its editor while holding shift key will now open MIDI mapping dialog. [Fix] MIDI mapping: Some minor tweaks and fixes to the MIDI mapping dialog. [Fix] Pattern tab: Fixed possible crash occurring if echo pattern in echo paste doesn't exist. Modified Paths: -------------- trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp trunk/OpenMPT/mptrack/MIDIMappingDialog.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Mpt_midi.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/soundlib/midi.h trunk/OpenMPT/soundlib/patternContainer.h Modified: trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp 2009-08-25 20:14:24 UTC (rev 343) +++ trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp 2009-08-26 20:40:27 UTC (rev 344) @@ -65,6 +65,7 @@ m_ChannelCBox.SetCurSel(1+GetFromMIDIMsg_Channel(dwMidiDataParam)); m_EventCBox.SetCurSel(0); m_ControllerCBox.SetCurSel(GetFromMIDIMsg_DataByte1(dwMidiDataParam)); + OnCbnSelchangeComboChannel(); OnCbnSelchangeComboEvent(); OnCbnSelchangeComboController(); UpdateString(); @@ -78,16 +79,6 @@ { CDialog::OnInitDialog(); - if (m_rMIDIMapper.GetCount() > 0) - m_Setting = m_rMIDIMapper.GetDirective(0); - - m_ChannelCBox.SetCurSel(m_Setting.GetChannel()); - - CheckDlgButton(IDC_CHECKACTIVE, m_Setting.IsActive() ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(IDC_CHECKCAPTURE, m_Setting.GetCaptureMIDI() ? BST_CHECKED : BST_UNCHECKED); - GetDlgItem(IDC_CHECK_PATRECORD)->ShowWindow((m_rSndFile.GetType() == MOD_TYPE_MPT) ? SW_SHOW : SW_HIDE); - CheckDlgButton(IDC_CHECK_PATRECORD, m_Setting.GetAllowPatternEdit() ? BST_CHECKED : BST_UNCHECKED); - m_EventCBox.SetCurSel(0); //Add controller names. @@ -97,14 +88,13 @@ temp.Format("%3d %s", i, MidiCCNames[i]); m_ControllerCBox.AddString(temp); } - m_ControllerCBox.SetCurSel(m_Setting.GetController()); //Add Pluginnames AddPluginNamesToCombobox(m_PluginCBox, m_rSndFile.m_MixPlugins); m_PluginCBox.SetCurSel(m_Setting.GetPlugIndex()-1); //Add plugin parameter names - AddPluginParameternamesToCombobox(m_PlugParamCBox, m_rSndFile.m_MixPlugins[0]); + AddPluginParameternamesToCombobox(m_PlugParamCBox, m_rSndFile.m_MixPlugins[(m_Setting.GetPlugIndex() <= MAX_MIXPLUGINS) ? m_Setting.GetPlugIndex() - 1 : 0]); m_PlugParamCBox.SetCurSel(m_Setting.GetParamIndex()); //Add directives to list. @@ -113,16 +103,26 @@ { m_List.AddString(CreateListString(*iter)); } - if(m_rMIDIMapper.GetCount() > 0) + if(m_rMIDIMapper.GetCount() > 0 && m_Setting.IsDefault()) { m_List.SetCurSel(0); OnLbnSelchangeList1(); - m_Setting = m_rMIDIMapper.GetDirective(0); } + else + { + m_ChannelCBox.SetCurSel(m_Setting.GetChannel()); + m_ControllerCBox.SetCurSel(m_Setting.GetController()); + CheckDlgButton(IDC_CHECKACTIVE, m_Setting.IsActive() ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(IDC_CHECKCAPTURE, m_Setting.GetCaptureMIDI() ? BST_CHECKED : BST_UNCHECKED); + GetDlgItem(IDC_CHECK_PATRECORD)->ShowWindow((m_rSndFile.GetType() == MOD_TYPE_MPT) ? SW_SHOW : SW_HIDE); + CheckDlgButton(IDC_CHECK_PATRECORD, m_Setting.GetAllowPatternEdit() ? BST_CHECKED : BST_UNCHECKED); + } UpdateString(); CMainFrame::GetMainFrame()->SetMidiRecordWnd(GetSafeHwnd()); + + CheckDlgButton(IDC_CHECK_MIDILEARN, BST_CHECKED); return TRUE; // return TRUE unless you set the focus to a control } Modified: trunk/OpenMPT/mptrack/MIDIMappingDialog.h =================================================================== --- trunk/OpenMPT/mptrack/MIDIMappingDialog.h 2009-08-25 20:14:24 UTC (rev 343) +++ trunk/OpenMPT/mptrack/MIDIMappingDialog.h 2009-08-26 20:40:27 UTC (rev 344) @@ -21,6 +21,8 @@ // Dialog Data enum { IDD = IDD_MIDIPARAMCONTROL }; + CMIDIMappingDirective m_Setting; + protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support @@ -49,7 +51,7 @@ CSpinButtonCtrl m_SpinMoveMapping; - CMIDIMappingDirective m_Setting; + public: afx_msg void OnLbnSelchangeList1(); Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-25 20:14:24 UTC (rev 343) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-26 20:40:27 UTC (rev 344) @@ -2304,7 +2304,7 @@ ORDERINDEX oNextOrder = m_SndFile.Order.GetNextOrderIgnoringSkips(oCurrentOrder); if((oNextOrder <= 0) || (oNextOrder >= m_SndFile.Order.size())) goto PasteDone; nPattern = m_SndFile.Order[oNextOrder]; - if(m_SndFile.Patterns.IsValidIndex(nPattern) == false) goto PasteDone; + if(m_SndFile.Patterns.IsValidPat(nPattern) == false) goto PasteDone; m = m_SndFile.Patterns[nPattern]; PrepareUndo(nPattern, 0,0, m_SndFile.m_nChannels, m_SndFile.PatternSize[nPattern]); oCurrentOrder = oNextOrder; Modified: trunk/OpenMPT/mptrack/Mpt_midi.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mpt_midi.cpp 2009-08-25 20:14:24 UTC (rev 343) +++ trunk/OpenMPT/mptrack/Mpt_midi.cpp 2009-08-26 20:40:27 UTC (rev 344) @@ -165,6 +165,20 @@ //---------------------------------------------------------------------------- +CString CMIDIMappingDirective::ToString() const +//--------------------------------------------- +{ + CString str; str.Preallocate(20); + char flags[4] = "000"; + if(m_Active) flags[0] = '1'; + if(m_CaptureMIDI) flags[1] = '1'; + if(m_AllowPatternEdit) flags[2] = '1'; + str.Format("%s:%d:%x:%d:%d:%d", flags, (int)GetChannel(), (int)GetEvent(), (int)GetController(), (int)m_PluginIndex, m_Parameter); + str.Trim(); + return str; +} + + size_t CMIDIMapper::GetSerializationSize() const //--------------------------------------------- { Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-08-25 20:14:24 UTC (rev 343) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-08-26 20:40:27 UTC (rev 344) @@ -3018,7 +3018,7 @@ //-------------------------------------------------------------------------------- { static MODCOMMAND m; - if (rSf.Patterns.IsValidIndex(pos.nPat) && pos.nRow < rSf.Patterns[pos.nPat].GetNumRows() && pos.nChn < rSf.GetNumChannels()) + if (rSf.Patterns.IsValidPat(pos.nPat) && pos.nRow < rSf.Patterns[pos.nPat].GetNumRows() && pos.nChn < rSf.GetNumChannels()) return rSf.Patterns[pos.nPat].GetpModCommand(pos.nRow, pos.nChn); else return &m; @@ -5125,7 +5125,7 @@ const ROWINDEX iRowCandidate, const PATTERNINDEX iPatCandidate) const //------------------------------------------------------------------------------------------- { - if(rSndFile.Patterns.IsValidIndex(iPatCandidate) && rSndFile.Patterns[iPatCandidate].IsValidRow(iRowCandidate)) + if(rSndFile.Patterns.IsValidPat(iPatCandidate) && rSndFile.Patterns[iPatCandidate].IsValidRow(iRowCandidate)) { // Case: Edit position candidates are valid -- use them. iPat = iPatCandidate; iRow = iRowCandidate; Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2009-08-25 20:14:24 UTC (rev 343) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2009-08-26 20:40:27 UTC (rev 344) @@ -14,6 +14,7 @@ #include "defaultvsteditor.h" //rewbs.defaultPlugGUI #include "midi.h" #include "version.h" +#include "midimappingdialog.h" #ifdef VST_USE_ALTERNATIVE_MAGIC //Pelya's plugin ID fix. Breaks fx presets, so let's avoid it for now. #include "Unzip32.h" //For CRC calculation (to detect plugins with same UID) #endif @@ -677,6 +678,18 @@ pModDoc->RecordParamChange(pVstPlugin->GetSlot(), index); } + if (CMainFrame::GetInputHandler()->ShiftPressed()) + { + CMainFrame::GetInputHandler()->SetModifierMask(0); // Make sure that the dialog will open only once. + CAbstractVstEditor *pVstEditor = pVstPlugin->GetEditor(); + const HWND oldMIDIRecondWnd = CMainFrame::GetMainFrame()->GetMidiRecordWnd(); + CMIDIMappingDialog dlg(pVstEditor, *pModDoc->GetSoundFile()); + dlg.m_Setting.SetParamIndex(index); + dlg.m_Setting.SetPlugIndex(pVstPlugin->GetSlot()+1); + dlg.DoModal(); + CMainFrame::GetMainFrame()->SetMidiRecordWnd(oldMIDIRecondWnd); + } + // Learn macro CAbstractVstEditor *pVstEditor = pVstPlugin->GetEditor(); if (pVstEditor) { Modified: trunk/OpenMPT/soundlib/midi.h =================================================================== --- trunk/OpenMPT/soundlib/midi.h 2009-08-25 20:14:24 UTC (rev 343) +++ trunk/OpenMPT/soundlib/midi.h 2009-08-26 20:40:27 UTC (rev 344) @@ -63,20 +63,12 @@ void SetParamIndex(const int i) {m_Parameter = i;} uint32 GetParamIndex() const {return m_Parameter;} - bool operator==(const CMIDIMappingDirective& d) {return memcmp(this, &d, sizeof(CMIDIMappingDirective)) == 0;} + bool IsDefault() const {return *this == CMIDIMappingDirective();} - CString ToString() const - { - CString str; str.Preallocate(20); - char flags[4] = "000"; - if(m_Active) flags[0] = '1'; - if(m_CaptureMIDI) flags[1] = '1'; - if(m_AllowPatternEdit) flags[2] = '1'; - str.Format("%s:%d:%x:%d:%d:%d", flags, (int)GetChannel(), (int)GetEvent(), (int)GetController(), (int)m_PluginIndex, m_Parameter); - str.Trim(); - return str; - } + bool operator==(const CMIDIMappingDirective& d) const {return memcmp(this, &d, sizeof(CMIDIMappingDirective)) == 0;} + CString ToString() const; + BYTE GetChnEvent() const {return m_ChnEvent;} private: Modified: trunk/OpenMPT/soundlib/patternContainer.h =================================================================== --- trunk/OpenMPT/soundlib/patternContainer.h 2009-08-25 20:14:24 UTC (rev 343) +++ trunk/OpenMPT/soundlib/patternContainer.h 2009-08-26 20:40:27 UTC (rev 344) @@ -55,6 +55,9 @@ // Return true if pattern can be accessed with operator[](iPat), false otherwise. bool IsValidIndex(const PATTERNINDEX iPat) const {return (iPat < Size());} + + // Return true if IsValidIndex() is true and the corresponding pattern has allocated modcommand array, false otherwise. + bool IsValidPat(const PATTERNINDEX iPat) const {return IsValidIndex(iPat) && (*this)[iPat];} void ResizeArray(const PATTERNINDEX newSize); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-08-29 00:40:36
|
Revision: 346 http://modplug.svn.sourceforge.net/modplug/?rev=346&view=rev Author: saga-games Date: 2009-08-29 00:40:26 +0000 (Sat, 29 Aug 2009) Log Message: ----------- [Fix] IT Compatibility: Don't reset channel panning if panbrello ends (experimental) [Imp] PSM Loader: I think it's finished... finally. Subsongs should work perfectly, a few other things have also been fixed / improved. Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-26 22:04:14 UTC (rev 345) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-29 00:40:26 UTC (rev 346) @@ -354,9 +354,9 @@ case MOD_TYPE_STM: case MOD_TYPE_DSM: case MOD_TYPE_AMF: - case MOD_TYPE_PSM: m_SndFile.ChangeModTypeTo(MOD_TYPE_S3M); break; + case MOD_TYPE_PSM: default: m_SndFile.ChangeModTypeTo(MOD_TYPE_IT); } Modified: trunk/OpenMPT/soundlib/Load_psm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-26 22:04:14 UTC (rev 345) +++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-29 00:40:26 UTC (rev 346) @@ -8,12 +8,11 @@ * * What's playing? * - Epic Pinball - Perfect! (the old tunes in PSM16 format are not supported) - * - Extreme Pinball - Default tempo / speed / restart position of subtunes is missing. - * I'm using the last default values, restart position is still completely missing + * - Extreme Pinball - Perfect! (subtunes included!) * - Jazz Jackrabbit - Perfect! - * - One Must Fall! - Perfect! (I modelled the volume slide and portamento conversion after this, as I got the original MTM files) + * - One Must Fall! - Perfect! (it helped a lot to have the original MTM files...) * - Silverball - Currently not supported (old PSM16 format) - * - Sinaria - Seems to work more or less (never played the game, so I can't really tell...) + * - Sinaria - Seems to work (never played the game, so I can't really tell...) * * Effect conversion should be about right... */ @@ -77,6 +76,26 @@ }; #pragma pack() +struct PSMSUBSONG // For internal use (pattern conversion) +{ + BYTE channelPanning[MAX_BASECHANNELS], channelVolume[MAX_BASECHANNELS]; + bool channelSurround[MAX_BASECHANNELS]; + BYTE defaultTempo, defaultSpeed; + CHAR songName[10]; + ORDERINDEX startOrder, endOrder, restartPos; + + PSMSUBSONG() { + memset(channelPanning, 128, sizeof(channelPanning)); + memset(channelVolume, 64, sizeof(channelVolume)); + memset(channelSurround, false, sizeof(channelSurround)); + memset(songName, 0, sizeof(songName)); + defaultTempo = 125; + defaultSpeed = 6; + startOrder = endOrder = restartPos = ORDERINDEX_INVALID; + } +}; + +// Portamento effect conversion (depending on format version) inline BYTE convert_psm_porta(BYTE param, bool bNewFormat) { return ((bNewFormat) ? (param) : ((param < 4) ? (param | 0xF0) : (param >> 2))); @@ -100,7 +119,8 @@ ) return false; // Yep, this seems to be a valid file. - m_nType = MOD_TYPE_PSM; + m_nType = MOD_TYPE_IT; + SetModFlag(MSF_COMPATIBLE_PLAY, true); m_nChannels = 0; dwMemPos += 12; @@ -110,15 +130,18 @@ m_nVSTiVolume = m_nSamplePreAmp = 48; // not supported in this format, so use a good default value // pattern offset and identifier - PATTERNINDEX numPatterns = 0; - vector<DWORD> patternOffsets; - vector<DWORD> patternIDs; + PATTERNINDEX numPatterns = 0; // used for setting up the orderlist - final pattern count + vector<DWORD> patternOffsets; // pattern offsets (sorted as they occour in the file) + vector<DWORD> patternIDs; // pattern IDs (sorted as they occour in the file) + vector<DWORD> orderOffsets; // combine the upper two vectors to get the offsets for each order item patternOffsets.clear(); patternIDs.clear(); + orderOffsets.clear(); Order.clear(); + // subsong setup + vector<PSMSUBSONG> subsongs; + bool bSubsongPanningDiffers = false; // do we have subsongs with different panning positions? - std::string sComment; // we will store some information about the tune here - while(dwMemPos + 8 < dwMemLength) { // Skip through the chunks @@ -141,39 +164,37 @@ break; case 0x444F4250: // "PBOD" - Pattern data of a single pattern - if(chunkSize < 4 || chunkSize != LittleEndian(*(DWORD *)(lpStream + dwMemPos))) return false; // same value twice + if(chunkSize < 8 || chunkSize != LittleEndian(*(DWORD *)(lpStream + dwMemPos))) return false; // same value twice - // Pattern ID (something like "P0 " or "P13 ") follows + // Pattern ID (something like "P0 " or "P13 ", or "PATT0 " in Sinaria) follows if(memcmp(lpStream + dwMemPos + 4, "P", 1)) return false; if(!memcmp(lpStream + dwMemPos + 4, "PATT", 4)) bNewFormat = true; + if(bNewFormat && chunkSize < 12) return false; // 4 additional bytes + char patternID[4]; memcpy(patternID, lpStream + dwMemPos + 5 + (bNewFormat ? 3 : 0), 3); patternID[3] = 0; + patternIDs.push_back(atoi(patternID)); patternOffsets.push_back(dwMemPos + 8 + (bNewFormat ? 4 : 0)); - patternIDs.push_back(atoi(patternID)); - numPatterns++; // Convert later as we have to know how many channels there are. break; - case 0x474E4F53: // "SONG" - Information about this file (channel count etc) - // We will not check for the "song type", because it is not ALWAYS "MAINSONG " (Extreme Pinball seems to use other song types for the sub songs) - // However, the last char always seems to be a space char. + case 0x474E4F53: // "SONG" - Subsong information (channel count etc) { if(chunkSize < sizeof(PSMSONGHEADER)) return false; PSMSONGHEADER *pSong = (PSMSONGHEADER *)(lpStream + dwMemPos); - if(pSong->compression != 0x01) return false; - m_nChannels = max(m_nChannels, pSong->numChannels); // subsongs *might* have different channel count + if(pSong->compression != 0x01) return false; // no compression for PSM files + m_nChannels = CLAMP(pSong->numChannels, m_nChannels, MAX_BASECHANNELS); // subsongs *might* have different channel count - CHAR cSongName[10]; - memcpy(cSongName, &pSong->songType, 9); - cSongName[9] = 0; - sComment += "\r\nSubsong: "; - sComment += cSongName; + PSMSUBSONG subsong; + subsong.restartPos = (ORDERINDEX)Order.size(); // restart order "offset": current orderlist length + memcpy(subsong.songName, &pSong->songType, 9); // subsong name + subsong.songName[9] = 0; DWORD dwChunkPos = dwMemPos + sizeof(PSMSONGHEADER); - // Sub chunks + // "Sub sub chunks" while(dwChunkPos + 8 < dwMemPos + chunkSize) { DWORD subChunkID = LittleEndian(*(DWORD *)(lpStream + dwChunkPos)); @@ -190,20 +211,11 @@ memcpy(cversion, lpStream + dwChunkPos, 6); cversion[6] = 0; int version = atoi(cversion); - // Sinaria song dates + // Sinaria song dates (just to go sure...) if(version == 800211 || version == 940902 || version == 940903 || version == 940906 || version == 940914 || version == 941213) bNewFormat = true; } - #ifdef DEBUG - CHAR cDate[7]; - memcpy(cDate, lpStream + dwChunkPos, 6); - cDate[6] = 0; - sComment += " - Build Date: "; - sComment += cDate; - if(bNewFormat) sComment += " (New Format)"; - else sComment += " (Old Format)"; - #endif break; case 0x484C504F: // "OPLH" - Order list, channel + module settings @@ -215,6 +227,8 @@ // Now, the interesting part begins! DWORD dwSettingsOffset = dwChunkPos + 2; WORD nChunkCount = 0, nFirstOrderChunk = (WORD)-1; + + // "Sub sub sub chunks" (grrrr, silly format) while(dwSettingsOffset - dwChunkPos + 1 < subChunkSize) { switch(lpStream[dwSettingsOffset]) @@ -226,57 +240,62 @@ case 0x01: // Order list item if(dwSettingsOffset - dwChunkPos + 5 > subChunkSize) return false; // Pattern name follows - find pattern (this is the orderlist) - for(PATTERNINDEX i = 0; i < patternIDs.size(); i++) { - char patternID[4]; + char patternID[4]; // temporary memcpy(patternID, lpStream + dwSettingsOffset + 2 + (bNewFormat ? 3 : 0), 3); patternID[3] = 0; DWORD nPattern = atoi(patternID); - if(patternIDs[i] == nPattern) + + // seek which pattern has this ID + for(uint32 i = 0; i < patternIDs.size(); i++) { - Order.push_back(i); - break; + if(patternIDs[i] == nPattern) + { + // found the right pattern, copy offset + start / end positions. + if(subsong.startOrder == ORDERINDEX_INVALID) + subsong.startOrder = (ORDERINDEX)orderOffsets.size(); + subsong.endOrder = (ORDERINDEX)orderOffsets.size(); + + // every pattern in the order will be unique, so store the pointer + pattern ID + orderOffsets.push_back(patternOffsets[i]); + Order.push_back(numPatterns); + numPatterns++; + break; + } } } + // decide whether this is the first order chunk or not (for finding out the correct restart position) if(nFirstOrderChunk == (WORD)-1) nFirstOrderChunk = nChunkCount; dwSettingsOffset += 5 + (bNewFormat ? 4 : 0); break; case 0x04: // Restart position { - // NOTE: This should not be global! (Extreme Pinball!!!) WORD nRestartChunk = LittleEndian(*(WORD *)(lpStream + dwSettingsOffset + 1)); ORDERINDEX nRestartPosition = 0; - if(nRestartChunk == 0) nRestartPosition = 0; - else if(nRestartChunk >= nFirstOrderChunk) nRestartPosition = (ORDERINDEX)(nRestartChunk - nFirstOrderChunk); - #ifdef DEBUG - { - char s[32]; - wsprintf(s, " - restart pos %d", nRestartPosition); - sComment += s; - } - #endif + if(nRestartChunk >= nFirstOrderChunk) nRestartPosition = (ORDERINDEX)(nRestartChunk - nFirstOrderChunk); + subsong.restartPos += nRestartPosition; + m_nRestartPos = subsong.restartPos; } dwSettingsOffset += 3; break; case 0x07: // Default Speed if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break; - // Same note as above! - m_nDefaultSpeed = lpStream[dwSettingsOffset + 1]; + m_nDefaultSpeed = subsong.defaultSpeed = lpStream[dwSettingsOffset + 1]; dwSettingsOffset += 2; break; case 0x08: // Default Tempo if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break; - // Same note as above! - m_nDefaultTempo = lpStream[dwSettingsOffset + 1]; + m_nDefaultTempo = subsong.defaultTempo = lpStream[dwSettingsOffset + 1]; dwSettingsOffset += 2; break; case 0x0C: // Sample map table (???) if(dwSettingsOffset - dwChunkPos + 7 > subChunkSize) break; + // Never seems to be different, so... if (lpStream[dwSettingsOffset + 1] != 0x00 || lpStream[dwSettingsOffset + 2] != 0xFF || lpStream[dwSettingsOffset + 3] != 0x00 || lpStream[dwSettingsOffset + 4] != 0x00 || lpStream[dwSettingsOffset + 5] != 0x01 || lpStream[dwSettingsOffset + 6] != 0x00) @@ -287,31 +306,44 @@ case 0x0D: // Channel panning table if(dwSettingsOffset - dwChunkPos + 4 > subChunkSize) break; + if(lpStream[dwSettingsOffset + 1] < MAX_BASECHANNELS) { - CHANNELINDEX nChn = min(lpStream[dwSettingsOffset + 1], pSong->numChannels); + CHANNELINDEX nChn = lpStream[dwSettingsOffset + 1]; switch(lpStream[dwSettingsOffset + 3]) { - case 0: - ChnSettings[nChn].nPan = lpStream[dwSettingsOffset + 2] ^ 128; + case 0: // use panning + ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = lpStream[dwSettingsOffset + 2] ^ 128; + ChnSettings[nChn].dwFlags &= ~CHN_SURROUND; + subsong.channelSurround[nChn] = false; break; - case 2: - ChnSettings[nChn].nPan = 128; + case 2: // surround + ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128; ChnSettings[nChn].dwFlags |= CHN_SURROUND; + subsong.channelSurround[nChn] = true; break; - case 4: - ChnSettings[nChn].nPan = 128; + case 4: // center + ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128; + ChnSettings[nChn].dwFlags &= ~CHN_SURROUND; + subsong.channelSurround[nChn] = false; break; } + if(bSubsongPanningDiffers == false && subsongs.size() > 0) + { + if(subsongs.back().channelPanning[nChn] != subsong.channelPanning[nChn] + || subsongs.back().channelSurround[nChn] != subsong.channelSurround[nChn]) + bSubsongPanningDiffers = true; + } } dwSettingsOffset += 4; break; - case 0x0E: // Channel volume table + case 0x0E: // Channel volume table (0...255) if(dwSettingsOffset - dwChunkPos + 3 > subChunkSize) break; - ChnSettings[min(lpStream[dwSettingsOffset + 1], pSong->numChannels)].nVolume = (lpStream[dwSettingsOffset + 2] >> 2) + 1; + if(lpStream[dwSettingsOffset + 1] < MAX_BASECHANNELS) + ChnSettings[lpStream[dwSettingsOffset + 1]].nVolume = subsong.channelVolume[lpStream[dwSettingsOffset + 1]] = (lpStream[dwSettingsOffset + 2] >> 2) + 1; dwSettingsOffset += 3; break; @@ -320,12 +352,15 @@ CString s; s.Format("Please report to the OpenMPT team: Unknown chunk %d found at position %d (in the OPLH chunk of this PSM file)", lpStream[dwSettingsOffset], dwSettingsOffset); MessageBox(NULL, s, TEXT("OpenMPT PSM import"), MB_ICONERROR); + // anyway, in such cases, we have to quit as we don't know how big the chunk really is. return false; break; } nChunkCount++; } + // separate subsongs by "---" patterns + orderOffsets.push_back(nullptr); Order.push_back(Order.GetInvalidPatIndex()); } break; @@ -334,20 +369,26 @@ if(subChunkSize & 1) return false; for(DWORD i = 0; i < subChunkSize; i += 2) { - if((i >> 1) >= m_nChannels) break; + CHANNELINDEX nChn = (CHANNELINDEX)(i >> 1); + if(nChn >= m_nChannels) break; switch(lpStream[dwChunkPos + i]) { - case 0: - ChnSettings[i >> 1].nPan = lpStream[dwChunkPos + i + 1] ^ 128; + case 0: // use panning + ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = lpStream[dwChunkPos + i + 1] ^ 128; + ChnSettings[nChn].dwFlags &= ~CHN_SURROUND; + subsong.channelSurround[nChn] = false; break; - case 2: - ChnSettings[i >> 1].nPan = 128; - ChnSettings[i >> 1].dwFlags |= CHN_SURROUND; + case 2: // surround + ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128; + ChnSettings[nChn].dwFlags |= CHN_SURROUND; + subsong.channelSurround[nChn] = true; break; - case 4: - ChnSettings[i >> 1].nPan = 128; + case 4: // center + ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128; + ChnSettings[nChn].dwFlags &= ~CHN_SURROUND; + subsong.channelSurround[nChn] = false; break; } } @@ -368,6 +409,9 @@ dwChunkPos += subChunkSize; } + + // attach this subsong to the subsong list - finally, all "sub sub sub ..." chunks are parsed. + subsongs.push_back(subsong); } break; @@ -375,6 +419,7 @@ case 0x504D5344: // DSMP - Samples if(!bNewFormat) { + // original header if(chunkSize < sizeof(PSMOLDSAMPLEHEADER)) return false; PSMOLDSAMPLEHEADER *pSample = (PSMOLDSAMPLEHEADER *)(lpStream + dwMemPos); SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1); @@ -434,10 +479,14 @@ if(m_nChannels == 0) return false; + // Now that we know the number of channels, we can go through all the patterns. - for(PATTERNINDEX nPat = 0; nPat < numPatterns; nPat++) + // This is a bit stupid since we will even read duplicate patterns twice, but hey, we do this just once... so who cares? + PATTERNINDEX nPat = 0; + for(ORDERINDEX nOrd = 0; nOrd < Order.size(); nOrd++) { - DWORD dwPatternOffset = patternOffsets[nPat]; + if(orderOffsets[nOrd] == nullptr) continue; + DWORD dwPatternOffset = orderOffsets[nOrd]; if(dwPatternOffset + 2 > dwMemLength) return false; WORD patternSize = LittleEndianW(*(WORD *)(lpStream + dwPatternOffset)); dwPatternOffset += 2; @@ -659,11 +708,7 @@ break; default: - #ifdef DEBUG - ASSERT(false); - #else command = CMD_NONE; - #endif break; } @@ -679,17 +724,52 @@ row_data += m_nChannels; dwPatternOffset += rowSize; } - + nPat++; } - if(!sComment.empty()) + // write subsong "configuration" to patterns + for(uint32 i = 0; i < subsongs.size(); i++) { - m_lpszSongComments = new char[sComment.length() + 1]; - if (m_lpszSongComments) + PATTERNINDEX startPattern = Order[subsongs[i].startOrder], endPattern = Order[subsongs[i].endOrder]; + if(startPattern == PATTERNINDEX_INVALID || endPattern == PATTERNINDEX_INVALID) continue; // what, invalid subtune? + + // set the subsong name to all pattern names + for(PATTERNINDEX nPat = startPattern; nPat <= endPattern; nPat++) { - memset(m_lpszSongComments, 0, sComment.length() + 1); - memcpy(m_lpszSongComments, sComment.c_str(), sComment.length()); + SetPatternName(nPat, subsongs[i].songName); } + + // subsongs with different panning setup -> write to pattern (MUSIC_C.PSM) + if(bSubsongPanningDiffers) + { + for(CHANNELINDEX nChn = 0; nChn < m_nChannels; nChn++) + { + if(subsongs[i].channelSurround[nChn] == true) + TryWriteEffect(startPattern, 0, CMD_S3MCMDEX, 0x91, false, nChn, false, true); + else + TryWriteEffect(startPattern, 0, CMD_PANNING8, subsongs[i].channelPanning[nChn], false, nChn, false, true); + } + } + // write default tempo/speed to pattern + TryWriteEffect(startPattern, 0, CMD_SPEED, subsongs[i].defaultSpeed, false, CHANNELINDEX_INVALID, false, true); + TryWriteEffect(startPattern, 0, CMD_TEMPO, subsongs[i].defaultTempo, false, CHANNELINDEX_INVALID, false, true); + + // don't write channel volume for now, as it's always set to 100% anyway + + // there's a restart pos, so let's try to insert a Bxx command in the last pattern + if(subsongs[i].restartPos != ORDERINDEX_INVALID) + { + ROWINDEX lastRow = Patterns[endPattern].GetNumRows() - 1; + MODCOMMAND *row_data; + row_data = Patterns[endPattern]; + for(uint32 nCell = 0; nCell < m_nChannels * Patterns[endPattern].GetNumRows(); nCell++) + { + if(row_data->command == CMD_PATTERNBREAK || row_data->command == CMD_POSITIONJUMP) + lastRow = nCell / m_nChannels; + row_data++; + } + TryWriteEffect(endPattern, lastRow, CMD_POSITIONJUMP, (BYTE)subsongs[i].restartPos, false, CHANNELINDEX_INVALID, false, true); + } } return true; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-26 22:04:14 UTC (rev 345) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-29 00:40:26 UTC (rev 346) @@ -3119,7 +3119,7 @@ if(m_nType & MOD_TYPE_S3M && nParam > 0x80) break; - m->volcmd = VOLCMD_VOLUME; + m->volcmd = VOLCMD_PANNING; m->command = nEffect; if(m_nType & MOD_TYPE_S3M) Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-26 22:04:14 UTC (rev 345) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-29 00:40:26 UTC (rev 346) @@ -1445,6 +1445,7 @@ pdelta += pChn->nRealPan; pChn->nRealPan = CLAMP(pdelta, 0, 256); + if(IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPan = pChn->nRealPan; } int nPeriodFrac = 0; // Instrument Auto-Vibrato This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-08-29 14:56:28
|
Revision: 347 http://modplug.svn.sourceforge.net/modplug/?rev=347&view=rev Author: saga-games Date: 2009-08-29 14:56:14 +0000 (Sat, 29 Aug 2009) Log Message: ----------- [Fix] MP3 Tagging: Synchsafe integers were calculated wrong; Writing the comments field last so the chance of fucking up everything is lower (Winamp's tag reader seems to have some problems with my long comments, but they seem to be encoded correctly? :-S) [Fix] XM Compatibility: Note Off with instrument number causes fadeout for samples that have no envelope. [Imp] Comments tab: Default view mode is instruments instead of samples for XM files. Modified Paths: -------------- trunk/OpenMPT/mptrack/tagging.cpp trunk/OpenMPT/mptrack/view_com.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp Modified: trunk/OpenMPT/mptrack/tagging.cpp =================================================================== --- trunk/OpenMPT/mptrack/tagging.cpp 2009-08-29 00:40:26 UTC (rev 346) +++ trunk/OpenMPT/mptrack/tagging.cpp 2009-08-29 14:56:14 UTC (rev 347) @@ -1,5 +1,5 @@ /* - * Purpose: File tagging (ID3v2, RIFF + more in the future) + * Purpose: File tagging (ID3v2, RIFF + more iIn the future) * Authors: OpenMPT Devs */ @@ -23,15 +23,15 @@ // Convert Integer to Synchsafe Integer (see ID3v2.4 specs) // Basically, it's a BigEndian integer, but the MSB of all bytes is 0. // Thus, a 32-bit integer turns into a 28-bit integer. -UINT32 CFileTagging::intToSynchsafe(UINT32 in) +UINT32 CFileTagging::intToSynchsafe(UINT32 iIn) { - in = LittleEndian(in); - UINT32 out = 0; + iIn = LittleEndian(iIn); + UINT32 iOut = 0, iSteps = 0; do { - out <<= 8; - out |= (in & 0x7F); - } while(in >>= 7); - return BigEndian(out); + iOut |= (iIn & 0x7F) << iSteps; + iSteps += 8; + } while(iIn >>= 7); + return BigEndian(iOut); } // Write Tags @@ -53,7 +53,7 @@ tHeader.flags = 0x00; // No flags fwrite(&tHeader, 1, sizeof(tHeader), f); - // Write TIT2 (Title), TCOM / TPE1 (Composer), TALB (Album), TCON (Genre), TYER (Date), WXXX (URL), COMM (Comment), TENC (Encoder) + // Write TIT2 (Title), TCOM / TPE1 (Composer), TALB (Album), TCON (Genre), TYER (Date), WXXX (URL), TENC (Encoder), COMM (Comment) WriteID3v2Frame("TIT2", title, f); WriteID3v2Frame("TPE1", artist, f); WriteID3v2Frame("TCOM", artist, f); @@ -61,8 +61,8 @@ WriteID3v2Frame("TCON", genre, f); WriteID3v2Frame("TYER", year, f); WriteID3v2Frame("WXXX", url, f); + WriteID3v2Frame("TENC", encoder, f); WriteID3v2Frame("COMM", comments, f); - WriteID3v2Frame("TENC", encoder, f); // Write Padding for(UINT i = 0; i < ID3v2_PADDING; i++) Modified: trunk/OpenMPT/mptrack/view_com.cpp =================================================================== --- trunk/OpenMPT/mptrack/view_com.cpp 2009-08-29 00:40:26 UTC (rev 346) +++ trunk/OpenMPT/mptrack/view_com.cpp 2009-08-29 14:56:14 UTC (rev 347) @@ -97,13 +97,30 @@ //---------------------------- { m_nCurrentListId = 0; - m_nListId = IDC_LIST_SAMPLES; + m_nListId = 0;//IDC_LIST_SAMPLES; } void CViewComments::OnInitialUpdate() //----------------------------------- { + if(m_nListId == 0) + { + m_nListId = IDC_LIST_SAMPLES; + + // For XM, set the instrument list as the default list + CModDoc *pModDoc = GetDocument(); + CSoundFile *pSndFile; + if(pModDoc) + { + pSndFile= pModDoc->GetSoundFile(); + if(pSndFile && (pSndFile->m_nType & MOD_TYPE_XM)) + { + m_nListId = IDC_LIST_INSTRUMENTS; + } + } + } + CChildFrame *pFrame = (CChildFrame *)GetParentFrame(); CRect rect; Modified: trunk/OpenMPT/soundlib/Load_psm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-29 00:40:26 UTC (rev 346) +++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-29 14:56:14 UTC (rev 347) @@ -15,6 +15,7 @@ * - Sinaria - Seems to work (never played the game, so I can't really tell...) * * Effect conversion should be about right... + * If OpenMPT will ever support subtunes properly, the subtune crap should be rewritten completely. */ #include "stdafx.h" Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-29 00:40:26 UTC (rev 346) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-29 14:56:14 UTC (rev 347) @@ -1233,8 +1233,8 @@ note = instr = 0; } - // XM: Key-Off + Sample == Note Cut - if ((note == NOTE_KEYOFF) && ((!pChn->pModInstrument) || (!(pChn->pModInstrument->dwFlags & ENV_VOLUME)))) + // XM: Key-Off + Sample == Note Cut (BUT: Only if no instr number is present!) + if ((note == NOTE_KEYOFF) && (!pChn->pModInstrument || !IsCompatibleMode(TRK_FASTTRACKER2)) && ((!pChn->pModInstrument) || (!(pChn->pModInstrument->dwFlags & ENV_VOLUME)))) { pChn->dwFlags |= CHN_FASTVOLRAMP; pChn->nVolume = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-08-30 14:30:04
|
Revision: 349 http://modplug.svn.sourceforge.net/modplug/?rev=349&view=rev Author: saga-games Date: 2009-08-30 14:29:58 +0000 (Sun, 30 Aug 2009) Log Message: ----------- [Fix] XM Compatibility: Compatible Arpeggio was done wrong [Fix] XM Compatibility: More compatible "Note Off + Something" [Fix] IT COmpatibility: Removed a "fix" again that was causing to completely destroy panbrello [Imp] Comments tab: Only switch only to instrument list in XM modules if there are actually instruments Modified Paths: -------------- trunk/OpenMPT/mptrack/view_com.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/view_com.cpp =================================================================== --- trunk/OpenMPT/mptrack/view_com.cpp 2009-08-30 00:07:19 UTC (rev 348) +++ trunk/OpenMPT/mptrack/view_com.cpp 2009-08-30 14:29:58 UTC (rev 349) @@ -114,7 +114,7 @@ if(pModDoc) { pSndFile= pModDoc->GetSoundFile(); - if(pSndFile && (pSndFile->m_nType & MOD_TYPE_XM)) + if(pSndFile && (pSndFile->m_nType & MOD_TYPE_XM) && pSndFile->m_nInstruments > 0) { m_nListId = IDC_LIST_INSTRUMENTS; } Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-30 00:07:19 UTC (rev 348) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-30 14:29:58 UTC (rev 349) @@ -1233,8 +1233,8 @@ note = instr = 0; } - // XM: Key-Off + Sample == Note Cut (BUT: Only if no instr number is present!) - if ((note == NOTE_KEYOFF) && (!pChn->pModInstrument || !IsCompatibleMode(TRK_FASTTRACKER2)) && ((!pChn->pModInstrument) || (!(pChn->pModInstrument->dwFlags & ENV_VOLUME)))) + // XM: Key-Off + Sample == Note Cut (BUT: Only if no instr number or volume effect is present!) + if ((note == NOTE_KEYOFF) && ((!instr && !vol && cmd != CMD_VOLUME) || !IsCompatibleMode(TRK_FASTTRACKER2)) && ((!pChn->pModInstrument) || (!(pChn->pModInstrument->dwFlags & ENV_VOLUME)))) { pChn->dwFlags |= CHN_FASTVOLRAMP; pChn->nVolume = 0; Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-30 00:07:19 UTC (rev 348) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-30 14:29:58 UTC (rev 349) @@ -951,8 +951,7 @@ pChn->nRealPan = pChn->nPan; } - if (pChn->nRealPan < 0) pChn->nRealPan = 0; - if (pChn->nRealPan > 256) pChn->nRealPan = 256; + pChn->nRealPan = CLAMP(pChn->nRealPan, 0, 256); pChn->nRampLength = 0; //Aux variables @@ -1231,7 +1230,7 @@ if (!(m_dwSongFlags & SONG_FIRSTTICK)) { - arpPos = (m_nTickCount - m_nMusicSpeed) % 3; + arpPos = ((int)m_nTickCount - (int)m_nMusicSpeed) % 3; if(arpPos < 0) arpPos += 3; switch(arpPos) { @@ -1445,7 +1444,7 @@ pdelta += pChn->nRealPan; pChn->nRealPan = CLAMP(pdelta, 0, 256); - if(IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPan = pChn->nRealPan; + //if(IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPan = pChn->nRealPan; // TODO } int nPeriodFrac = 0; // Instrument Auto-Vibrato This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-08-30 22:27:26
|
Revision: 350 http://modplug.svn.sourceforge.net/modplug/?rev=350&view=rev Author: saga-games Date: 2009-08-30 22:27:15 +0000 (Sun, 30 Aug 2009) Log Message: ----------- [Fix] S3M Loader: Small modifications to pattern loader to load somewhat broken S3M files [Fix] S3M Loader: Don't reset global volume to max if it is min for "new" modules [Fix] S3M Loader: Smarter Zxx conversion [Fix] S3M Saver: Was completely broken for a reason that's beyond my understanding :) (order size only has to be multiple of 2, not 16!) [Imp] Mod Conversion: Convert 500/600 commands properly from MOD to any format, Adjust sustain loops for XM files, removed XM arpeggio conversion (it might be unwanted) Modified Paths: -------------- trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/soundlib/Load_s3m.cpp Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-30 14:29:58 UTC (rev 349) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-30 22:27:15 UTC (rev 350) @@ -396,15 +396,22 @@ } // End if (oldTypeIsIT_MPT && newTypeIsS3M) - //////////////////////// - // Convert XM arpeggio - if(m->command == CMD_ARPEGGIO && (newTypeIsXM || oldTypeIsXM)) + + /////////////////////////////////////////////////// + // Convert MOD to anything - adjust effect memory + if (oldTypeIsMOD) { - // swap notes - m->param = ((m->param & 0x0F) << 4) | ((m->param & 0xF0) >> 4); - } + switch(m->command) + { + case CMD_TONEPORTAVOL: // lacks memory -> 500 is the same as 300 + if(m->param == 0x00) m->command = CMD_TONEPORTAMENTO; + break; + case CMD_VIBRATOVOL: // lacks memory -> 600 is the same as 400 + if(m->param == 0x00) m->command = CMD_VIBRATO; + break; + } + } // End if (oldTypeIsMOD && newTypeIsXM) - ///////////////////////////////////////////////////////////////////////////////// // Convert anything to MOD - remove volume column, adjust retrig, effect memory if (newTypeIsMOD) @@ -664,26 +671,38 @@ CSoundFile::FrequencyToTranspose(&m_SndFile.Samples[i]); if (!(m_SndFile.Samples[i].uFlags & CHN_PANNING)) m_SndFile.Samples[i].nPan = 128; } - BOOL bBrokenNoteMap = FALSE; - for (UINT j=1; j<=m_SndFile.m_nInstruments; j++) + bool bBrokenNoteMap = false, bBrokenSustainLoop = false; + for (UINT j = 1; j <= m_SndFile.m_nInstruments; j++) { MODINSTRUMENT *pIns = m_SndFile.Instruments[j]; if (pIns) { - for (UINT k=0; k<NOTE_MAX; k++) + for (UINT k = 0; k < NOTE_MAX; k++) { if ((pIns->NoteMap[k]) && (pIns->NoteMap[k] != (BYTE)(k+1))) { - bBrokenNoteMap = TRUE; + bBrokenNoteMap = true; break; } } + // Convert sustain loops to sustain "points" + if(pIns->VolEnv.nSustainStart != pIns->VolEnv.nSustainEnd) + { + pIns->VolEnv.nSustainEnd = pIns->VolEnv.nSustainStart; + bBrokenSustainLoop = true; + } + if(pIns->PanEnv.nSustainStart != pIns->PanEnv.nSustainEnd) + { + pIns->PanEnv.nSustainEnd = pIns->PanEnv.nSustainStart; + bBrokenSustainLoop = true; + } pIns->dwFlags &= ~(ENV_SETPANNING|ENV_VOLCARRY|ENV_PANCARRY|ENV_PITCHCARRY|ENV_FILTER|ENV_PITCH); pIns->nIFC &= 0x7F; pIns->nIFR &= 0x7F; } } if (bBrokenNoteMap) AddToLog("WARNING: Note Mapping will be lost when saving as XM.\n"); + if (bBrokenSustainLoop) AddToLog("WARNING: Sustain loops were converted to sustain points.\n"); } if(newTypeIsMOD) Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-30 14:29:58 UTC (rev 349) +++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-30 22:27:15 UTC (rev 350) @@ -18,43 +18,6 @@ extern WORD S3MFineTuneTable[16]; -static void HandleZxx(uint8& nType, MODCOMMAND* const m) -//------------------------------------------------------------------- -{ - if(nType == 0) - { - CString str; - str.Format(GetStrI18N("The S3M file contains Zxx effect. " - "It can be processed in the following ways:\n" - "Yes : Convert Zxx to S8x(set panning)-effects (PixPlay)\n" - "No : Remove Zxx effects\n" - "Cancel: Keep Zxx effects\n" - "\nNote that options (yes) and (no) modify the loaded pattern data." - )); - const int nResult = ::AfxMessageBox(str, MB_YESNOCANCEL|MB_ICONINFORMATION); - - if(nResult == IDYES) - nType = 2; - else if(nResult == IDNO) - nType = 3; - else - nType = 1; - } - if(nType != 1) - { - if(nType == 2) - { - m->command = CMD_S3MCMDEX; - m->param = 0x80 + (m->param & 0xF); - } - else - { - m->command = 0; - m->param = 0; - } - } -} - ////////////////////////////////////////////////////// // ScreamTracker S3M file support @@ -264,6 +227,7 @@ DWORD dwMemPos; BYTE insflags[128], inspack[128]; S3MFILEHEADER psfh = *(S3MFILEHEADER *)lpStream; + bool bKeepMidiMacros = false; psfh.reserved1 = LittleEndianW(psfh.reserved1); psfh.ordnum = LittleEndianW(psfh.ordnum); @@ -278,8 +242,26 @@ if (psfh.scrm != 0x4D524353) return false; if((psfh.cwtv & 0xF000) == 0x5000) // OpenMPT Version number (Major.Minor) + { m_dwLastSavedWithVersion = (psfh.cwtv & 0x0FFF) << 16; + bKeepMidiMacros = true; // simply load Zxx commands + } + if(psfh.cwtv == 0x1320 && psfh.special == 0 && (psfh.ordnum & 0x0F) == 0 && psfh.ultraclicks == 0 && (psfh.flags & ~0x50) == 0) + { + // MPT 1.16 and older versions of OpenMPT + m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 16, 00, 00); + bKeepMidiMacros = true; // simply load Zxx commands + } + if((psfh.cwtv & 0xF000) >= 0x2000) + { + // 2xyy - Orpheus, 3xyy - IT, 4xyy - Schism, 5xyy - OpenMPT + bKeepMidiMacros = true; // simply load Zxx commands + } + + if(!bKeepMidiMacros) // Remove macros so they don't interfere with other tunes + memset(&m_MidiCfg, 0, sizeof(m_MidiCfg)); + dwMemPos = 0x60; m_nType = MOD_TYPE_S3M; memset(m_szNames,0,sizeof(m_szNames)); @@ -292,7 +274,8 @@ m_nDefaultTempo = CLAMP(m_nDefaultTempo, 32, 255); // Global Volume m_nDefaultGlobalVolume = psfh.globalvol << 2; - if ((!m_nDefaultGlobalVolume) || (m_nDefaultGlobalVolume > 256)) m_nDefaultGlobalVolume = 256; + if(!m_nDefaultGlobalVolume && psfh.cwtv < 0x1320) m_nDefaultGlobalVolume = 256; // not very reliable, but it fixes a few tunes + if(m_nDefaultGlobalVolume > 256) m_nDefaultGlobalVolume = 256; m_nSamplePreAmp = psfh.mastervol & 0x7F; // Bit 8 = Stereo (we always use stereo) // Channels m_nChannels = 4; @@ -386,8 +369,14 @@ //ASSERT(iLooplength == 0 || iLooplength > 4); } } + + /* Try to find out if Zxx commands are supposed to be panning commands (PixPlay). + We won't convert if there are not enough Zxx commands, too "high" Zxx commands + or there are only "left" or "right" pannings (we assume that stereo should be somewhat balanced) */ + bool bDoNotConvertZxx = false; + int iZxxCountRight = 0, iZxxCountLeft = 0; + // Reading patterns - uint8 nZxxHandling = 0; for (UINT iPat=0; iPat<patnum; iPat++) { UINT nInd = ((DWORD)ptr[nins+iPat]) << 4; @@ -402,8 +391,9 @@ MODCOMMAND *p = Patterns[iPat]; UINT row = 0; UINT j = 0; - while (j < len) + while (row < 64) // this fixes ftp://us.aminet.net/pub/aminet/mods/8voic/s3m_hunt.lha (was: while (j < len)) { + if(j + nInd + 1 >= dwMemLength) break; BYTE b = src[j++]; if (!b) { @@ -416,6 +406,7 @@ MODCOMMAND *m = &p[row*m_nChannels+chn]; if (b & 0x20) { + if(j + nInd + 2 >= dwMemLength) break; m->note = src[j++]; if (m->note < 0xF0) m->note = (m->note & 0x0F) + 12*(m->note >> 4) + 13; else if (m->note == 0xFF) m->note = NOTE_NONE; @@ -423,6 +414,7 @@ } if (b & 0x40) { + if(j + nInd + 1 >= dwMemLength) break; UINT vol = src[j++]; if ((vol >= 128) && (vol <= 192)) { @@ -437,12 +429,22 @@ } if (b & 0x80) { + if(j + nInd + 2 >= dwMemLength) break; m->command = src[j++]; m->param = src[j++]; if (m->command) S3MConvert(m, FALSE); if(m->command == CMD_MIDI) { - HandleZxx(nZxxHandling, m); + if(m->param > 0x0F) + { + // PixPlay has Z00 to Z0F panning, so we ignore this. + bDoNotConvertZxx = true; + } + else + { + if(m->param < 0x08) iZxxCountLeft++; + if(m->param > 0x08) iZxxCountRight++; + } } } } else @@ -451,10 +453,27 @@ if (b & 0x40) j++; if (b & 0x80) j += 2; } - if (j >= len) break; } } } + + if((UINT)(iZxxCountLeft + iZxxCountRight) >= m_nChannels && !bDoNotConvertZxx && (iZxxCountLeft - iZxxCountRight > -(int)m_nChannels)) + { + // there are enough Zxx commands, so let's assume this was made to be played with PixPlay + for(PATTERNINDEX nPat = 0; nPat < Patterns.Size(); nPat++) if(Patterns[nPat]) + { + MODCOMMAND *m = Patterns[nPat]; + for(UINT len = PatternSize[nPat] * m_nChannels; len; m++, len--) + { + if(m->command == CMD_MIDI) + { + m->command = CMD_S3MCMDEX; + m->param |= 0x80; + } + } + } + } + // Reading samples for (UINT iRaw=1; iRaw<=insnum; iRaw++) if ((Samples[iRaw].nLength) && (insfile[iRaw])) { @@ -469,11 +488,6 @@ m_nMaxPeriod = 32767; if (psfh.flags & 0x10) m_dwSongFlags |= SONG_AMIGALIMITS; - if(nZxxHandling != 0 && nZxxHandling != 1 && GetpModDoc() != 0) - { - GetpModDoc()->SetModified(); - GetpModDoc()->SetShowSaveDialog(true); - } return true; } @@ -507,15 +521,14 @@ header[0x1B] = 0; header[0x1C] = 0x1A; header[0x1D] = 0x10; - // Changes to 1.17.02.53: - // -Try to save whole sequence instead of stopping on first empty order. - // -With more than 0xF0 orders, limit sequence to 0xF0 instead of just masking with 0xF0. - //TODO: Check whether the 0xF0 mask is correct. - // (there are two bytes reserved from the header, so why 0xF0 mask?). - //nbo = (GetNumPatterns() + 15) & 0xF0; + nbo = Order.GetLengthTailTrimmed(); - if(nbo > 0xF0) nbo = 0xF0; - if (!nbo) nbo = 1; + if (nbo < 2) + nbo = 2; + else if (nbo & 1) // number of orders must be even + nbo++; + nbo = (nbo + 15) & 0xF0; // TODO why does it not work otherwise? nbo should be multiple of 2, not 16! + if(nbo > 0xF0) nbo = 0xF0; // sequence too long header[0x20] = nbo & 0xFF; header[0x21] = nbo >> 8; nbi = m_nInstruments; @@ -536,7 +549,7 @@ // Following: One nibble = Major version, one byte = Minor version (hex) MptVersion::VersionNum vVersion = MptVersion::num; header[0x28] = (BYTE)((vVersion >> 16) & 0xFF); // the "17" in OpenMPT 1.17 - header[0x29] = 0x50 | (BYTE)((vVersion >> 24) & 0x0F); // the "1" in OpenMPT 1.17 + OpenMPT Identifier 5 (works only for versions up to 15.99 :)) + header[0x29] = 0x50 | (BYTE)((vVersion >> 24) & 0x0F); // the "1." in OpenMPT 1.17 + OpenMPT Identifier 5 (works only for versions up to 9.99 :)) header[0x2A] = 0x02; // Version = 1 => Signed samples header[0x2B] = 0x00; header[0x2C] = 'S'; @@ -548,7 +561,7 @@ header[0x32] = CLAMP(m_nDefaultTempo, 32, 255); header[0x33] = CLAMP(m_nSamplePreAmp, 0x10, 0x7F) | 0x80; // Bit 8 = Stereo header[0x34] = 0x10; // 16 Channels for UltraClick removal - header[0x35] = 0xFC; + header[0x35] = 0xFC; // Write pan positions for (i=0; i<32; i++) { if (i < m_nChannels) @@ -562,7 +575,7 @@ memset(patptr, 0, sizeof(patptr)); memset(insptr, 0, sizeof(insptr)); UINT ofs0 = 0x60 + nbo; - UINT ofs1 = ((0x60 + nbo + nbi*2 + nbp*2 + 15) & 0xFFF0) + 0x20; + UINT ofs1 = ((0x60 + nbo + nbi * 2 + nbp * 2 + 15) & 0xFFF0) + ((header[0x35] == 0xFC) ? 0x20 : 0); UINT ofs = ofs1; for (i=0; i<nbi; i++) insptr[i] = (WORD)((ofs + i*0x50) / 16); for (i=0; i<nbp; i++) patptr[i] = (WORD)((ofs + nbi*0x50) / 16); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-09-01 18:50:54
|
Revision: 351 http://modplug.svn.sourceforge.net/modplug/?rev=351&view=rev Author: relabsoluness Date: 2009-09-01 18:50:33 +0000 (Tue, 01 Sep 2009) Log Message: ----------- [Ref] Moved constants from Sndfile.h to a new file, renamed OrderToPatternTable files, added some utility functions, minor code cleanup. Modified Paths: -------------- trunk/OpenMPT/mptrack/misc_util.h trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/typedefs.h trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/mod_specifications.h trunk/OpenMPT/soundlib/pattern.h trunk/OpenMPT/soundlib/patternContainer.h Added Paths: ----------- trunk/OpenMPT/soundlib/ModSequence.cpp trunk/OpenMPT/soundlib/ModSequence.h trunk/OpenMPT/soundlib/Snd_defs.h Removed Paths: ------------- trunk/OpenMPT/soundlib/OrderToPatternTable.cpp trunk/OpenMPT/soundlib/OrderToPatternTable.h Modified: trunk/OpenMPT/mptrack/misc_util.h =================================================================== --- trunk/OpenMPT/mptrack/misc_util.h 2009-08-30 22:27:15 UTC (rev 350) +++ trunk/OpenMPT/mptrack/misc_util.h 2009-09-01 18:50:33 UTC (rev 351) @@ -81,4 +81,33 @@ LPCCH LoadResource(LPCTSTR lpName, LPCTSTR lpType, LPCCH& pData, size_t& nSize, HGLOBAL& hglob); +namespace utilImpl +{ + template <bool bMemcpy> + struct ArrayCopyImpl {}; + + template <> + struct ArrayCopyImpl<true> + { + template <class T> + static void Do(T* pDst, const T* pSrc, const size_t n) {memcpy(pDst, pSrc, sizeof(T) * n);} + }; + + template <> + struct ArrayCopyImpl<false> + { + template <class T> + static void Do(T* pDst, const T* pSrc, const size_t n) {std::copy(pSrc, pSrc + n, pDst);} + }; +} // namespace utilImpl + + +// Copies n elements from array pSrc to array pDst. +// If the source and destination arrays overlap, behaviour is undefined. +template <class T> +void ArrayCopy(T* pDst, const T* pSrc, const size_t n) +{ + utilImpl::ArrayCopyImpl<std::tr1::has_trivial_assign<T>::value>::Do(pDst, pSrc, n); +} + #endif Modified: trunk/OpenMPT/mptrack/mptrack.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack.vcproj 2009-08-30 22:27:15 UTC (rev 350) +++ trunk/OpenMPT/mptrack/mptrack.vcproj 2009-09-01 18:50:33 UTC (rev 351) @@ -367,6 +367,9 @@ RelativePath=".\Modedit.cpp"> </File> <File + RelativePath="..\soundlib\ModSequence.cpp"> + </File> + <File RelativePath="..\soundlib\modsmp_ctrl.cpp"> </File> <File @@ -397,9 +400,6 @@ RelativePath=".\OpenGLEditor.cpp"> </File> <File - RelativePath="..\soundlib\OrderToPatternTable.cpp"> - </File> - <File RelativePath="..\soundlib\pattern.cpp"> </File> <File @@ -795,6 +795,9 @@ RelativePath=".\moddoc.h"> </File> <File + RelativePath="..\soundlib\ModSequence.h"> + </File> + <File RelativePath="..\soundlib\modsmp_ctrl.h"> </File> <File @@ -819,12 +822,6 @@ RelativePath=".\OpenGLEditor.h"> </File> <File - RelativePath=".\order.h"> - </File> - <File - RelativePath="..\soundlib\OrderToPatternTable.h"> - </File> - <File RelativePath="..\soundlib\pattern.h"> </File> <File @@ -852,6 +849,9 @@ RelativePath=".\serialization_utils.h"> </File> <File + RelativePath="..\soundlib\Snd_defs.h"> + </File> + <File RelativePath="..\Soundlib\snddev.h"> </File> <File Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-08-30 22:27:15 UTC (rev 350) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-09-01 18:50:33 UTC (rev 351) @@ -493,6 +493,10 @@ > </File> <File + RelativePath="..\soundlib\ModSequence.cpp" + > + </File> + <File RelativePath="..\soundlib\modsmp_ctrl.cpp" > </File> @@ -533,10 +537,6 @@ > </File> <File - RelativePath="..\soundlib\OrderToPatternTable.cpp" - > - </File> - <File RelativePath="..\soundlib\pattern.cpp" > </File> @@ -1051,6 +1051,10 @@ > </File> <File + RelativePath="..\soundlib\ModSequence.h" + > + </File> + <File RelativePath="..\soundlib\modsmp_ctrl.h" > </File> @@ -1083,14 +1087,6 @@ > </File> <File - RelativePath=".\order.h" - > - </File> - <File - RelativePath="..\soundlib\OrderToPatternTable.h" - > - </File> - <File RelativePath="..\soundlib\pattern.h" > </File> @@ -1127,6 +1123,10 @@ > </File> <File + RelativePath="..\soundlib\Snd_defs.h" + > + </File> + <File RelativePath="..\Soundlib\snddev.h" > </File> Modified: trunk/OpenMPT/mptrack/typedefs.h =================================================================== --- trunk/OpenMPT/mptrack/typedefs.h 2009-08-30 22:27:15 UTC (rev 350) +++ trunk/OpenMPT/mptrack/typedefs.h 2009-09-01 18:50:33 UTC (rev 351) @@ -31,26 +31,26 @@ typedef float float32; -typedef uint32 ROWINDEX; - const ROWINDEX ROWINDEX_MAX = uint32_max; -typedef uint16 CHANNELINDEX; - const CHANNELINDEX CHANNELINDEX_MAX = uint16_max; - const CHANNELINDEX CHANNELINDEX_INVALID = CHANNELINDEX_MAX; -typedef uint16 ORDERINDEX; - const ORDERINDEX ORDERINDEX_MAX = uint16_max; - const ORDERINDEX ORDERINDEX_INVALID = ORDERINDEX_MAX; -typedef uint16 PATTERNINDEX; - const PATTERNINDEX PATTERNINDEX_MAX = uint16_max; - const PATTERNINDEX PATTERNINDEX_INVALID = PATTERNINDEX_MAX; -typedef uint8 PLUGINDEX; -typedef uint16 TEMPO; -typedef uint16 SAMPLEINDEX; - const SAMPLEINDEX SAMPLEINDEX_MAX = uint16_max; - const SAMPLEINDEX SAMPLEINDEX_INVALID = SAMPLEINDEX_MAX; -typedef uint16 INSTRUMENTINDEX; - const SAMPLEINDEX INSTRUMENTINDEX_MAX = uint16_max; - const SAMPLEINDEX INSTRUMENTINDEX_INVALID = INSTRUMENTINDEX_MAX; -typedef uint32 MODTYPE; +#if !_HAS_TR1 + namespace std + { + namespace tr1 + { + template <class T> struct has_trivial_assign {static const bool value = false;}; + #define SPECIALIZE_TRIVIAL_ASSIGN(type) template <> struct has_trivial_assign<type> {static const bool value = true;} + SPECIALIZE_TRIVIAL_ASSIGN(int8); + SPECIALIZE_TRIVIAL_ASSIGN(uint8); + SPECIALIZE_TRIVIAL_ASSIGN(int16); + SPECIALIZE_TRIVIAL_ASSIGN(uint16); + SPECIALIZE_TRIVIAL_ASSIGN(int32); + SPECIALIZE_TRIVIAL_ASSIGN(uint32); + SPECIALIZE_TRIVIAL_ASSIGN(int64); + SPECIALIZE_TRIVIAL_ASSIGN(uint64); + #undef SPECIALIZE_TRIVIAL_ASSIGN + }; + }; +#endif + #endif Copied: trunk/OpenMPT/soundlib/ModSequence.cpp (from rev 349, trunk/OpenMPT/soundlib/OrderToPatternTable.cpp) =================================================================== --- trunk/OpenMPT/soundlib/ModSequence.cpp (rev 0) +++ trunk/OpenMPT/soundlib/ModSequence.cpp 2009-09-01 18:50:33 UTC (rev 351) @@ -0,0 +1,221 @@ +#include "stdafx.h" +#include "sndfile.h" +#include "ModSequence.h" +#include "../mptrack/serialization_utils.h" + +#define str_SequenceTruncationNote (GetStrI18N((_TEXT("Module has sequence of length %u; it will be truncated to maximum supported length, %u.")))) + +DWORD COrderToPatternTable::Deserialize(const BYTE* const src, const DWORD memLength) +//------------------------------------------------------------------------- +{ + if(memLength < 2 + 4) return 0; + uint16 version = 0; + uint32 s = 0; + DWORD memPos = 0; + memcpy(&version, src, sizeof(version)); + memPos += sizeof(version); + if(version != 0) return memPos; + memcpy(&s, src+memPos, sizeof(s)); + memPos += sizeof(s); + if(s > 65000) return true; + if(memLength < memPos+s*4) return memPos; + + const uint32 nOriginalSize = s; + if(s > ModSpecs::mptm.ordersMax) + s = ModSpecs::mptm.ordersMax; + + resize(max(s, MAX_ORDERS)); + for(size_t i = 0; i<s; i++, memPos +=4 ) + { + uint32 temp; + memcpy(&temp, src+memPos, 4); + (*this)[i] = static_cast<PATTERNINDEX>(temp); + } + memPos += 4*(nOriginalSize - s); + return memPos; +} + + +size_t COrderToPatternTable::WriteToByteArray(BYTE* dest, const UINT numOfBytes, const UINT destSize) +//----------------------------------------------------------------------------- +{ + if(numOfBytes > destSize) return true; + if(size() < numOfBytes) resize(numOfBytes, 0xFF); + UINT i = 0; + for(i = 0; i<numOfBytes; i++) + { + dest[i] = static_cast<BYTE>((*this)[i]); + } + return i; //Returns the number of bytes written. +} + + +size_t COrderToPatternTable::WriteAsByte(FILE* f, const UINT count) +//--------------------------------------------------------------- +{ + if(size() < count) resize(count, GetInvalidPatIndex()); + + size_t i = 0; + + for(i = 0; i<count; i++) + { + const PATTERNINDEX pat = (*this)[i]; + BYTE temp = static_cast<BYTE>((*this)[i]); + + if(pat > 0xFD) + { + if(pat == GetInvalidPatIndex()) temp = 0xFF; + else temp = 0xFE; + } + fwrite(&temp, 1, 1, f); + } + return i; //Returns the number of bytes written. +} + +bool COrderToPatternTable::ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength) +//------------------------------------------------------------------------- +{ + if(howMany < 0 || howMany > memLength) return true; + if(m_rSndFile.GetType() != MOD_TYPE_MPT && howMany > MAX_ORDERS) return true; + + if(size() < static_cast<size_t>(howMany)) + resize(howMany, GetInvalidPatIndex()); + + for(int i = 0; i<howMany; i++, pFrom++) + (*this)[i] = *pFrom; + return false; +} + + +bool COrderToPatternTable::NeedsExtraDatafield() const +//---------------------------------------------- +{ + if(m_rSndFile.GetType() == MOD_TYPE_MPT && m_rSndFile.Patterns.Size() > 0xFD) + return true; + else + return false; +} + + +void COrderToPatternTable::OnModTypeChanged(const MODTYPE oldtype) +//---------------------------------------------------------------- +{ + const CModSpecifications specs = m_rSndFile.GetModSpecifications(); + + //Resize orderlist if needed. Because old orderlist had MAX_ORDERS(256) elements, not making it + //smaller than that even if the modtype doesn't support that many orders. + if(specs.ordersMax < GetCount()) + { + resize(max(MAX_ORDERS, specs.ordersMax)); + for(ORDERINDEX i = GetCount(); i>specs.ordersMax; --i) (*this)[i-1] = GetInvalidPatIndex(); + } + if (GetCount() < MAX_ORDERS) + resize(MAX_ORDERS, GetInvalidPatIndex()); + + //Replace items used to denote end of song/skip order. + replace(begin(), end(), GetInvalidPatIndex(oldtype), GetInvalidPatIndex()); + replace(begin(), end(), GetIgnoreIndex(oldtype), GetIgnoreIndex()); +} + + +ORDERINDEX COrderToPatternTable::GetLengthTailTrimmed() const +//----------------------------------------------------------- +{ + ORDERINDEX nEnd = GetCount(); + if(nEnd == 0) return 0; + nEnd--; + const PATTERNINDEX iInvalid = GetInvalidPatIndex(); + while(nEnd > 0 && (*this)[nEnd] == iInvalid) + nEnd--; + return ((*this)[nEnd] == iInvalid) ? 0 : nEnd+1; +} + + +ORDERINDEX COrderToPatternTable::GetLengthFirstEmpty() const +//---------------------------------------------------------- +{ + const ORDERINDEX nLength = GetCount(); + ORDERINDEX nMax = 0; + while ((nMax < nLength) && ((*this)[nMax] != (*this).GetInvalidPatIndex())) nMax++; + return nMax; +} + + +ORDERINDEX COrderToPatternTable::GetNextOrderIgnoringSkips(const ORDERINDEX start) const +//------------------------------------------------------------------------------------- +{ + const ORDERINDEX count = GetCount(); + if(count == 0) return 0; + ORDERINDEX next = min(count-1, start+1); + while(next+1 < count && (*this)[next] == GetIgnoreIndex()) next++; + return next; +} + +ORDERINDEX COrderToPatternTable::GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const +//------------------------------------------------------------------------------------- +{ + const ORDERINDEX count = GetCount(); + if(start == 0 || count == 0) return 0; + ORDERINDEX prev = min(start-1, count-1); + while(prev > 0 && (*this)[prev] == GetIgnoreIndex()) prev--; + return prev; +} + + +void COrderToPatternTable::Init() +//------------------------------- +{ + resize(MAX_ORDERS, GetInvalidPatIndex()); + for(ORDERINDEX i = 0; i < GetCount(); i++) + { + (*this)[i] = GetInvalidPatIndex(); + } +} + + + +PATTERNINDEX COrderToPatternTable::GetInvalidPatIndex(const MODTYPE type) {return type == MOD_TYPE_MPT ? 65535 : 0xFF;} +PATTERNINDEX COrderToPatternTable::GetIgnoreIndex(const MODTYPE type) {return type == MOD_TYPE_MPT ? 65534 : 0xFE;} + +PATTERNINDEX COrderToPatternTable::GetInvalidPatIndex() const {return GetInvalidPatIndex(m_rSndFile.GetType());} +PATTERNINDEX COrderToPatternTable::GetIgnoreIndex() const {return GetIgnoreIndex(m_rSndFile.GetType());} + + +void ReadModSequence(std::istream& iStrm, COrderToPatternTable& seq, const size_t) +//-------------------------------------------------------------------------------- +{ + uint16 size; + srlztn::Binaryread<uint16>(iStrm, size); + if(size > ModSpecs::mptm.ordersMax) + { + // Hack: Show message here if trying to load longer sequence than what is supported. + CString str; str.Format(str_SequenceTruncationNote, size, ModSpecs::mptm.ordersMax); + AfxMessageBox(str, MB_ICONWARNING); + size = ModSpecs::mptm.ordersMax; + } + seq.resize(max(size, MAX_ORDERS), seq.GetInvalidPatIndex()); + if(size == 0) + { seq.Init(); return; } + + for(size_t i = 0; i < size; i++) + { + uint16 temp; + srlztn::Binaryread<uint16>(iStrm, temp); + seq[i] = temp; + } +} + + +void WriteModSequence(std::ostream& oStrm, const COrderToPatternTable& seq) +//------------------------------------------------------------------------- +{ + uint16 size = seq.GetCount(); + srlztn::Binarywrite<uint16>(oStrm, size); + const COrderToPatternTable::const_iterator endIter = seq.end(); + for(COrderToPatternTable::const_iterator citer = seq.begin(); citer != endIter; citer++) + { + const uint16 temp = static_cast<uint16>(*citer); + srlztn::Binarywrite<uint16>(oStrm, temp); + } +} + Copied: trunk/OpenMPT/soundlib/ModSequence.h (from rev 349, trunk/OpenMPT/soundlib/OrderToPatternTable.h) =================================================================== --- trunk/OpenMPT/soundlib/ModSequence.h (rev 0) +++ trunk/OpenMPT/soundlib/ModSequence.h 2009-09-01 18:50:33 UTC (rev 351) @@ -0,0 +1,68 @@ +#ifndef ORDERTOPATTERNTABLE_H +#define ORDERTOPATTERNTABLE_H + +#include <vector> +using std::vector; + +class CSoundFile; + + +#pragma warning(disable:4244) //conversion from 'type1' to 'type2', possible loss of data. + + +//============================================== +class COrderToPatternTable : public vector<PATTERNINDEX> +//============================================== +{ +public: + COrderToPatternTable(const CSoundFile& sndFile) : m_rSndFile(sndFile) {} + + // Initialize default sized sequence. + void Init(); + + bool ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength); + + size_t WriteAsByte(FILE* f, const UINT count); + + size_t WriteToByteArray(BYTE* dest, const UINT numOfBytes, const UINT destSize); + + ORDERINDEX GetCount() const {return size();} + + //Deprecated function used for MPTm's created in 1.17.02.46 - 1.17.02.48. + DWORD Deserialize(const BYTE* const src, const DWORD memLength); + + //Returns true if the IT orderlist datafield is not sufficient to store orderlist information. + bool NeedsExtraDatafield() const; + + void OnModTypeChanged(const MODTYPE oldtype); + + // Returns length of sequence without counting trailing '---' items. + ORDERINDEX GetLengthTailTrimmed() const; + + // Returns length of sequence stopping counting on first '---' (or at the end of sequence). + ORDERINDEX GetLengthFirstEmpty() const; + + PATTERNINDEX GetInvalidPatIndex() const; //To correspond 0xFF + static PATTERNINDEX GetInvalidPatIndex(const MODTYPE type); + + PATTERNINDEX GetIgnoreIndex() const; //To correspond 0xFE + static PATTERNINDEX GetIgnoreIndex(const MODTYPE type); + + //Returns the previous/next order ignoring skip indeces(+++). + //If no previous/next order exists, return first/last order, and zero + //when orderlist is empty. + ORDERINDEX GetNextOrderIgnoringSkips(const ORDERINDEX start) const; + ORDERINDEX GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const; + +private: + const CSoundFile& m_rSndFile; +}; + +#pragma warning(default:4244) //conversion from 'type1' to 'type2', possible loss of data. + + +void ReadModSequence(std::istream& iStrm, COrderToPatternTable& seq, const size_t nSize = 0); +void WriteModSequence(std::ostream& oStrm, const COrderToPatternTable& seq); + +#endif + Deleted: trunk/OpenMPT/soundlib/OrderToPatternTable.cpp =================================================================== --- trunk/OpenMPT/soundlib/OrderToPatternTable.cpp 2009-08-30 22:27:15 UTC (rev 350) +++ trunk/OpenMPT/soundlib/OrderToPatternTable.cpp 2009-09-01 18:50:33 UTC (rev 351) @@ -1,221 +0,0 @@ -#include "stdafx.h" -#include "sndfile.h" -#include "ordertopatterntable.h" -#include "../mptrack/serialization_utils.h" - -#define str_SequenceTruncationNote (GetStrI18N((_TEXT("Module has sequence of length %u; it will be truncated to maximum supported length, %u.")))) - -DWORD COrderToPatternTable::Deserialize(const BYTE* const src, const DWORD memLength) -//------------------------------------------------------------------------- -{ - if(memLength < 2 + 4) return 0; - uint16 version = 0; - uint32 s = 0; - DWORD memPos = 0; - memcpy(&version, src, sizeof(version)); - memPos += sizeof(version); - if(version != 0) return memPos; - memcpy(&s, src+memPos, sizeof(s)); - memPos += sizeof(s); - if(s > 65000) return true; - if(memLength < memPos+s*4) return memPos; - - const uint32 nOriginalSize = s; - if(s > ModSpecs::mptm.ordersMax) - s = ModSpecs::mptm.ordersMax; - - resize(max(s, MAX_ORDERS)); - for(size_t i = 0; i<s; i++, memPos +=4 ) - { - uint32 temp; - memcpy(&temp, src+memPos, 4); - (*this)[i] = static_cast<PATTERNINDEX>(temp); - } - memPos += 4*(nOriginalSize - s); - return memPos; -} - - -size_t COrderToPatternTable::WriteToByteArray(BYTE* dest, const UINT numOfBytes, const UINT destSize) -//----------------------------------------------------------------------------- -{ - if(numOfBytes > destSize) return true; - if(size() < numOfBytes) resize(numOfBytes, 0xFF); - UINT i = 0; - for(i = 0; i<numOfBytes; i++) - { - dest[i] = static_cast<BYTE>((*this)[i]); - } - return i; //Returns the number of bytes written. -} - - -size_t COrderToPatternTable::WriteAsByte(FILE* f, const UINT count) -//--------------------------------------------------------------- -{ - if(size() < count) resize(count, GetInvalidPatIndex()); - - size_t i = 0; - - for(i = 0; i<count; i++) - { - const PATTERNINDEX pat = (*this)[i]; - BYTE temp = static_cast<BYTE>((*this)[i]); - - if(pat > 0xFD) - { - if(pat == GetInvalidPatIndex()) temp = 0xFF; - else temp = 0xFE; - } - fwrite(&temp, 1, 1, f); - } - return i; //Returns the number of bytes written. -} - -bool COrderToPatternTable::ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength) -//------------------------------------------------------------------------- -{ - if(howMany < 0 || howMany > memLength) return true; - if(m_rSndFile.GetType() != MOD_TYPE_MPT && howMany > MAX_ORDERS) return true; - - if(size() < static_cast<size_t>(howMany)) - resize(howMany, GetInvalidPatIndex()); - - for(int i = 0; i<howMany; i++, pFrom++) - (*this)[i] = *pFrom; - return false; -} - - -bool COrderToPatternTable::NeedsExtraDatafield() const -//---------------------------------------------- -{ - if(m_rSndFile.GetType() == MOD_TYPE_MPT && m_rSndFile.Patterns.Size() > 0xFD) - return true; - else - return false; -} - - -void COrderToPatternTable::OnModTypeChanged(const MODTYPE oldtype) -//---------------------------------------------------------------- -{ - const CModSpecifications specs = m_rSndFile.GetModSpecifications(); - - //Resize orderlist if needed. Because old orderlist had MAX_ORDERS(256) elements, not making it - //smaller than that even if the modtype doesn't support that many orders. - if(specs.ordersMax < GetCount()) - { - resize(max(MAX_ORDERS, specs.ordersMax)); - for(ORDERINDEX i = GetCount(); i>specs.ordersMax; --i) (*this)[i-1] = GetInvalidPatIndex(); - } - if (GetCount() < MAX_ORDERS) - resize(MAX_ORDERS, GetInvalidPatIndex()); - - //Replace items used to denote end of song/skip order. - replace(begin(), end(), GetInvalidPatIndex(oldtype), GetInvalidPatIndex()); - replace(begin(), end(), GetIgnoreIndex(oldtype), GetIgnoreIndex()); -} - - -ORDERINDEX COrderToPatternTable::GetLengthTailTrimmed() const -//----------------------------------------------------------- -{ - ORDERINDEX nEnd = GetCount(); - if(nEnd == 0) return 0; - nEnd--; - const PATTERNINDEX iInvalid = GetInvalidPatIndex(); - while(nEnd > 0 && (*this)[nEnd] == iInvalid) - nEnd--; - return ((*this)[nEnd] == iInvalid) ? 0 : nEnd+1; -} - - -ORDERINDEX COrderToPatternTable::GetLengthFirstEmpty() const -//---------------------------------------------------------- -{ - const ORDERINDEX nLength = GetCount(); - ORDERINDEX nMax = 0; - while ((nMax < nLength) && ((*this)[nMax] != (*this).GetInvalidPatIndex())) nMax++; - return nMax; -} - - -ORDERINDEX COrderToPatternTable::GetNextOrderIgnoringSkips(const ORDERINDEX start) const -//------------------------------------------------------------------------------------- -{ - const ORDERINDEX count = GetCount(); - if(count == 0) return 0; - ORDERINDEX next = min(count-1, start+1); - while(next+1 < count && (*this)[next] == GetIgnoreIndex()) next++; - return next; -} - -ORDERINDEX COrderToPatternTable::GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const -//------------------------------------------------------------------------------------- -{ - const ORDERINDEX count = GetCount(); - if(start == 0 || count == 0) return 0; - ORDERINDEX prev = min(start-1, count-1); - while(prev > 0 && (*this)[prev] == GetIgnoreIndex()) prev--; - return prev; -} - - -void COrderToPatternTable::Init() -//------------------------------- -{ - resize(MAX_ORDERS, GetInvalidPatIndex()); - for(ORDERINDEX i = 0; i < GetCount(); i++) - { - (*this)[i] = GetInvalidPatIndex(); - } -} - - - -PATTERNINDEX COrderToPatternTable::GetInvalidPatIndex(const MODTYPE type) {return type == MOD_TYPE_MPT ? 65535 : 0xFF;} -PATTERNINDEX COrderToPatternTable::GetIgnoreIndex(const MODTYPE type) {return type == MOD_TYPE_MPT ? 65534 : 0xFE;} - -PATTERNINDEX COrderToPatternTable::GetInvalidPatIndex() const {return GetInvalidPatIndex(m_rSndFile.GetType());} -PATTERNINDEX COrderToPatternTable::GetIgnoreIndex() const {return GetIgnoreIndex(m_rSndFile.GetType());} - - -void ReadModSequence(std::istream& iStrm, COrderToPatternTable& seq, const size_t) -//-------------------------------------------------------------------------------- -{ - uint16 size; - srlztn::Binaryread<uint16>(iStrm, size); - if(size > ModSpecs::mptm.ordersMax) - { - // Hack: Show message here if trying to load longer sequence than what is supported. - CString str; str.Format(str_SequenceTruncationNote, size, ModSpecs::mptm.ordersMax); - AfxMessageBox(str, MB_ICONWARNING); - size = ModSpecs::mptm.ordersMax; - } - seq.resize(max(size, MAX_ORDERS), seq.GetInvalidPatIndex()); - if(size == 0) - { seq.Init(); return; } - - for(size_t i = 0; i < size; i++) - { - uint16 temp; - srlztn::Binaryread<uint16>(iStrm, temp); - seq[i] = temp; - } -} - - -void WriteModSequence(std::ostream& oStrm, const COrderToPatternTable& seq) -//------------------------------------------------------------------------- -{ - uint16 size = seq.GetCount(); - srlztn::Binarywrite<uint16>(oStrm, size); - const COrderToPatternTable::const_iterator endIter = seq.end(); - for(COrderToPatternTable::const_iterator citer = seq.begin(); citer != endIter; citer++) - { - const uint16 temp = static_cast<uint16>(*citer); - srlztn::Binarywrite<uint16>(oStrm, temp); - } -} - Deleted: trunk/OpenMPT/soundlib/OrderToPatternTable.h =================================================================== --- trunk/OpenMPT/soundlib/OrderToPatternTable.h 2009-08-30 22:27:15 UTC (rev 350) +++ trunk/OpenMPT/soundlib/OrderToPatternTable.h 2009-09-01 18:50:33 UTC (rev 351) @@ -1,68 +0,0 @@ -#ifndef ORDERTOPATTERNTABLE_H -#define ORDERTOPATTERNTABLE_H - -#include <vector> -using std::vector; - -class CSoundFile; - - -#pragma warning(disable:4244) //conversion from 'type1' to 'type2', possible loss of data. - - -//============================================== -class COrderToPatternTable : public vector<PATTERNINDEX> -//============================================== -{ -public: - COrderToPatternTable(const CSoundFile& sndFile) : m_rSndFile(sndFile) {} - - // Initialize default sized sequence. - void Init(); - - bool ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength); - - size_t WriteAsByte(FILE* f, const UINT count); - - size_t WriteToByteArray(BYTE* dest, const UINT numOfBytes, const UINT destSize); - - ORDERINDEX GetCount() const {return size();} - - //Deprecated function used for MPTm's created in 1.17.02.46 - 1.17.02.48. - DWORD Deserialize(const BYTE* const src, const DWORD memLength); - - //Returns true if the IT orderlist datafield is not sufficient to store orderlist information. - bool NeedsExtraDatafield() const; - - void OnModTypeChanged(const MODTYPE oldtype); - - // Returns length of sequence without counting trailing '---' items. - ORDERINDEX GetLengthTailTrimmed() const; - - // Returns length of sequence stopping counting on first '---' (or at the end of sequence). - ORDERINDEX GetLengthFirstEmpty() const; - - PATTERNINDEX GetInvalidPatIndex() const; //To correspond 0xFF - static PATTERNINDEX GetInvalidPatIndex(const MODTYPE type); - - PATTERNINDEX GetIgnoreIndex() const; //To correspond 0xFE - static PATTERNINDEX GetIgnoreIndex(const MODTYPE type); - - //Returns the previous/next order ignoring skip indeces(+++). - //If no previous/next order exists, return first/last order, and zero - //when orderlist is empty. - ORDERINDEX GetNextOrderIgnoringSkips(const ORDERINDEX start) const; - ORDERINDEX GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const; - -private: - const CSoundFile& m_rSndFile; -}; - -#pragma warning(default:4244) //conversion from 'type1' to 'type2', possible loss of data. - - -void ReadModSequence(std::istream& iStrm, COrderToPatternTable& seq, const size_t nSize = 0); -void WriteModSequence(std::ostream& oStrm, const COrderToPatternTable& seq); - -#endif - Added: trunk/OpenMPT/soundlib/Snd_defs.h =================================================================== --- trunk/OpenMPT/soundlib/Snd_defs.h (rev 0) +++ trunk/OpenMPT/soundlib/Snd_defs.h 2009-09-01 18:50:33 UTC (rev 351) @@ -0,0 +1,367 @@ +/* + * OpenMPT + * + * Snd_defs.h + * + * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs +*/ + +#ifndef SND_DEF_H +#define SND_DEF_H + +#ifndef LPCBYTE +typedef const BYTE * LPCBYTE; +#endif + +typedef uint32 ROWINDEX; + const ROWINDEX ROWINDEX_MAX = uint32_max; +typedef uint16 CHANNELINDEX; + const CHANNELINDEX CHANNELINDEX_MAX = uint16_max; + const CHANNELINDEX CHANNELINDEX_INVALID = CHANNELINDEX_MAX; +typedef uint16 ORDERINDEX; + const ORDERINDEX ORDERINDEX_MAX = uint16_max; + const ORDERINDEX ORDERINDEX_INVALID = ORDERINDEX_MAX; +typedef uint16 PATTERNINDEX; + const PATTERNINDEX PATTERNINDEX_MAX = uint16_max; + const PATTERNINDEX PATTERNINDEX_INVALID = PATTERNINDEX_MAX; +typedef uint8 PLUGINDEX; +typedef uint16 TEMPO; +typedef uint16 SAMPLEINDEX; + const SAMPLEINDEX SAMPLEINDEX_MAX = uint16_max; + const SAMPLEINDEX SAMPLEINDEX_INVALID = SAMPLEINDEX_MAX; +typedef uint16 INSTRUMENTINDEX; + const SAMPLEINDEX INSTRUMENTINDEX_MAX = uint16_max; + const SAMPLEINDEX INSTRUMENTINDEX_INVALID = INSTRUMENTINDEX_MAX; +typedef uint8 SEQUENCEINDEX; + const SEQUENCEINDEX SEQUENCEINDEX_MAX = uint8_max; + const SEQUENCEINDEX SEQUENCEINDEX_INVALID = SEQUENCEINDEX_MAX; +typedef uint32 MODTYPE; + +#define MAX_PATTERN_ROWS 1024 // -> CODE#0008 -> DESC="#define to set pattern size" -! BEHAVIOUR_CHANGE#0008 + + +#define MOD_AMIGAC2 0x1AB +// -> CODE#0006 +// -> DESC="misc quantity changes" +#define MAX_SAMPLE_LENGTH 0x10000000 // 0x04000000 (64MB -> now 256MB). + // Note: Sample size in bytes can be more than 256 MB. +// -! BEHAVIOUR_CHANGE#0006 +#define MAX_SAMPLE_RATE 100000 +#define MAX_ORDERS 256 +const SEQUENCEINDEX MAX_SEQUENCES = 10; +#define MAX_PATTERNS 240 +#define MAX_SAMPLES 4000 + +#define MAX_INSTRUMENTS 256 //200 // -> CODE#0006 -> DESC="misc quantity changes" // -! BEHAVIOUR_CHANGE#0006 +//#ifdef FASTSOUNDLIB +//#define MAX_CHANNELS 80 +//#else +// -> CODE#0006 +// -> DESC="misc quantity changes" +#define MAX_CHANNELS 256 //200 // Note: This is the maximum number of sound channels, + // see MAX_BASECHANNELS for max pattern channels. +// -! BEHAVIOUR_CHANGE#0006 +//#endif +// -> CODE#0006 +// -> DESC="misc quantity changes" +//#ifdef FASTSOUNDLIB +//#define MAX_BASECHANNELS 64 +//#else +#define MAX_BASECHANNELS 127 // Max pattern channels. +//#endif +// -! BEHAVIOUR_CHANGE#0006 +#define MAX_ENVPOINTS 32 +#define MIN_PERIOD 0x0020 +#define MAX_PERIOD 0xFFFF +#define MAX_PATTERNNAME 32 +#define MAX_CHANNELNAME 20 +#define MAX_INFONAME 80 +#define MAX_EQ_BANDS 6 + +#define MAX_MIXPLUGINS 100 //50 // -> CODE#0006 -> DESC="misc quantity changes" -! BEHAVIOUR_CHANGE#0006 +#define MAX_PLUGPRESETS 1000 //rewbs.plugPresets + +#define MOD_TYPE_NONE 0x00 +#define MOD_TYPE_MOD 0x01 +#define MOD_TYPE_S3M 0x02 +#define MOD_TYPE_XM 0x04 +#define MOD_TYPE_MED 0x08 +#define MOD_TYPE_MTM 0x10 +#define MOD_TYPE_IT 0x20 +#define MOD_TYPE_669 0x40 +#define MOD_TYPE_ULT 0x80 +#define MOD_TYPE_STM 0x100 +#define MOD_TYPE_FAR 0x200 +#define MOD_TYPE_WAV 0x400 +#define MOD_TYPE_AMF 0x800 +#define MOD_TYPE_AMS 0x1000 +#define MOD_TYPE_DSM 0x2000 +#define MOD_TYPE_MDL 0x4000 +#define MOD_TYPE_OKT 0x8000 +#define MOD_TYPE_MID 0x10000 +#define MOD_TYPE_DMF 0x20000 +#define MOD_TYPE_PTM 0x40000 +#define MOD_TYPE_DBM 0x80000 +#define MOD_TYPE_MT2 0x100000 +#define MOD_TYPE_AMF0 0x200000 +#define MOD_TYPE_PSM 0x400000 +#define MOD_TYPE_J2B 0x800000 +#define MOD_TYPE_MPT 0x1000000 +#define MOD_TYPE_UMX 0x80000000 // Fake type +#define MAX_MODTYPE 24 + +// For compatibility mode +#define TRK_IMPULSETRACKER MOD_TYPE_IT | MOD_TYPE_MPT +#define TRK_FASTTRACKER2 MOD_TYPE_XM +#define TRK_SCREAMTRACKER MOD_TYPE_S3M +#define TRK_PROTRACKER MOD_TYPE_MOD +#define TRK_ALLTRACKERS TRK_IMPULSETRACKER | TRK_FASTTRACKER2 | TRK_SCREAMTRACKER | TRK_PROTRACKER + + + +// Channel flags: +// Bits 0-7: Sample Flags +#define CHN_16BIT 0x01 +#define CHN_LOOP 0x02 +#define CHN_PINGPONGLOOP 0x04 +#define CHN_SUSTAINLOOP 0x08 +#define CHN_PINGPONGSUSTAIN 0x10 +#define CHN_PANNING 0x20 +#define CHN_STEREO 0x40 +#define CHN_PINGPONGFLAG 0x80 //When flag is on, bidiloop is processed backwards? +// Bits 8-31: Channel Flags +#define CHN_MUTE 0x100 +#define CHN_KEYOFF 0x200 +#define CHN_NOTEFADE 0x400 +#define CHN_SURROUND 0x800 +#define CHN_NOIDO 0x1000 +#define CHN_HQSRC 0x2000 +#define CHN_FILTER 0x4000 +#define CHN_VOLUMERAMP 0x8000 +#define CHN_VIBRATO 0x10000 +#define CHN_TREMOLO 0x20000 +#define CHN_PANBRELLO 0x40000 +#define CHN_PORTAMENTO 0x80000 +#define CHN_GLISSANDO 0x100000 +#define CHN_VOLENV 0x200000 +#define CHN_PANENV 0x400000 +#define CHN_PITCHENV 0x800000 +#define CHN_FASTVOLRAMP 0x1000000 +#define CHN_EXTRALOUD 0x2000000 +#define CHN_REVERB 0x4000000 +#define CHN_NOREVERB 0x8000000 +#define CHN_SOLO 0x10000000 // -> CODE#0012 -> DESC="midi keyboard split" -! NEW_FEATURE#0012 +#define CHN_NOFX 0x20000000 // -> CODE#0015 -> DESC="channels management dlg" -! NEW_FEATURE#0015 +#define CHN_SYNCMUTE 0x40000000 + +#define ENV_VOLUME 0x0001 +#define ENV_VOLSUSTAIN 0x0002 +#define ENV_VOLLOOP 0x0004 +#define ENV_PANNING 0x0008 +#define ENV_PANSUSTAIN 0x0010 +#define ENV_PANLOOP 0x0020 +#define ENV_PITCH 0x0040 +#define ENV_PITCHSUSTAIN 0x0080 +#define ENV_PITCHLOOP 0x0100 +#define ENV_SETPANNING 0x0200 +#define ENV_FILTER 0x0400 +#define ENV_VOLCARRY 0x0800 +#define ENV_PANCARRY 0x1000 +#define ENV_PITCHCARRY 0x2000 +#define ENV_MUTE 0x4000 + + +// Filter Modes +#define FLTMODE_UNCHANGED 0xFF +#define FLTMODE_LOWPASS 0 +#define FLTMODE_HIGHPASS 1 +#define FLTMODE_BANDPASS 2 + + +#define RSF_16BIT 0x04 +#define RSF_STEREO 0x08 + +#define RS_PCM8S 0 // 8-bit signed +#define RS_PCM8U 1 // 8-bit unsigned +#define RS_PCM8D 2 // 8-bit delta values +#define RS_ADPCM4 3 // 4-bit ADPCM-packed +#define RS_PCM16D 4 // 16-bit delta values +#define RS_PCM16S 5 // 16-bit signed +#define RS_PCM16U 6 // 16-bit unsigned +#define RS_PCM16M 7 // 16-bit motorola order +#define RS_STPCM8S (RS_PCM8S|RSF_STEREO) // stereo 8-bit signed +#define RS_STPCM8U (RS_PCM8U|RSF_STEREO) // stereo 8-bit unsigned +#define RS_STPCM8D (RS_PCM8D|RSF_STEREO) // stereo 8-bit delta values +#define RS_STPCM16S (RS_PCM16S|RSF_STEREO) // stereo 16-bit signed +#define RS_STPCM16U (RS_PCM16U|RSF_STEREO) // stereo 16-bit unsigned +#define RS_STPCM16D (RS_PCM16D|RSF_STEREO) // stereo 16-bit delta values +#define RS_STPCM16M (RS_PCM16M|RSF_STEREO) // stereo 16-bit signed big endian +// IT 2.14 compressed samples +#define RS_IT2148 0x10 +#define RS_IT21416 0x14 +#define RS_IT2158 0x12 +#define RS_IT21516 0x16 +// AMS Packed Samples +#define RS_AMS8 0x11 +#define RS_AMS16 0x15 +// DMF Huffman compression +#define RS_DMF8 0x13 +#define RS_DMF16 0x17 +// MDL Huffman compression +#define RS_MDL8 0x20 +#define RS_MDL16 0x24 +#define RS_PTM8DTO16 0x25 +// Stereo Interleaved Samples +#define RS_STIPCM8S (RS_PCM8S|0x40|RSF_STEREO) // stereo 8-bit signed +#define RS_STIPCM8U (RS_PCM8U|0x40|RSF_STEREO) // stereo 8-bit unsigned +#define RS_STIPCM16S (RS_PCM16S|0x40|RSF_STEREO) // stereo 16-bit signed +#define RS_STIPCM16U (RS_PCM16U|0x40|RSF_STEREO) // stereo 16-bit unsigned +#define RS_STIPCM16M (RS_PCM16M|0x40|RSF_STEREO) // stereo 16-bit signed big endian +// 24-bit signed +#define RS_PCM24S (RS_PCM16S|0x80) // mono 24-bit signed +#define RS_STIPCM24S (RS_PCM16S|0x80|RSF_STEREO) // stereo 24-bit signed +// 32-bit +#define RS_PCM32S (RS_PCM16S|0xC0) // mono 32-bit signed +#define RS_STIPCM32S (RS_PCM16S|0xC0|RSF_STEREO) // stereo 32-bit signed + + + +// NNA types (New Note Action) +#define NNA_NOTECUT 0 +#define NNA_CONTINUE 1 +#define NNA_NOTEOFF 2 +#define NNA_NOTEFADE 3 + +// DCT types (Duplicate Check Types) +#define DCT_NONE 0 +#define DCT_NOTE 1 +#define DCT_SAMPLE 2 +#define DCT_INSTRUMENT 3 +#define DCT_PLUGIN 4 //rewbs.VSTiNNA + +// DNA types (Duplicate Note Action) +#define DNA_NOTECUT 0 +#define DNA_NOTEOFF 1 +#define DNA_NOTEFADE 2 + +// Mixer Hardware-Dependent features +#define SYSMIX_ENABLEMMX 0x01 +#define SYSMIX_SLOWCPU 0x02 +#define SYSMIX_FASTCPU 0x04 +#define SYSMIX_MMXEX 0x08 +#define SYSMIX_3DNOW 0x10 +#define SYSMIX_SSE 0x20 + +// Module flags +#define SONG_EMBEDMIDICFG 0x0001 +#define SONG_FASTVOLSLIDES 0x0002 +#define SONG_ITOLDEFFECTS 0x0004 +#define SONG_ITCOMPATMODE 0x0008 +#define SONG_LINEARSLIDES 0x0010 +#define SONG_PATTERNLOOP 0x0020 +#define SONG_STEP 0x0040 +#define SONG_PAUSED 0x0080 +#define SONG_FADINGSONG 0x0100 +#define SONG_ENDREACHED 0x0200 +#define SONG_GLOBALFADE 0x0400 +#define SONG_CPUVERYHIGH 0x0800 +#define SONG_FIRSTTICK 0x1000 +#define SONG_MPTFILTERMODE 0x2000 +#define SONG_SURROUNDPAN 0x4000 +#define SONG_EXFILTERRANGE 0x8000 +#define SONG_AMIGALIMITS 0x10000 +// -> CODE#0023 +// -> DESC="IT project files (.itp)" +#define SONG_ITPROJECT 0x20000 +#define SONG_ITPEMBEDIH 0x40000 +// -! NEW_FEATURE#0023 +#define SONG_BREAKTOROW 0x80000 +#define SONG_POSJUMP 0x100000 + +// Global Options (Renderer) +#define SNDMIX_REVERSESTEREO 0x0001 +#define SNDMIX_NOISEREDUCTION 0x0002 +#define SNDMIX_AGC 0x0004 +#define SNDMIX_NORESAMPLING 0x0008 +// SNDMIX_NOLINEARSRCMODE is the default +//#define SNDMIX_HQRESAMPLER 0x0010 //rewbs.resamplerConf: renamed SNDMIX_HQRESAMPLER to SNDMIX_SPLINESRCMODE +#define SNDMIX_SPLINESRCMODE 0x0010 +#define SNDMIX_MEGABASS 0x0020 +#define SNDMIX_SURROUND 0x0040 +#define SNDMIX_REVERB 0x0080 +#define SNDMIX_EQ 0x0100 +#define SNDMIX_SOFTPANNING 0x0200 +//#define SNDMIX_ULTRAHQSRCMODE 0x0400 //rewbs.resamplerConf: renamed SNDMIX_ULTRAHQSRCMODE to SNDMIX_POLYPHASESRCMODE +#define SNDMIX_POLYPHASESRCMODE 0x0400 +#define SNDMIX_FIRFILTERSRCMODE 0x0800 //rewbs: added SNDMIX_FIRFILTERSRCMODE + +//rewbs.resamplerConf: for stuff that applies to cubic spline, polyphase and FIR +#define SNDMIX_HQRESAMPLER (SNDMIX_SPLINESRCMODE|SNDMIX_POLYPHASESRCMODE|SNDMIX_FIRFILTERSRCMODE) + +////rewbs.resamplerConf: for stuff that applies to polyphase and FIR +#define SNDMIX_ULTRAHQSRCMODE (SNDMIX_POLYPHASESRCMODE|SNDMIX_FIRFILTERSRCMODE) + +// Misc Flags (can safely be turned on or off) +#define SNDMIX_DIRECTTODISK 0x10000 +#define SNDMIX_ENABLEMMX 0x20000 +#define SNDMIX_NOBACKWARDJUMPS 0x40000 +#define SNDMIX_MAXDEFAULTPAN 0x80000 // Used by the MOD loader +#define SNDMIX_MUTECHNMODE 0x100000 // Notes are not played on muted channels +#define SNDMIX_EMULATE_MIX_BUGS 0x200000 // rewbs.emulateMixBugs + +#define MAX_GLOBAL_VOLUME 256 + +// Resampling modes +enum { + SRCMODE_NEAREST, + SRCMODE_LINEAR, + SRCMODE_SPLINE, + SRCMODE_POLYPHASE, + SRCMODE_FIRFILTER, //rewbs.resamplerConf + SRCMODE_DEFAULT, + NUM_SRC_MODES +}; + +enum { + ENV_RESET_ALL, + ENV_RESET_VOL, + ENV_RESET_PAN, + ENV_RESET_PITCH, + ENV_RELEASE_NODE_UNSET=0xFF, + NOT_YET_RELEASED=-1 +}; + +enum { + CHANNEL_ONLY = 0, + INSTRUMENT_ONLY = 1, + PRIORITISE_INSTRUMENT = 2, + PRIORITISE_CHANNEL = 3, + EVEN_IF_MUTED = false, + RESPECT_MUTES = true, +}; + +//Plugin velocity handling options +enum PLUGVELOCITYHANDLING +{ + PLUGIN_VELOCITYHANDLING_CHANNEL = 0, + PLUGIN_VELOCITYHANDLING_VOLUME +}; + +//Plugin volumecommand handling options +enum PLUGVOLUMEHANDLING +{ + PLUGIN_VOLUMEHANDLING_MIDI = 0, + PLUGIN_VOLUMEHANDLING_DRYWET, + PLUGIN_VOLUMEHANDLING_IGNORE, +}; + +// filtermodes +/*enum { + INST_FILTERMODE_DEFAULT=0, + INST_FILTERMODE_HIGHPASS, + INST_FILTERMODE_LOWPASS, + INST_NUMFILTERMODES +};*/ + +#endif Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-08-30 22:27:15 UTC (rev 350) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-09-01 18:50:33 UTC (rev 351) @@ -7,364 +7,21 @@ * OpenMPT devs */ +#ifndef __SNDFILE_H +#define __SNDFILE_H + #include "../mptrack/SoundFilePlayConfig.h" #include "../mptrack/misc_util.h" #include "mod_specifications.h" #include <vector> #include <bitset> #include "midi.h" +#include "Snd_defs.h" class CTuningBase; typedef CTuningBase CTuning; -using std::bitset; -#ifndef __SNDFILE_H -#define __SNDFILE_H - -#ifndef LPCBYTE -typedef const BYTE * LPCBYTE; -#endif - -// -> CODE#0008 -// -> DESC="#define to set pattern size" -#define MAX_PATTERN_ROWS 1024 -// -! BEHAVIOUR_CHANGE#0008 - -#define MOD_AMIGAC2 0x1AB -// -> CODE#0006 -// -> DESC="misc quantity changes" -#define MAX_SAMPLE_LENGTH 0x10000000 // 0x04000000 (64MB -> now 256MB). - // Note: Sample size in bytes can be more than 256 MB. -// -! BEHAVIOUR_CHANGE#0006 -#define MAX_SAMPLE_RATE 100000 -#define MAX_ORDERS 256 -#define MAX_PATTERNS 240 -#define MAX_SAMPLES 4000 -// -> CODE#0006 -// -> DESC="misc quantity changes" -#define MAX_INSTRUMENTS 256 //200 -// -! BEHAVIOUR_CHANGE#0006 -//#ifdef FASTSOUNDLIB -//#define MAX_CHANNELS 80 -//#else -// -> CODE#0006 -// -> DESC="misc quantity changes" -#define MAX_CHANNELS 256 //200 //Note: This is the maximum number of sound channels, - // see MAX_BASECHANNELS for max pattern channels. -// -! BEHAVIOUR_CHANGE#0006 -//#endif -// -> CODE#0006 -// -> DESC="misc quantity changes" -//#ifdef FASTSOUNDLIB -//#define MAX_BASECHANNELS 64 -//#else -#define MAX_BASECHANNELS 127 //Max pattern channels. -//#endif -// -! BEHAVIOUR_CHANGE#0006 -#define MAX_ENVPOINTS 32 -#define MIN_PERIOD 0x0020 -#define MAX_PERIOD 0xFFFF -#define MAX_PATTERNNAME 32 -#define MAX_CHANNELNAME 20 -#define MAX_INFONAME 80 -#define MAX_EQ_BANDS 6 -// -> CODE#0006 -// -> DESC="misc quantity changes" -#define MAX_MIXPLUGINS 100 //50 -// -! BEHAVIOUR_CHANGE#0006 -#define MAX_PLUGPRESETS 1000 //rewbs.plugPresets - -#define MOD_TYPE_NONE 0x00 -#define MOD_TYPE_MOD 0x01 -#define MOD_TYPE_S3M 0x02 -#define MOD_TYPE_XM 0x04 -#define MOD_TYPE_MED 0x08 -#define MOD_TYPE_MTM 0x10 -#define MOD_TYPE_IT 0x20 -#define MOD_TYPE_669 0x40 -#define MOD_TYPE_ULT 0x80 -#define MOD_TYPE_STM 0x100 -#define MOD_TYPE_FAR 0x200 -#define MOD_TYPE_WAV 0x400 -#define MOD_TYPE_AMF 0x800 -#define MOD_TYPE_AMS 0x1000 -#define MOD_TYPE_DSM 0x2000 -#define MOD_TYPE_MDL 0x4000 -#define MOD_TYPE_OKT 0x8000 -#define MOD_TYPE_MID 0x10000 -#define MOD_TYPE_DMF 0x20000 -#define MOD_TYPE_PTM 0x40000 -#define MOD_TYPE_DBM 0x80000 -#define MOD_TYPE_MT2 0x100000 -#define MOD_TYPE_AMF0 0x200000 -#define MOD_TYPE_PSM 0x400000 -#define MOD_TYPE_J2B 0x800000 -#define MOD_TYPE_MPT 0x1000000 -#define MOD_TYPE_UMX 0x80000000 // Fake type -#define MAX_MODTYPE 24 - -// For compatibility mode -#define TRK_IMPULSETRACKER MOD_TYPE_IT | MOD_TYPE_MPT -#define TRK_FASTTRACKER2 MOD_TYPE_XM -#define TRK_SCREAMTRACKER MOD_TYPE_S3M -#define TRK_PROTRACKER MOD_TYPE_MOD -#define TRK_ALLTRACKERS TRK_IMPULSETRACKER | TRK_FASTTRACKER2 | TRK_SCREAMTRACKER | TRK_PROTRACKER - - - -// Channel flags: -// Bits 0-7: Sample Flags -#define CHN_16BIT 0x01 -#define CHN_LOOP 0x02 -#define CHN_PINGPONGLOOP 0x04 -#define CHN_SUSTAINLOOP 0x08 -#define CHN_PINGPONGSUSTAIN 0x10 -#define CHN_PANNING 0x20 -#define CHN_STEREO 0x40 -#define CHN_PINGPONGFLAG 0x80 //When flag is on, bidiloop is processed backwards? -// Bits 8-31: Channel Flags -#define CHN_MUTE 0x100 -#define CHN_KEYOFF 0x200 -#define CHN_NOTEFADE 0x400 -#define CHN_SURROUND 0x800 -#define CHN_NOIDO 0x1000 -#define CHN_HQSRC 0x2000 -#define CHN_FILTER 0x4000 -#define CHN_VOLUMERAMP 0x8000 -#define CHN_VIBRATO 0x10000 -#define CHN_TREMOLO 0x20000 -#define CHN_PANBRELLO 0x40000 -#define CHN_PORTAMENTO 0x80000 -#define CHN_GLISSANDO 0x100000 -#define CHN_VOLENV 0x200000 -#define CHN_PANENV 0x400000 -#define CHN_PITCHENV 0x800000 -#define CHN_FASTVOLRAMP 0x1000000 -#define CHN_EXTRALOUD 0x2000000 -#define CHN_REVERB 0x4000000 -#define CHN_NOREVERB 0x8000000 -// -> CODE#0012 -// -> DESC="midi keyboard split" -#define CHN_SOLO 0x10000000 -// -! NEW_FEATURE#0012 - -// -> CODE#0015 -// -> DESC="channels management dlg" -#define CHN_NOFX 0x20000000 -// -! NEW_FEATURE#0015 - -#define CHN_SYNCMUTE 0x40000000 - -#define ENV_VOLUME 0x0001 -#define ENV_VOLSUSTAIN 0x0002 -#define ENV_VOLLOOP 0x0004 -#define ENV_PANNING 0x0008 -#define ENV_PANSUSTAIN 0x0010 -#define ENV_PANLOOP 0x0020 -#define ENV_PITCH 0x0040 -#define ENV_PITCHSUSTAIN 0x0080 -#define ENV_PITCHLOOP 0x0100 -#define ENV_SETPANNING 0x0200 -#define ENV_FILTER 0x0400 -#define ENV_VOLCARRY 0x0800 -#define ENV_PANCARRY 0x1000 -#define ENV_PITCHCARRY 0x2000 -#define ENV_MUTE 0x4000 - - -// Filter Modes -#define FLTMODE_UNCHANGED 0xFF -#define FLTMODE_LOWPASS 0 -#define FLTMODE_HIGHPASS 1 -#define FLTMODE_BANDPASS 2 - - -#define RSF_16BIT 0x04 -#define RSF_STEREO 0x08 - -#define RS_PCM8S 0 // 8-bit signed -#define RS_PCM8U 1 // 8-bit unsigned -#define RS_PCM8D 2 // 8-bit delta values -#define RS_ADPCM4 3 // 4-bit ADPCM-packed -#define RS_PCM16D 4 // 16-bit delta values -#define RS_PCM16S 5 // 16-bit signed -#define RS_PCM16U 6 // 16-bit unsigned -#define RS_PCM16M 7 // 16-bit motorola order -#define RS_STPCM8S (RS_PCM8S|RSF_STEREO) // stereo 8-bit signed -#define RS_STPCM8U (RS_PCM8U|RSF_STEREO) // stereo 8-bit unsigned -#define RS_STPCM8D (RS_PCM8D|RSF_STEREO) // stereo 8-bit delta values -#define RS_STPCM16S (RS_PCM16S|RSF_STEREO) // stereo 16-bit signed -#define RS_STPCM16U (RS_PCM16U|RSF_STEREO) // stereo 16-bit unsigned -#define RS_STPCM16D (RS_PCM16D|RSF_STEREO) // stereo 16-bit delta values -#define RS_STPCM16M (RS_PCM16M|RSF_STEREO) // stereo 16-bit signed big endian -// IT 2.14 compressed samples -#define RS_IT2148 0x10 -#define RS_IT21416 0x14 -#define RS_IT2158 0x12 -#define RS_IT21516 0x16 -// AMS Packed Samples -#define RS_AMS8 0x11 -#define RS_AMS16 0x15 -// DMF Huffman compression -#define RS_DMF8 0x13 -#define RS_DMF16 0x17 -// MDL Huffman compression -#define RS_MDL8 0x20 -#define RS_MDL16 0x24 -#define RS_PTM8DTO16 0x25 -// Stereo Interleaved Samples -#define RS_STIPCM8S (RS_PCM8S|0x40|RSF_STEREO) // stereo 8-bit signed -#define RS_STIPCM8U (RS_PCM8U|0x40|RSF_STEREO) // stereo 8-bit unsigned -#define RS_STIPCM16S (RS_PCM16S|0x40|RSF_STEREO) // stereo 16-bit signed -#define RS_STIPCM16U (RS_PCM16U|0x40|RSF_STEREO) // stereo 16-bit unsigned -#define RS_STIPCM16M (RS_PCM16M|0x40|RSF_STEREO) // stereo 16-bit signed big endian -// 24-bit signed -#define RS_PCM24S (RS_PCM16S|0x80) // mono 24-bit signed -#define RS_STIPCM24S (RS_PCM16S|0x80|RSF_STEREO) // stereo 24-bit signed -// 32-bit -#define RS_PCM32S (RS_PCM16S|0xC0) // mono 32-bit signed -#define RS_STIPCM32S (RS_PCM16S|0xC0|RSF_STEREO) // stereo 32-bit signed - - - -// NNA types (New Note Action) -#define NNA_NOTECUT 0 -#define NNA_CONTINUE 1 -#define NNA_NOTEOFF 2 -#define NNA_NOTEFADE 3 - -// DCT types (Duplicate Check Types) -#define DCT_NONE 0 -#define DCT_NOTE 1 -#define DCT_SAMPLE 2 -#define DCT_INSTRUMENT 3 -#define DCT_PLUGIN 4 //rewbs.VSTiNNA - -// DNA types (Duplicate Note Action) -#define DNA_NOTECUT 0 -#define DNA_NOTEOFF 1 -#define DNA_NOTEFADE 2 - -// Mixer Hardware-Dependent features -#define SYSMIX_ENABLEMMX 0x01 -#define SYSMIX_SLOWCPU 0x02 -#define SYSMIX_FASTCPU 0x04 -#define SYSMIX_MMXEX 0x08 -#define SYSMIX_3DNOW 0x10 -#define SYSMIX_SSE 0x20 - -// Module flags -#define SONG_EMBEDMIDICFG 0x0001 -#define SONG_FASTVOLSLIDES 0x0002 -#define SONG_ITOLDEFFECTS 0x0004 -#define SONG_ITCOMPATMODE 0x0008 -#define SONG_LINEARSLIDES 0x0010 -#define SONG_PATTERNLOOP 0x0020 -#define SONG_STEP 0x0040 -#define SONG_PAUSED 0x0080 -#define SONG_FADINGSONG 0x0100 -#define SONG_ENDREACHED 0x0200 -#define SONG_GLOBALFADE 0x0400 -#define SONG_CPUVERYHIGH 0x0800 -#define SONG_FIRSTTICK 0x1000 -#define SONG_MPTFILTERMODE 0x2000 -#define SONG_SURROUNDPAN 0x4000 -#define SONG_EXFILTERRANGE 0x8000 -#define SONG_AMIGALIMITS 0x10000 -// -> CODE#0023 -// -> DESC="IT project files (.itp)" -#define SONG_ITPROJECT 0x20000 -#define SONG_ITPEMBEDIH 0x40000 -// -! NEW_FEATURE#0023 -#define SONG_BREAKTOROW 0x80000 -#define SONG_POSJUMP 0x100000 - -// Global Options (Renderer) -#define SNDMIX_REVERSESTEREO 0x0001 -#define SNDMIX_NOISEREDUCTION 0x0002 -#define SNDMIX_AGC 0x0004 -#define SNDMIX_NORESAMPLING 0x0008 -// SNDMIX_NOLINEARSRCMODE is the default -//#define SNDMIX_HQRESAMPLER 0x0010 //rewbs.resamplerConf: renamed SNDMIX_HQRESAMPLER to SNDMIX_SPLINESRCMODE -#define SNDMIX_SPLINESRCMODE 0x0010 -#define SNDMIX_MEGABASS 0x0020 -#define SNDMIX_SURROUND 0x0040 -#define SNDMIX_REVERB 0x0080 -#define SNDMIX_EQ 0x0100 -#define SNDMIX_SOFTPANNING 0x0200 -//#define SNDMIX_ULTRAHQSRCMODE 0x0400 //rewbs.resamplerConf: renamed SNDMIX_ULTRAHQSRCMODE to SNDMIX_POLYPHASESRCMODE -#define SNDMIX_POLYPHASESRCMODE 0x0400 -#define SNDMIX_FIRFILTERSRCMODE 0x0800 //rewbs: added SNDMIX_FIRFILTERSRCMODE - -//rewbs.resamplerConf: for stuff that applies to cubic spline, polyphase and FIR -#define SNDMIX_HQRESAMPLER (SNDMIX_SPLINESRCMODE|SNDMIX_POLYPHASESRCMODE|SNDMIX_FIRFILTERSRCMODE) - -////rewbs.resamplerConf: for stuff that applies to polyphase and FIR -#define SNDMIX_ULTRAHQSRCMODE (SNDMIX_POLYPHASESRCMODE|SNDMIX_FIRFILTERSRCMODE) - -// Misc Flags (can safely be turned on or off) -#define SNDMIX_DIRECTTODISK 0x10000 -#define SNDMIX_ENABLEMMX 0x20000 -#define SNDMIX_NOBACKWARDJUMPS 0x40000 -#define SNDMIX_MAXDEFAULTPAN 0x80000 // Used by the MOD loader -#define SNDMIX_MUTECHNMODE 0x100000 // Notes are not played on muted channels -#define SNDMIX_EMULATE_MIX_BUGS 0x200000 // rewbs.emulateMixBugs - -#define MAX_GLOBAL_VOLUME 256 - -// Resampling modes -enum { - SRCMODE_NEAREST, - SRCMODE_LINEAR, - SRCMODE_SPLINE, - SRCMODE_POLYPHASE, - SRCMODE_FIRFILTER, //rewbs.resamplerConf - SRCMODE_DEFAULT, - NUM_SRC_MODES -}; - -enum { - ENV_RESET_ALL, - ENV_RESET_VOL, - ENV_RESET_PAN, - ENV_RESET_PITCH, - ENV_RELEASE_NODE_UNSET=0xFF, - NOT_YET_RELEASED=-1 -}; - -enum { - CHANNEL_ONLY = 0, - INSTRUMENT_ONLY = 1, - PRIORITISE_INSTRUMENT = 2, - PRIORITISE_CHANNEL = 3, - EVEN_IF_MUTED = false, - RESPECT_MUTES = true, -}; - -//Plugin velocity handling options -enum PLUGVELOCITYHANDLING -{ - PLUGIN_VELOCITYHANDLING_CHANNEL = 0, - PLUGIN_VELOCITYHANDLING_VOLUME -}; - -//Plugin volumecommand handling options -enum PLUGVOLUMEHANDLING -{ - PLUGIN_VOLUMEHANDLING_MIDI = 0, - PLUGIN_VOLUMEHANDLING_DRYWET, - PLUGIN_VOLUMEHANDLING_IGNORE, -}; - -// filtermodes -/*enum { - INST_FILTERMODE_DEFAULT=0, - INST_FILTERMODE_HIGHPASS, - INST_FILTERMODE_LOWPASS, - INST_NUMFILTERMODES -};*/ - // Sample Struct struct MODSAMPLE { @@ -774,12 +431,11 @@ #include "pattern.h" #include "patternContainer.h" -#include "ordertopatterntable.h" +#include "ModSequence.h" +#include "PlaybackEventer.h" -#include "playbackEventer.h" - class CSoundFile; //====================== @@ -1022,10 +678,7 @@ bool ReadSTM(LPCBYTE lpStream, DWORD dwMemLength); bool ReadIT(LPCBYTE lpStream, const DWORD dwMemLength); //bool ReadMPT(LPCBYTE lpStream, const DWORD dwMemLength); -// -> CODE#0023 -// -> DESC="IT project files (.itp)" - bool ReadITProject(LPCBYTE lpStream, const DWORD dwMemLength); -// -! NEW_FEATURE#0023 + bool ReadITProject(LPCBYTE lpStream, const DWORD dwMemLength); // -> CODE#0023 -> DESC="IT project files (.itp)" -! NEW_FEATURE#0023 bool Read669(LPCBYTE lpStream, DWORD dwMemLength); bool ReadUlt(LPCBYTE lpStream, DWORD dwMemLength); bool ReadWav(LPCBYTE lpStream, DWORD dwMemLength); @@ -1055,10 +708,7 @@ bool SaveMod(LPCSTR lpszFileName, UINT nPacking=0, const bool bCompatibilityExport = false); bool SaveIT(LPCSTR lpszFileName, UINT nPacking=0); bool SaveCompatIT(LPCSTR lpszFileName); -// -> CODE#0023 -// -> DESC="IT project files (.itp)" - bool SaveITProject(LPCSTR lpszFileName); -// -! NEW_FEATURE#0023 + bool SaveITProject(LPCSTR lpszFileName); // -> CODE#0023 -> DESC="IT project files (.itp)" -! NEW_FEATURE#0023 UINT SaveMixPlugins(FILE *f=NULL, BOOL bUpdate=TRUE); void WriteInstrumentPropertyForAllInstruments(__int32 code, __int16 size, FILE* f, MODINSTRUMENT* instruments[], UINT nInstruments); void SaveExtendedInstrumentProperties(MODINSTRUMENT *instruments[], UINT nInstruments, FILE* f); Modified: trunk/OpenMPT/soundlib/mod_specifications.h =================================================================== --- trunk/OpenMPT/soundlib/mod_specifications.h 2009-08-30 22:27:15 UTC (rev 350) +++ trunk/OpenMPT/soundlib/mod_specifications.h 2009-09-01 18:50:33 UTC (rev 351) @@ -1,6 +1,7 @@ #ifndef MOD_SPECIFICATIONS_H #define MOD_SPECIFICATIONS_H +#include "Snd_defs.h" #include "modcommand.h" // #include "../mptrack/SoundFilePlayConfig.h" // mixlevel constants. Modified: trunk/OpenMPT/soundlib/pattern.h =================================================================== --- trunk/OpenMPT/soundlib/pattern.h 2009-08-30 22:27:15 UTC (rev 350) +++ trunk/OpenMPT/soundlib/pattern.h 2009-09-01 18:50:33 UTC (rev 351) @@ -3,6 +3,7 @@ #include <vector> #include "modcommand.h" +#include "Snd_defs.h" using std::vector; Modified: trunk/OpenMPT/soundlib/patternContainer.h =================================================================== --- trunk/OpenMPT/soundlib/patternContainer.h 2009-08-30 22:27:15 UTC (rev 350) +++ trunk/OpenMPT/soundlib/patternContainer.h 2009-09-01 18:50:33 UTC (rev 351) @@ -2,6 +2,7 @@ #define PATTERNCONTAINER_H #include "pattern.h" +#include "Snd_defs.h" class CSoundFile; typedef CPattern MODPATTERN; @@ -25,7 +26,7 @@ //BEGIN: INTERFACE METHODS public: - CPatternContainer(CSoundFile& sndFile) : m_rSndFile(sndFile) {m_Patterns.assign(240, MODPATTERN(*this));} + CPatternContainer(CSoundFile& sndFile) : m_rSndFile(sndFile) {m_Patterns.assign(MAX_PATTERNS, MODPATTERN(*this));} // Clears existing patterns and resizes array to default size. void Init(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-09-01 22:08:51
|
Revision: 352 http://modplug.svn.sourceforge.net/modplug/?rev=352&view=rev Author: saga-games Date: 2009-09-01 22:08:43 +0000 (Tue, 01 Sep 2009) Log Message: ----------- [Imp] S3M saver: Orderlist is now as small as possible (multiple of 2 instead of multiple of 16); Using ST3's default UltraClick value [Imp] PSM loader: "Cosmetic" changes (use default values of first subtune for default speed/tempo/panning/etc., don't touch patterns if only one subtune is present. Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/Load_s3m.cpp Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-01 18:50:33 UTC (rev 351) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-01 22:08:43 UTC (rev 352) @@ -2077,7 +2077,7 @@ #define MOD_TYPE_XMIT (MOD_TYPE_XM|MOD_TYPE_IT) #define MOD_TYPE_XMITMPT (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT) #define MOD_TYPE_ITMPT (MOD_TYPE_IT|MOD_TYPE_MPT) -#define MAX_FXINFO 66 //rewbs.smoothVST, increased from 64... I wonder what this will break? +#define MAX_FXINFO 68 //rewbs.smoothVST, increased from 64... I wonder what this will break? const MPTEFFECTINFO gFXInfo[MAX_FXINFO] = @@ -2153,8 +2153,10 @@ {CMD_S3MCMDEX, 0xF0,0x70, 0, MOD_TYPE_ITMPT, "Instr. control"}, // -> CODE#0010 // -> DESC="add extended parameter mechanism to pattern effects" - {CMD_XPARAM, 0x00,0x00, 0, MOD_TYPE_XMITMPT, "X param"} + {CMD_XPARAM, 0x00,0x00, 0, MOD_TYPE_XMITMPT, "X param"}, // -! NEW_FEATURE#0010 + {CMD_NOTESLIDEUP, 0x00,0x00, 0, 0, "Note Slide Up"}, // .IMF effect + {CMD_NOTESLIDEDOWN, 0x00,0x00, 0, 0, "Note Slide Down"}, // .IMF effect }; Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2009-09-01 18:50:33 UTC (rev 351) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2009-09-01 22:08:43 UTC (rev 352) @@ -1689,6 +1689,7 @@ "coda for sample drawing code|" "http://coda.s3m.us/|" "Storlek for all the IT compatibility hints and testcases|" + "as well as the IMF loader|" "http://schismtracker.org/|" "Pel K. Txnder for the scrolling credits control :)|" "http://tinyurl.com/4yze8|" Modified: trunk/OpenMPT/soundlib/Load_psm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-09-01 18:50:33 UTC (rev 351) +++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-09-01 22:08:43 UTC (rev 352) @@ -283,13 +283,13 @@ case 0x07: // Default Speed if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break; - m_nDefaultSpeed = subsong.defaultSpeed = lpStream[dwSettingsOffset + 1]; + subsong.defaultSpeed = lpStream[dwSettingsOffset + 1]; dwSettingsOffset += 2; break; case 0x08: // Default Tempo if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break; - m_nDefaultTempo = subsong.defaultTempo = lpStream[dwSettingsOffset + 1]; + subsong.defaultTempo = lpStream[dwSettingsOffset + 1]; dwSettingsOffset += 2; break; @@ -313,20 +313,17 @@ switch(lpStream[dwSettingsOffset + 3]) { case 0: // use panning - ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = lpStream[dwSettingsOffset + 2] ^ 128; - ChnSettings[nChn].dwFlags &= ~CHN_SURROUND; + subsong.channelPanning[nChn] = lpStream[dwSettingsOffset + 2] ^ 128; subsong.channelSurround[nChn] = false; break; case 2: // surround - ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128; - ChnSettings[nChn].dwFlags |= CHN_SURROUND; + subsong.channelPanning[nChn] = 128; subsong.channelSurround[nChn] = true; break; case 4: // center - ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128; - ChnSettings[nChn].dwFlags &= ~CHN_SURROUND; + subsong.channelPanning[nChn] = 128; subsong.channelSurround[nChn] = false; break; @@ -341,10 +338,10 @@ dwSettingsOffset += 4; break; - case 0x0E: // Channel volume table (0...255) + case 0x0E: // Channel volume table (0...255) - apparently always 255 if(dwSettingsOffset - dwChunkPos + 3 > subChunkSize) break; if(lpStream[dwSettingsOffset + 1] < MAX_BASECHANNELS) - ChnSettings[lpStream[dwSettingsOffset + 1]].nVolume = subsong.channelVolume[lpStream[dwSettingsOffset + 1]] = (lpStream[dwSettingsOffset + 2] >> 2) + 1; + subsong.channelVolume[lpStream[dwSettingsOffset + 1]] = (lpStream[dwSettingsOffset + 2] >> 2) + 1; dwSettingsOffset += 3; break; @@ -375,20 +372,17 @@ switch(lpStream[dwChunkPos + i]) { case 0: // use panning - ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = lpStream[dwChunkPos + i + 1] ^ 128; - ChnSettings[nChn].dwFlags &= ~CHN_SURROUND; + subsong.channelPanning[nChn] = lpStream[dwChunkPos + i + 1] ^ 128; subsong.channelSurround[nChn] = false; break; case 2: // surround - ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128; - ChnSettings[nChn].dwFlags |= CHN_SURROUND; + subsong.channelPanning[nChn] = 128; subsong.channelSurround[nChn] = true; break; case 4: // center - ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128; - ChnSettings[nChn].dwFlags &= ~CHN_SURROUND; + subsong.channelPanning[nChn] = 128; subsong.channelSurround[nChn] = false; break; } @@ -478,9 +472,23 @@ dwMemPos += chunkSize; } - if(m_nChannels == 0) + if(m_nChannels == 0 || subsongs.size() == 0) return false; + // Make the default variables of the first subsong global + m_nDefaultSpeed = subsongs[0].defaultSpeed; + m_nDefaultTempo = subsongs[0].defaultTempo; + m_nRestartPos = subsongs[0].restartPos; + for(CHANNELINDEX nChn = 0; nChn < m_nChannels; nChn++) + { + ChnSettings[nChn].nVolume = subsongs[0].channelVolume[nChn]; + ChnSettings[nChn].nPan = subsongs[0].channelPanning[nChn]; + if(subsongs[0].channelSurround[nChn]) + ChnSettings[nChn].dwFlags |= CHN_SURROUND; + else + ChnSettings[nChn].dwFlags &= ~CHN_SURROUND; + } + // Now that we know the number of channels, we can go through all the patterns. // This is a bit stupid since we will even read duplicate patterns twice, but hey, we do this just once... so who cares? PATTERNINDEX nPat = 0; @@ -582,7 +590,7 @@ case 0x04: // volslide down command = CMD_VOLUMESLIDE; if (bNewFormat) param &= 0x0F; - else param = (param >> 1) & 0x0F; + else if(param < 2) param |= 0xF0; else param = (param >> 1) & 0x0F; break; // Portamento @@ -728,48 +736,51 @@ nPat++; } - // write subsong "configuration" to patterns - for(uint32 i = 0; i < subsongs.size(); i++) + if(subsongs.size() > 1) { - PATTERNINDEX startPattern = Order[subsongs[i].startOrder], endPattern = Order[subsongs[i].endOrder]; - if(startPattern == PATTERNINDEX_INVALID || endPattern == PATTERNINDEX_INVALID) continue; // what, invalid subtune? + // write subsong "configuration" to patterns (only if there are multiple subsongs) + for(uint32 i = 0; i < subsongs.size(); i++) + { + PATTERNINDEX startPattern = Order[subsongs[i].startOrder], endPattern = Order[subsongs[i].endOrder]; + if(startPattern == PATTERNINDEX_INVALID || endPattern == PATTERNINDEX_INVALID) continue; // what, invalid subtune? - // set the subsong name to all pattern names - for(PATTERNINDEX nPat = startPattern; nPat <= endPattern; nPat++) - { - SetPatternName(nPat, subsongs[i].songName); - } - - // subsongs with different panning setup -> write to pattern (MUSIC_C.PSM) - if(bSubsongPanningDiffers) - { - for(CHANNELINDEX nChn = 0; nChn < m_nChannels; nChn++) + // set the subsong name to all pattern names + for(PATTERNINDEX nPat = startPattern; nPat <= endPattern; nPat++) { - if(subsongs[i].channelSurround[nChn] == true) - TryWriteEffect(startPattern, 0, CMD_S3MCMDEX, 0x91, false, nChn, false, true); - else - TryWriteEffect(startPattern, 0, CMD_PANNING8, subsongs[i].channelPanning[nChn], false, nChn, false, true); + SetPatternName(nPat, subsongs[i].songName); } - } - // write default tempo/speed to pattern - TryWriteEffect(startPattern, 0, CMD_SPEED, subsongs[i].defaultSpeed, false, CHANNELINDEX_INVALID, false, true); - TryWriteEffect(startPattern, 0, CMD_TEMPO, subsongs[i].defaultTempo, false, CHANNELINDEX_INVALID, false, true); - // don't write channel volume for now, as it's always set to 100% anyway + // subsongs with different panning setup -> write to pattern (MUSIC_C.PSM) + if(bSubsongPanningDiffers) + { + for(CHANNELINDEX nChn = 0; nChn < m_nChannels; nChn++) + { + if(subsongs[i].channelSurround[nChn] == true) + TryWriteEffect(startPattern, 0, CMD_S3MCMDEX, 0x91, false, nChn, false, true); + else + TryWriteEffect(startPattern, 0, CMD_PANNING8, subsongs[i].channelPanning[nChn], false, nChn, false, true); + } + } + // write default tempo/speed to pattern + TryWriteEffect(startPattern, 0, CMD_SPEED, subsongs[i].defaultSpeed, false, CHANNELINDEX_INVALID, false, true); + TryWriteEffect(startPattern, 0, CMD_TEMPO, subsongs[i].defaultTempo, false, CHANNELINDEX_INVALID, false, true); - // there's a restart pos, so let's try to insert a Bxx command in the last pattern - if(subsongs[i].restartPos != ORDERINDEX_INVALID) - { - ROWINDEX lastRow = Patterns[endPattern].GetNumRows() - 1; - MODCOMMAND *row_data; - row_data = Patterns[endPattern]; - for(uint32 nCell = 0; nCell < m_nChannels * Patterns[endPattern].GetNumRows(); nCell++) + // don't write channel volume for now, as it's always set to 100% anyway + + // there's a restart pos, so let's try to insert a Bxx command in the last pattern + if(subsongs[i].restartPos != ORDERINDEX_INVALID) { - if(row_data->command == CMD_PATTERNBREAK || row_data->command == CMD_POSITIONJUMP) - lastRow = nCell / m_nChannels; - row_data++; + ROWINDEX lastRow = Patterns[endPattern].GetNumRows() - 1; + MODCOMMAND *row_data; + row_data = Patterns[endPattern]; + for(uint32 nCell = 0; nCell < m_nChannels * Patterns[endPattern].GetNumRows(); nCell++) + { + if(row_data->command == CMD_PATTERNBREAK || row_data->command == CMD_POSITIONJUMP) + lastRow = nCell / m_nChannels; + row_data++; + } + TryWriteEffect(endPattern, lastRow, CMD_POSITIONJUMP, (BYTE)subsongs[i].restartPos, false, CHANNELINDEX_INVALID, false, true); } - TryWriteEffect(endPattern, lastRow, CMD_POSITIONJUMP, (BYTE)subsongs[i].restartPos, false, CHANNELINDEX_INVALID, false, true); } } Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-09-01 18:50:33 UTC (rev 351) +++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-09-01 22:08:43 UTC (rev 352) @@ -527,7 +527,6 @@ nbo = 2; else if (nbo & 1) // number of orders must be even nbo++; - nbo = (nbo + 15) & 0xF0; // TODO why does it not work otherwise? nbo should be multiple of 2, not 16! if(nbo > 0xF0) nbo = 0xF0; // sequence too long header[0x20] = nbo & 0xFF; header[0x21] = nbo >> 8; @@ -560,7 +559,7 @@ header[0x31] = CLAMP(m_nDefaultSpeed, 1, 255); header[0x32] = CLAMP(m_nDefaultTempo, 32, 255); header[0x33] = CLAMP(m_nSamplePreAmp, 0x10, 0x7F) | 0x80; // Bit 8 = Stereo - header[0x34] = 0x10; // 16 Channels for UltraClick removal + header[0x34] = 0x08; // 8 Channels for UltraClick removal (default) header[0x35] = 0xFC; // Write pan positions for (i=0; i<32; i++) { @@ -571,7 +570,7 @@ } else header[0x40+i] = 0xFF; } fwrite(header, 0x60, 1, f); - Order.WriteAsByte(f, nbo); + nbo = Order.WriteAsByte(f, nbo); memset(patptr, 0, sizeof(patptr)); memset(insptr, 0, sizeof(insptr)); UINT ofs0 = 0x60 + nbo; @@ -595,6 +594,7 @@ { fwrite(S3MFiller, 0x10 - ((nbi*2+nbp*2) & 0x0F), 1, f); } + fseek(f, ofs1, SEEK_SET); ofs1 = ftell(f); fwrite(insex, nbi, 0x50, f); // Packing patterns This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-09-06 12:45:22
|
Revision: 353 http://modplug.svn.sourceforge.net/modplug/?rev=353&view=rev Author: saga-games Date: 2009-09-06 12:45:07 +0000 (Sun, 06 Sep 2009) Log Message: ----------- [Fix] Playback: Fixed a severe bug that caused a crash when trying to play a module that has an empty order list. (introduced in rev. 338) [Fix] IT Loader: The fix for old instrument header versions was wrong. [Fix] Note Properties: When double-clicking on a note in the pattern editor, the noteMin offset was not taken into consideration, which lead to wrong information for some formats. [Fix] Note Properties: Works partly with PC notes now. [Imp] Instrument editor: When inserting new envelope points using Shift+Click, the point can now be instantly dragged. [Imp] Setup: Added note to "always center active row" hint that this is required to be enabled for greyed out patterns [Imp] XI Saver: Fill out the "created with" field properly (OpenMPT instead of FastTracker 2) [Ref] Find/Replace: Partly rewrote Ins+/-1 code, does not work yet (didn't work before, either) [Ref] Renamed Echo Paste to Overflow Paste Modified Paths: -------------- trunk/OpenMPT/mptrack/CommandSet.cpp trunk/OpenMPT/mptrack/CommandSet.h trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Ctrl_pat.cpp trunk/OpenMPT/mptrack/Ctrl_pat.h trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Moptions.cpp trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/mptrack/View_ins.h 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/mptrack.rc trunk/OpenMPT/mptrack/res/patterns.bmp trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/CommandSet.cpp =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.cpp 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/CommandSet.cpp 2009-09-06 12:45:07 UTC (rev 353) @@ -2315,10 +2315,10 @@ commands[kcChannelReset].isDummy = false; commands[kcChannelReset].Message = "Reset channel"; - commands[kcSwitchEchoPaste].UID = 1787; - commands[kcSwitchEchoPaste].Message = "Switch echo paste"; - commands[kcSwitchEchoPaste].isHidden = false; - commands[kcSwitchEchoPaste].isDummy = false; + commands[kcSwitchOverflowPaste].UID = 1787; + commands[kcSwitchOverflowPaste].Message = "Toggle overflow paste"; + commands[kcSwitchOverflowPaste].isHidden = false; + commands[kcSwitchOverflowPaste].isDummy = false; commands[kcNotePC].UID = 1788; commands[kcNotePC].isHidden = false; Modified: trunk/OpenMPT/mptrack/CommandSet.h =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.h 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/CommandSet.h 2009-09-06 12:45:07 UTC (rev 353) @@ -84,7 +84,7 @@ kcEditPaste, kcEditMixPaste, kcEditMixPasteITStyle, - kcSwitchEchoPaste, + kcSwitchOverflowPaste, kcEditSelectAll, kcEditFind, kcEditFindNext, Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-09-06 12:45:07 UTC (rev 353) @@ -314,7 +314,10 @@ } wsprintf(s, "Map all notes to sample %d", pIns->Keyboard[m_nNote]); AppendMenu(hMenu, MF_STRING, ID_NOTEMAP_COPY_SMP, s); - wsprintf(s, "Map all notes to %s", pSndFile->GetNoteName(pIns->NoteMap[m_nNote], m_nInstrument).c_str()); + if(pIns->NoteMap[m_nNote] < NOTE_MIN_SPECIAL) + wsprintf(s, "Map all notes to %s", pSndFile->GetNoteName(pIns->NoteMap[m_nNote], m_nInstrument).c_str()); + else + wsprintf(s, "Map all notes to %s", szSpecialNoteNames[pIns->NoteMap[m_nNote] - NOTE_MIN_SPECIAL]); AppendMenu(hMenu, MF_STRING, ID_NOTEMAP_COPY_NOTE, s); AppendMenu(hMenu, MF_STRING, ID_NOTEMAP_RESET, "Reset note mapping"); AppendMenu(hMenu, MF_STRING, ID_INSTRUMENT_DUPLICATE, "Duplicate Instrument\tShift+New"); Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-09-06 12:45:07 UTC (rev 353) @@ -52,7 +52,7 @@ ON_COMMAND(ID_PATTERNDETAIL_LO, OnDetailLo) ON_COMMAND(ID_PATTERNDETAIL_MED, OnDetailMed) ON_COMMAND(ID_PATTERNDETAIL_HI, OnDetailHi) - ON_COMMAND(ID_ECHOPASTE, OnToggleEchoPaste) + ON_COMMAND(ID_OVERFLOWPASTE, OnToggleOverflowPaste) ON_CBN_SELCHANGE(IDC_COMBO_INSTRUMENT, OnInstrumentChanged) // -> CODE#0012 // -> DESC="midi keyboard split" @@ -158,7 +158,7 @@ m_ToolBar.AddButton(ID_PATTERNDETAIL_MED, 31, TBSTYLE_CHECK, TBSTATE_ENABLED); m_ToolBar.AddButton(ID_PATTERNDETAIL_HI, 32, TBSTYLE_CHECK, TBSTATE_ENABLED|TBSTATE_CHECKED); m_ToolBar.AddButton(ID_SEPARATOR, 0, TBSTYLE_SEP); - m_ToolBar.AddButton(ID_ECHOPASTE, 38, TBSTYLE_CHECK, ((CMainFrame::m_dwPatternSetup & PATTERN_ECHOPASTE) ? TBSTATE_CHECKED : 0) | TBSTATE_ENABLED); + m_ToolBar.AddButton(ID_OVERFLOWPASTE, 38, TBSTYLE_CHECK, ((CMainFrame::m_dwPatternSetup & PATTERN_OVERFLOWPASTE) ? TBSTATE_CHECKED : 0) | TBSTATE_ENABLED); // Special edit controls -> tab switch to view m_EditSpacing.SetParent(this); @@ -297,7 +297,7 @@ // -> CODE#0007 // -> DESC="uncheck follow song checkbox by default" CheckDlgButton(IDC_PATTERN_FOLLOWSONG, (CMainFrame::m_dwPatternSetup & PATTERN_FOLLOWSONGOFF) ? MF_UNCHECKED : MF_CHECKED); - m_ToolBar.SetState(ID_ECHOPASTE, ((CMainFrame::m_dwPatternSetup & PATTERN_ECHOPASTE) ? TBSTATE_CHECKED : 0) | TBSTATE_ENABLED); + m_ToolBar.SetState(ID_OVERFLOWPASTE, ((CMainFrame::m_dwPatternSetup & PATTERN_OVERFLOWPASTE) ? TBSTATE_CHECKED : 0) | TBSTATE_ENABLED); // -! BEHAVIOUR_CHANGE#0007 } if (dwHintMask & (HINT_MODTYPE|HINT_INSNAMES|HINT_SMPNAMES|HINT_PATNAMES)) @@ -1216,10 +1216,10 @@ SwitchToView(); } -void CCtrlPatterns::OnToggleEchoPaste() +void CCtrlPatterns::OnToggleOverflowPaste() //------------------------------------- { - CMainFrame::m_dwPatternSetup ^= PATTERN_ECHOPASTE; + CMainFrame::m_dwPatternSetup ^= PATTERN_OVERFLOWPASTE; UpdateView(HINT_MPTOPTIONS, NULL); SwitchToView(); } Modified: trunk/OpenMPT/mptrack/Ctrl_pat.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-09-06 12:45:07 UTC (rev 353) @@ -227,7 +227,7 @@ afx_msg void OnUpdateRecord(CCmdUI *pCmdUI); afx_msg void TogglePluginEditor(); //rewbs.instroVST afx_msg void ToggleSplitPluginEditor(); //rewbs.instroVST - afx_msg void OnToggleEchoPaste(); + afx_msg void OnToggleOverflowPaste(); //}}AFX_MSG DECLARE_MESSAGE_MAP() Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-09-06 12:45:07 UTC (rev 353) @@ -618,7 +618,7 @@ DWORD d; // Length / Type - wsprintf(s, "%d-bit %s, len: %d", (pSmp->uFlags & CHN_16BIT) ? 16 : 8, (pSmp->uFlags & CHN_STEREO) ? "stereo" : "mono", pSmp->nLength); + wsprintf(s, "%d-bit %s, len: %d", pSmp->GetElementarySampleSize() * 8, (pSmp->uFlags & CHN_STEREO) ? "stereo" : "mono", pSmp->nLength); SetDlgItemText(IDC_TEXT5, s); // Name memcpy(s, m_pSndFile->m_szNames[m_nSample], 32); Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2009-09-06 12:45:07 UTC (rev 353) @@ -207,7 +207,7 @@ #define PATTERN_SYNCMUTE 0x1000000 #define PATTERN_AUTODELAY 0x2000000 #define PATTERN_NOTEFADE 0x4000000 -#define PATTERN_ECHOPASTE 0x8000000 +#define PATTERN_OVERFLOWPASTE 0x8000000 #define PATTERN_POSITIONAWARETIMER 0x10000000 #define PATTERN_RESETCHANNELS 0x20000000 Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-06 12:45:07 UTC (rev 353) @@ -2315,7 +2315,7 @@ nrow++; //jojo.echopaste - if(CMainFrame::m_dwPatternSetup & PATTERN_ECHOPASTE) + if(CMainFrame::m_dwPatternSetup & PATTERN_OVERFLOWPASTE) { while(nrow >= m_SndFile.PatternSize[nPattern]) { Modified: trunk/OpenMPT/mptrack/Moptions.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moptions.cpp 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/Moptions.cpp 2009-09-06 12:45:07 UTC (rev 353) @@ -605,7 +605,7 @@ OPTGEN_SYNCMUTE, OPTGEN_AUTODELAY, OPTGEN_PATNOTEFADE, - OPTGEN_ECHOPASTE, + OPTGEN_OVERFLOWPASTE, OPTGEN_POSITIONAWARETIMER, OPTGEN_RESETCHANNELS, OPTGEN_MAXOPTIONS @@ -625,7 +625,7 @@ {"Ignored muted channels", "Notes will not be played on muted channels (unmuting will only start on a new note)."}, {"Quick cursor paste Auto-Repeat", "Leaving the space bar pressed will auto-repeat the action"}, {"No loud samples", "Disable loud playback of samples in the sample/instrument editor"}, - {"Show Prev/Next patterns", "Displays grayed-out version of the previous/next patterns in the pattern editor"}, + {"Show Prev/Next patterns", "Displays grayed-out version of the previous/next patterns in the pattern editor. Does not work if \"always center active row\" is disabled."}, {"Continuous scroll", "Jumps to the next pattern when moving past the end of a pattern"}, {"Record note off", "Record note off when a key is released on the PC keyboard (Only works in instrument mode)."}, {"Follow song off by default", "Ensure follow song is off when opening or starting a new song."}, //rewbs.noFollow @@ -644,7 +644,7 @@ {"Maintain sample sync on mute", "Samples continue to be processed when channels are muted (like in IT2 and FT2)"}, {"Automatic delay commands", "Automatically insert appropriate note-delay commands when recording notes during live playback."}, {"Note fade on key up", "Enable to fade/stop notes on key up in pattern tab." }, - {"Echo paste mode", "Wrap pasted pattern data into next pattern. This is useful for creating echo channels."}, + {"Overflow paste mode", "Wrap pasted pattern data into next pattern. This is useful for creating echo channels."}, {"Position aware timer", "If enabled, timer will show the playback position time if possible instead of running timer."}, {"Reset channels on loop", "If enabled, channels will be reset to their initial state when song looping is enabled.\nNote: This does not affect manual song loops (i.e. triggered by pattern commands)"}, }; @@ -709,7 +709,7 @@ case OPTGEN_AUTODELAY: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_AUTODELAY); break; case OPTGEN_PATNOTEFADE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_NOTEFADE); break; - case OPTGEN_ECHOPASTE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_ECHOPASTE); break; + case OPTGEN_OVERFLOWPASTE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_OVERFLOWPASTE); break; case OPTGEN_POSITIONAWARETIMER: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_POSITIONAWARETIMER); break; case OPTGEN_RESETCHANNELS: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_RESETCHANNELS); break; } @@ -774,13 +774,13 @@ // case OPTGEN_ALTERNTIVEBPMSPEED: mask = PATTERN_ALTERNTIVEBPMSPEED; break; // rewbs: this options is now available under song settings. It is therefore saved with the song. // -! NEW_FEATURE#0022 - case OPTGEN_PATTERNCTXMENUSTYLE: mask = PATTERN_OLDCTXMENUSTYLE; break; - case OPTGEN_SYNCMUTE: mask = PATTERN_SYNCMUTE; break; - case OPTGEN_AUTODELAY: mask = PATTERN_AUTODELAY; break; - case OPTGEN_PATNOTEFADE: mask = PATTERN_NOTEFADE; break; - case OPTGEN_ECHOPASTE: mask = PATTERN_ECHOPASTE; break; - case OPTGEN_POSITIONAWARETIMER: mask = PATTERN_POSITIONAWARETIMER; break; - case OPTGEN_RESETCHANNELS: mask = PATTERN_RESETCHANNELS; break; + case OPTGEN_PATTERNCTXMENUSTYLE: mask = PATTERN_OLDCTXMENUSTYLE; break; + case OPTGEN_SYNCMUTE: mask = PATTERN_SYNCMUTE; break; + case OPTGEN_AUTODELAY: mask = PATTERN_AUTODELAY; break; + case OPTGEN_PATNOTEFADE: mask = PATTERN_NOTEFADE; break; + case OPTGEN_OVERFLOWPASTE: mask = PATTERN_OVERFLOWPASTE; break; + case OPTGEN_POSITIONAWARETIMER: mask = PATTERN_POSITIONAWARETIMER; break; + case OPTGEN_RESETCHANNELS: mask = PATTERN_RESETCHANNELS; break; } if (bCheck) CMainFrame::m_dwPatternSetup |= mask; else CMainFrame::m_dwPatternSetup &= ~mask; Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-09-06 12:45:07 UTC (rev 353) @@ -1204,7 +1204,117 @@ return envelope->Ticks[EnvGetReleaseNode()]; } +bool CViewInstrument::EnvRemovePoint() +//-------------------------------------- +{ + CModDoc *pModDoc = GetDocument(); + if ((pModDoc) && (m_nDragItem) && (m_nDragItem-1 <= EnvGetLastPoint())) + { + CSoundFile *pSndFile = pModDoc->GetSoundFile(); + MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; + if (pIns) + { + INSTRUMENTENVELOPE *envelope = GetEnvelopePtr(); + if(envelope == nullptr || envelope->nNodes == 0) return false; + UINT nPoint = m_nDragItem - 1; + + envelope->nNodes--; + for (UINT i=nPoint; i<envelope->nNodes; i++) + { + envelope->Ticks[i] = envelope->Ticks[i + 1]; + envelope->Values[i] = envelope->Values[i + 1]; + } + if (nPoint >= envelope->nNodes) nPoint = envelope->nNodes-1; + if (envelope->nLoopStart > nPoint) envelope->nLoopStart--; + if (envelope->nLoopEnd > nPoint) envelope->nLoopEnd--; + if (envelope->nSustainStart > nPoint) envelope->nSustainStart--; + if (envelope->nSustainEnd > nPoint) envelope->nSustainEnd--; + if (envelope->nReleaseNode>nPoint && envelope->nReleaseNode!=ENV_RELEASE_NODE_UNSET) envelope->nReleaseNode--; + envelope->Ticks[0] = 0; + + pModDoc->SetModified(); + pModDoc->UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | HINT_ENVELOPE, NULL); + return true; + } + } + return false; +} + +// Insert point. Returns 0 if error occured, else point ID + 1. +UINT CViewInstrument::EnvInsertPoint() +//------------------------------------ +{ + CModDoc *pModDoc = GetDocument(); + if (pModDoc) + { + CSoundFile *pSndFile = pModDoc->GetSoundFile(); + MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; + if (pIns) + { + int nTick = ScreenToTick(m_ptMenu.x); + int nValue = ScreenToValue(m_ptMenu.y); + if(nTick < 0) return false; + + UINT maxpoints = (pSndFile->m_nType == MOD_TYPE_XM) ? 12 : 25; + //To check: Should there be MAX_ENVPOINTS? + + nValue = CLAMP(nValue, 0, 64); + + INSTRUMENTENVELOPE *envelope = GetEnvelopePtr(); + if(envelope == nullptr) return false; + BYTE cDefaultValue; + + switch(m_nEnv) + { + case ENV_VOLUME: + cDefaultValue = 64; + break; + case ENV_PANNING: + cDefaultValue = 32; + break; + case ENV_PITCH: + cDefaultValue = (pIns->dwFlags & ENV_FILTER) ? 64 : 32; + break; + default: + return false; + } + + if (envelope->nNodes < maxpoints) + { + if (!envelope->nNodes) + { + envelope->Ticks[0] = 0; + envelope->Values[0] = cDefaultValue; + envelope->nNodes = 1; + } + UINT i = 0; + for (i = 0; i < envelope->nNodes; i++) if (nTick <= envelope->Ticks[i]) break; + for (UINT j = envelope->nNodes; j > i; j--) + { + envelope->Ticks[j] = envelope->Ticks[j - 1]; + envelope->Values[j] = envelope->Values[j - 1]; + } + envelope->Ticks[i] = (WORD)nTick; + envelope->Values[i] = (BYTE)nValue; + envelope->nNodes++; + if (envelope->nLoopStart >= i) envelope->nLoopStart++; + if (envelope->nLoopEnd >= i) envelope->nLoopEnd++; + if (envelope->nSustainStart >= i) envelope->nSustainStart++; + if (envelope->nSustainEnd >= i) envelope->nSustainEnd++; + if (envelope->nReleaseNode >= i && envelope->nReleaseNode != ENV_RELEASE_NODE_UNSET) envelope->nReleaseNode++; + + pModDoc->SetModified(); + pModDoc->UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | HINT_ENVELOPE, NULL); + return i + 1; + } + } + } + return 0; +} + + + void CViewInstrument::DrawPositionMarks(HDC hdc) //---------------------------------------------- { @@ -1705,7 +1815,13 @@ if(CMainFrame::GetMainFrame()->GetInputHandler()->ShiftPressed()) { m_ptMenu = pt; - OnEnvInsertPoint(); + m_nDragItem = EnvInsertPoint(); // returns point ID + 1 if successful, else 0. + if(m_nDragItem > 0) + { + // Drag point if successful + SetCapture(); + m_dwStatus |= INSSTATUS_DRAGGING; + } } } } @@ -1939,106 +2055,13 @@ void CViewInstrument::OnEnvRemovePoint() //-------------------------------------- { - CModDoc *pModDoc = GetDocument(); - if ((pModDoc) && (m_nDragItem) && (m_nDragItem-1 <= EnvGetLastPoint())) - { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) - { - INSTRUMENTENVELOPE *envelope = GetEnvelopePtr(); - if(envelope == nullptr || envelope->nNodes == 0) return; - - UINT nPoint = m_nDragItem - 1; - - envelope->nNodes--; - for (UINT i=nPoint; i<envelope->nNodes; i++) - { - envelope->Ticks[i] = envelope->Ticks[i + 1]; - envelope->Values[i] = envelope->Values[i + 1]; - } - if (nPoint >= envelope->nNodes) nPoint = envelope->nNodes-1; - if (envelope->nLoopStart > nPoint) envelope->nLoopStart--; - if (envelope->nLoopEnd > nPoint) envelope->nLoopEnd--; - if (envelope->nSustainStart > nPoint) envelope->nSustainStart--; - if (envelope->nSustainEnd > nPoint) envelope->nSustainEnd--; - if (envelope->nReleaseNode>nPoint && envelope->nReleaseNode!=ENV_RELEASE_NODE_UNSET) envelope->nReleaseNode--; - envelope->Ticks[0] = 0; - - pModDoc->SetModified(); - pModDoc->UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | HINT_ENVELOPE, NULL); - } - } + EnvRemovePoint(); } - void CViewInstrument::OnEnvInsertPoint() //-------------------------------------- { - CModDoc *pModDoc = GetDocument(); - if (pModDoc) - { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) - { - int nTick = ScreenToTick(m_ptMenu.x); - int nValue = ScreenToValue(m_ptMenu.y); - if(nTick < 0) return; - - UINT maxpoints = (pSndFile->m_nType == MOD_TYPE_XM) ? 12 : 25; - //To check: Should there be MAX_ENVPOINTS? - - nValue = CLAMP(nValue, 0, 64); - - INSTRUMENTENVELOPE *envelope = GetEnvelopePtr(); - if(envelope == nullptr) return; - BYTE cDefaultValue; - - switch(m_nEnv) - { - case ENV_VOLUME: - cDefaultValue = 64; - break; - case ENV_PANNING: - cDefaultValue = 32; - break; - case ENV_PITCH: - cDefaultValue = (pIns->dwFlags & ENV_FILTER) ? 64 : 32; - break; - default: - return; - } - - if (envelope->nNodes < maxpoints) - { - if (!envelope->nNodes) - { - envelope->Ticks[0] = 0; - envelope->Values[0] = cDefaultValue; - envelope->nNodes = 1; - } - UINT i = 0; - for (i = 0; i < envelope->nNodes; i++) if (nTick <= envelope->Ticks[i]) break; - for (UINT j = envelope->nNodes; j > i; j--) - { - envelope->Ticks[j] = envelope->Ticks[j - 1]; - envelope->Values[j] = envelope->Values[j - 1]; - } - envelope->Ticks[i] = (WORD)nTick; - envelope->Values[i] = (BYTE)nValue; - envelope->nNodes++; - if (envelope->nLoopStart >= i) envelope->nLoopStart++; - if (envelope->nLoopEnd >= i) envelope->nLoopEnd++; - if (envelope->nSustainStart >= i) envelope->nSustainStart++; - if (envelope->nSustainEnd >= i) envelope->nSustainEnd++; - if (envelope->nReleaseNode >= i && envelope->nReleaseNode != ENV_RELEASE_NODE_UNSET) envelope->nReleaseNode++; - - pModDoc->SetModified(); - pModDoc->UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | HINT_ENVELOPE, NULL); - } - } - } + EnvInsertPoint(); } Modified: trunk/OpenMPT/mptrack/View_ins.h =================================================================== --- trunk/OpenMPT/mptrack/View_ins.h 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/View_ins.h 2009-09-06 12:45:07 UTC (rev 353) @@ -69,6 +69,8 @@ bool EnvSetPanEnv(bool bEnable); bool EnvSetPitchEnv(bool bEnable); bool EnvSetFilterEnv(bool bEnable); + UINT EnvInsertPoint(); + bool EnvRemovePoint(); int TickToScreen(int nTick) const; int PointToScreen(int nPoint) const; int ScreenToTick(int x) const; Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-06 12:45:07 UTC (rev 353) @@ -29,6 +29,7 @@ DWORD CViewPattern::m_dwReplaceFlags = 0; UINT CViewPattern::m_nFindMinChn = 0; UINT CViewPattern::m_nFindMaxChn = 0; +signed char cInstrRelChange = 0; IMPLEMENT_SERIAL(CViewPattern, CModScrollView, 0) @@ -1688,6 +1689,7 @@ pageReplace.m_nCommand = m_cmdReplace.command; pageReplace.m_nParam = m_cmdReplace.param; pageReplace.m_dwFlags = m_dwReplaceFlags; + pageReplace.cInstrRelChange = m_cInstrRelChange; dlg.AddPage(&pageFind); dlg.AddPage(&pageReplace); if (dlg.DoModal() == IDOK) @@ -1708,6 +1710,7 @@ m_cmdReplace.command = pageReplace.m_nCommand; m_cmdReplace.param = pageReplace.m_nParam; m_dwReplaceFlags = pageReplace.m_dwFlags; + m_cInstrRelChange = pageReplace.cInstrRelChange; m_bContinueSearch = FALSE; OnEditFindNext(); } @@ -1866,7 +1869,7 @@ if (!(m_dwReplaceFlags & PATSEARCH_REPLACE)) goto EndSearch; if (!(m_dwReplaceFlags & PATSEARCH_REPLACEALL)) { - UINT ans = MessageBox("Replace this occurrence ?", "Replace", MB_YESNOCANCEL); + UINT ans = MessageBox("Replace this occurrence?", "Replace", MB_YESNOCANCEL); if (ans == IDYES) bReplace = TRUE; else if (ans == IDNO) bReplace = FALSE; else goto EndSearch; } @@ -1875,22 +1878,22 @@ if ((m_dwReplaceFlags & PATSEARCH_NOTE)) { // -1 octave - if (m_cmdReplace.note == CFindReplaceTab::replaceMinusOctave) + if (m_cmdReplace.note == CFindReplaceTab::replaceNoteMinusOctave) { if (m->note > 12) m->note -= 12; } else // +1 octave - if (m_cmdReplace.note == CFindReplaceTab::replacePlusOctave) + if (m_cmdReplace.note == CFindReplaceTab::replaceNotePlusOctave) { if (m->note <= NOTE_MAX - 12) m->note += 12; } else // Note-- - if (m_cmdReplace.note == CFindReplaceTab::replaceMinusOne) + if (m_cmdReplace.note == CFindReplaceTab::replaceNoteMinusOne) { if (m->note > 1) m->note--; } else // Note++ - if (m_cmdReplace.note == CFindReplaceTab::replacePlusOne) + if (m_cmdReplace.note == CFindReplaceTab::replaceNotePlusOne) { if (m->note < NOTE_MAX) m->note++; } else m->note = m_cmdReplace.note; @@ -1898,15 +1901,12 @@ if ((m_dwReplaceFlags & PATSEARCH_INSTR)) { // Instr-- - if (m_cmdReplace.instr == CFindReplaceTab::replaceMinusOne) - { + if (m_cInstrRelChange == -1) if (m->instr > 1) m->instr--; - } else // Instr++ - if (m_cmdReplace.instr == CFindReplaceTab::replacePlusOne) - { - if (m->instr < MAX_INSTRUMENTS-1) m->instr++; - } else m->instr = m_cmdReplace.instr; + else if (m_cInstrRelChange == 1) + if (m->instr < MAX_INSTRUMENTS - 1) m->instr++; + else m->instr = m_cmdReplace.instr; } if ((m_dwReplaceFlags & PATSEARCH_VOLCMD)) { @@ -3609,7 +3609,7 @@ case kcChangeLoopStatus: SendCtrlMessage(CTRLMSG_PAT_LOOP, -1); return wParam; case kcNewPattern: SendCtrlMessage(CTRLMSG_PAT_NEWPATTERN); return wParam; case kcSwitchToOrderList: OnSwitchToOrderList(); - case kcSwitchEchoPaste: CMainFrame::m_dwPatternSetup ^= PATTERN_ECHOPASTE; return wParam; + case kcSwitchOverflowPaste: CMainFrame::m_dwPatternSetup ^= PATTERN_OVERFLOWPASTE; return wParam; } //Ranges: Modified: trunk/OpenMPT/mptrack/View_pat.h =================================================================== --- trunk/OpenMPT/mptrack/View_pat.h 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/View_pat.h 2009-09-06 12:45:07 UTC (rev 353) @@ -76,6 +76,7 @@ static MODCOMMAND m_cmdFind, m_cmdReplace, m_cmdOld; static DWORD m_dwFindFlags, m_dwReplaceFlags; static UINT m_nFindMinChn, m_nFindMaxChn; + signed char m_cInstrRelChange; // relative instrument change (quick'n'dirty fix) protected: CFastBitmap m_Dib; Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-09-06 12:45:07 UTC (rev 353) @@ -667,10 +667,10 @@ combo->SetItemData(combo->AddString("..."), 0); if (m_bReplace) { - combo->SetItemData(combo->AddString("note-1"), replaceMinusOne); - combo->SetItemData(combo->AddString("note+1"), replacePlusOne); - combo->SetItemData(combo->AddString("-1 oct"), replaceMinusOctave); - combo->SetItemData(combo->AddString("+1 oct"), replacePlusOctave); + combo->SetItemData(combo->AddString("note-1"), replaceNoteMinusOne); + combo->SetItemData(combo->AddString("note+1"), replaceNotePlusOne); + combo->SetItemData(combo->AddString("-1 oct"), replaceNoteMinusOctave); + combo->SetItemData(combo->AddString("+1 oct"), replaceNotePlusOctave); } else { combo->SetItemData(combo->AddString("any"), findAny); @@ -690,8 +690,8 @@ combo->SetItemData(combo->AddString(".."), 0); if (m_bReplace) { - combo->SetItemData(combo->AddString("ins-1"), replaceMinusOne); - combo->SetItemData(combo->AddString("ins+1"), replacePlusOne); + combo->SetItemData(combo->AddString("ins-1"), replaceInstrumentMinusOne); + combo->SetItemData(combo->AddString("ins+1"), replaceInstrumentPlusOne); } for (UINT n=1; n<MAX_INSTRUMENTS; n++) { @@ -705,10 +705,13 @@ combo->SetItemData(combo->AddString(s), n); } UINT ncount = combo->GetCount(); - for (UINT i=0; i<ncount; i++) if (m_nInstr == combo->GetItemData(i)) + for (UINT i=0; i<ncount; i++) { - combo->SetCurSel(i); - break; + if (m_nInstr == combo->GetItemData(i) || (cInstrRelChange == -1 && combo->GetItemData(i) == replaceInstrumentMinusOne) || (cInstrRelChange == 1 && combo->GetItemData(i) == replaceInstrumentPlusOne)) + { + combo->SetCurSel(i); + break; + } } } // Volume Command @@ -844,7 +847,19 @@ // Instrument if ((combo = (CComboBox *)GetDlgItem(IDC_COMBO2)) != NULL) { - m_nInstr = combo->GetItemData(combo->GetCurSel()); + switch(combo->GetItemData(combo->GetCurSel())) + { + case replaceInstrumentMinusOne: + cInstrRelChange = -1; + break; + case replaceInstrumentPlusOne: + cInstrRelChange = 1; + break; + default: + m_nInstr = combo->GetItemData(combo->GetCurSel()); + cInstrRelChange = 0; + break; + } } // Volume Command if (((combo = (CComboBox *)GetDlgItem(IDC_COMBO3)) != NULL) && (m_pModDoc)) @@ -1230,7 +1245,10 @@ AppendNotesToControlEx(*combo, pSndFile, m_nInstr); if (m_nNote <= NOTE_MAX) - combo->SetCurSel(m_nNote); + { + const MODCOMMAND::NOTE noteStart = (pSndFile != nullptr) ? pSndFile->GetModSpecifications().noteMin : 1; + combo->SetCurSel(m_nNote - (noteStart - 1)); + } else { for(int i = combo->GetCount() - 1; i >= 0; --i) @@ -1248,21 +1266,31 @@ if ((combo = (CComboBox *)GetDlgItem(IDC_COMBO2)) != NULL) { combo->ResetContent(); - combo->SetItemData(combo->AddString("No Instrument"), 0); - UINT max = pSndFile->m_nInstruments; - if (!max) max = pSndFile->m_nSamples; - for (UINT i=1; i<=max; i++) + + if(m_nNote == NOTE_PC || m_nNote == NOTE_PCS) { - wsprintf(s, "%02d:", i); - int k = strlen(s); - if (pSndFile->m_nInstruments) + // control plugin param note + combo->SetItemData(combo->AddString("No Effect"), 0); + AddPluginNamesToCombobox(*combo, pSndFile->m_MixPlugins, false); + } else + { + // instrument / sample + combo->SetItemData(combo->AddString("No Instrument"), 0); + UINT max = max(pSndFile->m_nInstruments, pSndFile->m_nSamples); // instrument / sample mode + for (UINT i = 1; i <= max; i++) { - if (pSndFile->Instruments[i]) - memcpy(s+k, pSndFile->Instruments[i]->name, 32); - } else - memcpy(s+k, pSndFile->m_szNames[i], 32); - s[k+32] = 0; - combo->SetItemData(combo->AddString(s), i); + wsprintf(s, "%02d: ", i); + int k = strlen(s); + // instrument / sample + if (pSndFile->m_nInstruments) + { + if (pSndFile->Instruments[i]) + memcpy(s+k, pSndFile->Instruments[i]->name, 32); + } else + memcpy(s+k, pSndFile->m_szNames[i], 32); + s[k+32] = 0; + combo->SetItemData(combo->AddString(s), i); + } } combo->SetCurSel(m_nInstr); } @@ -1272,6 +1300,8 @@ void CPageEditNote::OnNoteChanged() //--------------------------------- { + bool bWasParamControl = (m_nNote == NOTE_PC || m_nNote == NOTE_PCS) ? true : false; + CComboBox *combo; if ((combo = (CComboBox *)GetDlgItem(IDC_COMBO1)) != NULL) { @@ -1294,6 +1324,10 @@ } } } + bool bIsNowParamControl = (m_nNote == NOTE_PC || m_nNote == NOTE_PCS) ? true : false; + if(bWasParamControl != bIsNowParamControl) + UpdateDialog(); + if (m_pParent) m_pParent->UpdateNote(m_nNote, m_nInstr); } @@ -1324,7 +1358,7 @@ if ((combo = (CComboBox *)GetDlgItem(IDC_COMBO1)) != NULL) { CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); - if (pSndFile->m_nType == MOD_TYPE_MOD) + if (pSndFile->m_nType == MOD_TYPE_MOD || m_bIsParamControl) { combo->EnableWindow(FALSE); return; @@ -1427,18 +1461,27 @@ pSndFile = m_pModDoc->GetSoundFile(); if ((combo = (CComboBox *)GetDlgItem(IDC_COMBO1)) != NULL) { - UINT numfx = m_pModDoc->GetNumEffects(); - UINT fxndx = m_pModDoc->GetIndexFromEffect(m_nCommand, m_nParam); combo->ResetContent(); - combo->SetItemData(combo->AddString(" None"), (DWORD)-1); - if (!m_nCommand) combo->SetCurSel(0); - for (UINT i=0; i<numfx; i++) + if(m_bIsParamControl) { - if (m_pModDoc->GetEffectInfo(i, s, TRUE)) + // plugin param control note + AddPluginParameternamesToCombobox(*combo, pSndFile->m_MixPlugins[m_nPlugin]); + combo->SetCurSel(m_nPluginParam); + } else + { + // process as effect + UINT numfx = m_pModDoc->GetNumEffects(); + UINT fxndx = m_pModDoc->GetIndexFromEffect(m_nCommand, m_nParam); + combo->SetItemData(combo->AddString(" None"), (DWORD)-1); + if (!m_nCommand) combo->SetCurSel(0); + for (UINT i=0; i<numfx; i++) { - int k = combo->AddString(s); - combo->SetItemData(k, i); - if (i == fxndx) combo->SetCurSel(k); + if (m_pModDoc->GetEffectInfo(i, s, TRUE)) + { + int k = combo->AddString(s); + combo->SetItemData(k, i); + if (i == fxndx) combo->SetCurSel(k); + } } } } Modified: trunk/OpenMPT/mptrack/dlg_misc.h =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.h 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/dlg_misc.h 2009-09-06 12:45:07 UTC (rev 353) @@ -133,6 +133,7 @@ public: UINT m_nNote, m_nInstr, m_nVolCmd, m_nVol, m_nCommand, m_nParam, m_nMinChannel, m_nMaxChannel; + signed char cInstrRelChange; DWORD m_dwFlags; enum findItem @@ -143,10 +144,13 @@ enum replaceItem { - replaceMinusOctave = NOTE_MIN_SPECIAL - 1, - replacePlusOctave = NOTE_MIN_SPECIAL - 2, - replaceMinusOne = NOTE_MIN_SPECIAL - 3, - replacePlusOne = NOTE_MIN_SPECIAL - 4 + replaceNotePlusOne = NOTE_MAX + 1, + replaceNoteMinusOne = NOTE_MAX + 2, + replaceNotePlusOctave = NOTE_MAX + 3, + replaceNoteMinusOctave = NOTE_MAX + 4, + + replaceInstrumentPlusOne = MAX_INSTRUMENTS + 1, + replaceInstrumentMinusOne = MAX_INSTRUMENTS + 2, }; // Make sure there's unused notes between NOTE_MAX and NOTE_MIN_SPECIAL. @@ -235,10 +239,11 @@ { protected: UINT m_nVolCmd, m_nVolume; + bool m_bIsParamControl; public: CPageEditVolume(CModDoc *pModDoc, CEditCommand *parent):CPageEditCommand(pModDoc, parent, IDD_PAGEEDITVOLUME) {} - void Init(MODCOMMAND &m) { m_nVolCmd = m.volcmd; m_nVolume = m.vol; } + void Init(MODCOMMAND &m) { m_nVolCmd = m.volcmd; m_nVolume = m.vol; m_bIsParamControl = (m.note == NOTE_PC || m.note == NOTE_PCS) ? true : false;} void UpdateDialog(); void UpdateRanges(); @@ -256,7 +261,9 @@ //============================================ { protected: - UINT m_nCommand, m_nParam; + UINT m_nCommand, m_nParam, m_nPlugin; + UINT m_nPluginParam; + bool m_bIsParamControl; // -> CODE#0010 // -> DESC="add extended parameter mechanism to pattern effects" UINT m_nXParam, m_nMultiplier; @@ -268,7 +275,7 @@ CPageEditEffect(CModDoc *pModDoc, CEditCommand *parent):CPageEditCommand(pModDoc, parent, IDD_PAGEEDITEFFECT) {} // -> CODE#0010 // -> DESC="add extended parameter mechanism to pattern effects" - void Init(MODCOMMAND &m) { m_nCommand = m.command; m_nParam = m.param; m_pModcommand = &m;} + void Init(MODCOMMAND &m) { m_nCommand = m.command; m_nParam = m.param; m_pModcommand = &m; m_bIsParamControl = (m.note == NOTE_PC || m.note == NOTE_PCS) ? true : false; m_nPlugin = m.instr; m_nPluginParam = MODCOMMAND::GetValueVolCol(m.volcmd, m.vol);} void XInit(UINT xparam = 0, UINT multiplier = 1) { m_nXParam = xparam; m_nMultiplier = multiplier; } // -! NEW_FEATURE#0010 void UpdateDialog(); Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/mptrack.rc 2009-09-06 12:45:07 UTC (rev 353) @@ -2120,7 +2120,7 @@ BEGIN ID_EDIT_GOTO_MENU "Go to row / channel / pattern / order" ID_CLEANUP_COMPO "Reset attributes to defaults (useful for creating sample packs)\nCompo Cleanup" - ID_ECHOPASTE "Toggle echo paste\nToggle echo paste" + ID_OVERFLOWPASTE "Toggle overflow paste\nToggle overflow paste" END STRINGTABLE Modified: trunk/OpenMPT/mptrack/res/patterns.bmp =================================================================== (Binary files differ) Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/mptrack/resource.h 2009-09-06 12:45:07 UTC (rev 353) @@ -1113,7 +1113,7 @@ #define ID_CLEANUP_COMPO 59221 #define ID_SAMPLE_DRAW 59224 #define ID_SAMPLE_ADDSILENCE 59225 -#define ID_ECHOPASTE 59226 +#define ID_OVERFLOWPASTE 59226 #define ID_NOTEMAP_COPY_NOTE 59227 #define ID_CLEANUP_REARRANGESAMPLES 59228 Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-06 12:45:07 UTC (rev 353) @@ -230,7 +230,7 @@ const ITOLDINSTRUMENT *pis = (const ITOLDINSTRUMENT *)p; memcpy(pIns->name, pis->name, 26); memcpy(pIns->filename, pis->filename, 12); - pIns->nFadeOut = pis->fadeout << 7; + pIns->nFadeOut = pis->fadeout << 6; pIns->nGlobalVol = 64; for (UINT j=0; j<NOTE_MAX; j++) { Modified: trunk/OpenMPT/soundlib/Load_psm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-09-06 12:45:07 UTC (rev 353) @@ -776,7 +776,10 @@ for(uint32 nCell = 0; nCell < m_nChannels * Patterns[endPattern].GetNumRows(); nCell++) { if(row_data->command == CMD_PATTERNBREAK || row_data->command == CMD_POSITIONJUMP) + { lastRow = nCell / m_nChannels; + break; + } row_data++; } TryWriteEffect(endPattern, lastRow, CMD_POSITIONJUMP, (BYTE)subsongs[i].restartPos, false, CHANNELINDEX_INVALID, false, true); Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2009-09-06 12:45:07 UTC (rev 353) @@ -1324,7 +1324,7 @@ memcpy(xfh.extxi, "Extended Instrument: ", 21); memcpy(xfh.name, pIns->name, 22); xfh.name[22] = 0x1A; - memcpy(xfh.trkname, "FastTracker v2.00 ", 20); + memcpy(xfh.trkname, "Created by OpenMPT ", 20); xfh.shsize = 0x102; fwrite(&xfh, 1, sizeof(xfh), f); // XI Instrument Header Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-09-01 22:08:43 UTC (rev 352) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-09-06 12:45:07 UTC (rev 353) @@ -642,16 +642,18 @@ if ((m_nPattern < Patterns.Size()) && (!Patterns[m_nPattern])) m_nPattern = Order.GetIgnoreIndex(); while (m_nPattern >= Patterns.Size()) { - // End of song ? + // End of song? if ((m_nPattern == Order.GetInvalidPatIndex()) || (m_nCurrentPattern >= Order.size())) { if (!m_nRepeatCount) return FALSE; ORDERINDEX nRestartPosOverride = m_nRestartPos; - if(!m_nRestartPos && m_nCurrentPattern <= Order.size()) + if(!m_nRestartPos && m_nCurrentPattern <= Order.size() && m_nCurrentPattern > 0) { - // if we're in a subtune and there's no restart position, go to the first order of the subtune + /* Subtune detection. Subtunes are separated by "---" order items, so if we're in a + subtune and there's no restart position, we go to the first order of the subtune + (i.e. the first order after the previous "---" item) */ for(ORDERINDEX iOrd = m_nCurrentPattern - 1; iOrd > 0; iOrd--) { if(Order[iOrd] == Order.GetInvalidPatIndex()) @@ -709,7 +711,6 @@ //Handle Repeat position if (m_nRepeatCount > 0) m_nRepeatCount--; m_nCurrentPattern = nRestartPosOverride; - //m_nRow = 0; m_dwSongFlags &= ~SONG_BREAKTOROW; //If restart pos points to +++, move along while (Order[m_nCurrentPattern] == Order.GetIgnoreIndex()) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-09-07 20:24:27
|
Revision: 356 http://modplug.svn.sourceforge.net/modplug/?rev=356&view=rev Author: saga-games Date: 2009-09-07 20:24:18 +0000 (Mon, 07 Sep 2009) Log Message: ----------- [New] Pattern editor: When shift-clicking somewhere, a selection will be drawn from the previous cursor position to the new position. [Fix] Mod Saving: The compatibility export was only working properly for 8-bit mono samples. Everything else is going to be downsampled later, so the sample "fixing" has to be done before. Modified Paths: -------------- trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/soundlib/Load_mod.cpp Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-06 19:53:01 UTC (rev 355) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-07 20:24:18 UTC (rev 356) @@ -1032,32 +1032,40 @@ DragToSel(m_dwEndSel, TRUE); } else */ { - m_dwStartSel = GetPositionFromPoint(point); - if (((m_dwStartSel & 0xFFFF) >> 3) < pModDoc->GetNumChannels()) + if(CMainFrame::GetInputHandler()->ShiftPressed()) { - m_dwStatus |= PATSTATUS_MOUSEDRAGSEL; + // Shift pressed -> set 2nd selection point + DragToSel(GetPositionFromPoint(point), TRUE); + } else + { + // Set first selection point + m_dwStartSel = GetPositionFromPoint(point); + if (((m_dwStartSel & 0xFFFF) >> 3) < pModDoc->GetNumChannels()) + { + m_dwStatus |= PATSTATUS_MOUSEDRAGSEL; - if (m_dwStatus & PATSTATUS_CTRLDRAGSEL) - { - SetCurSel(m_dwStartSel, m_dwStartSel); + if (m_dwStatus & PATSTATUS_CTRLDRAGSEL) + { + SetCurSel(m_dwStartSel, m_dwStartSel); + } + 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)) + && ((m_dwStartSel & 0xFFFF) >= (m_dwBeginSel & 0xFFFF)) + && ((m_dwStartSel & 0xFFFF) <= (m_dwEndSel & 0xFFFF))) + { + m_dwStatus |= PATSTATUS_DRAGNDROPEDIT; + } else + if (CMainFrame::m_dwPatternSetup & PATTERN_CENTERROW) + { + SetCurSel(m_dwStartSel, m_dwStartSel); + } else + { + // Fix: Horizontal scrollbar pos screwed when selecting with mouse + SetCursorPosition( m_dwStartSel >> 16, m_dwStartSel & 0xFFFF ); + } } - 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)) - && ((m_dwStartSel & 0xFFFF) >= (m_dwBeginSel & 0xFFFF)) - && ((m_dwStartSel & 0xFFFF) <= (m_dwEndSel & 0xFFFF))) - { - m_dwStatus |= PATSTATUS_DRAGNDROPEDIT; - } else - if (CMainFrame::m_dwPatternSetup & PATTERN_CENTERROW) - { - SetCurSel(m_dwStartSel, m_dwStartSel); - } else - { - // Fix: Horizontal scrollbar pos screwed when selecting with mouse - SetCursorPosition( m_dwStartSel >> 16, m_dwStartSel & 0xFFFF ); - } } } } Modified: trunk/OpenMPT/soundlib/Load_mod.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mod.cpp 2009-09-06 19:53:01 UTC (rev 355) +++ trunk/OpenMPT/soundlib/Load_mod.cpp 2009-09-07 20:24:18 UTC (rev 356) @@ -546,8 +546,8 @@ MODSAMPLE *pSmp = &Samples[insmap[ismpd]]; if(bCompatibilityExport == true) // first two bytes have to be 0 due to PT's one-shot loop ("no loop") { - if(pSmp->nLength > 0) pSmp->pSample[0] = 0; - if(pSmp->nLength > 1) pSmp->pSample[1] = 0; + int iOverwriteLen = 2 * pSmp->GetElementarySampleSize() * ((pSmp->uFlags & CHN_STEREO) ? 2 : 1); + memset(pSmp->pSample, 0, min(iOverwriteLen, pSmp->GetSampleSizeInBytes())); } UINT flags = RS_PCM8S; #ifndef NO_PACKING This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-09-09 22:43:42
|
Revision: 357 http://modplug.svn.sourceforge.net/modplug/?rev=357&view=rev Author: saga-games Date: 2009-09-09 22:43:27 +0000 (Wed, 09 Sep 2009) Log Message: ----------- [New] MPTM: Allow up to 240 envelope points (did not set it to 255 to have a safety margin). Write additional loop points to extended instrument properties. [Ref] Rewrote a bit of the IT loader to avoid C&P code, removed constants where they should not be used Modified Paths: -------------- trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/Snd_defs.h trunk/OpenMPT/soundlib/mod_specifications.h Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2009-09-07 20:24:18 UTC (rev 356) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-09-09 22:43:27 UTC (rev 357) @@ -1256,9 +1256,6 @@ int nValue = ScreenToValue(m_ptMenu.y); if(nTick < 0) return false; - UINT maxpoints = (pSndFile->m_nType == MOD_TYPE_XM) ? 12 : 25; - //To check: Should there be MAX_ENVPOINTS? - nValue = CLAMP(nValue, 0, 64); INSTRUMENTENVELOPE *envelope = GetEnvelopePtr(); @@ -1280,7 +1277,7 @@ return false; } - if (envelope->nNodes < maxpoints) + if (envelope->nNodes < pSndFile->GetModSpecifications().envelopePointsMax) { if (!envelope->nNodes) { @@ -1973,8 +1970,6 @@ CModDoc *pModDoc = GetDocument(); if ((pModDoc) && (node>0) && (node <= EnvGetLastPoint())) { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - INSTRUMENTENVELOPE *envelope = GetEnvelopePtr(); if(envelope == nullptr) return; Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-07 20:24:18 UTC (rev 356) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-09 22:43:27 UTC (rev 357) @@ -216,11 +216,31 @@ return (value > 9) ? 9 : value; } +// 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) +//----------------------------------------------------------------------------------------------------------- +{ + mptEnv->nNodes = min(itEnv->num, iEnvMax); + mptEnv->nLoopStart = itEnv->lpb; + mptEnv->nLoopEnd = itEnv->lpe; + mptEnv->nSustainStart = itEnv->slb; + mptEnv->nSustainEnd = itEnv->sle; + // Attention: Full MPTM envelope is stored in extended instrument properties + for (UINT ev = 0; ev < 25; ev++) + { + mptEnv->Values[ev] = itEnv->data[ev * 3] + envOffset; + mptEnv->Ticks[ev] = (itEnv->data[ev * 3 + 2] << 8) | (itEnv->data[ev * 3 + 1]); + } +} + //BOOL CSoundFile::ITInstrToMPT(const void *p, MODINSTRUMENT *pIns, UINT trkvers) long CSoundFile::ITInstrToMPT(const void *p, MODINSTRUMENT *pIns, UINT trkvers) //rewbs.modularInstData //-------------------------------------------------------------------------------- { + // Envelope point count. Limited to 25 in IT format. + const int iEnvMax = (m_nType & MOD_TYPE_MPT) ? MAX_ENVPOINTS : 25; + long returnVal=0; pIns->pTuning = m_defaultInstrument.pTuning; pIns->nPluginVelocityHandling = PLUGIN_VELOCITYHANDLING_CHANNEL; @@ -257,6 +277,7 @@ } pIns->VolEnv.Values[ev] = pis->nodes[ev*2+1]; } + pIns->nNNA = pis->nna; pIns->nDCT = pis->dnc; pIns->nPan = 0x80; @@ -283,7 +304,7 @@ pIns->nFadeOut = pis->fadeout << 5; // should be 6? pIns->nGlobalVol = pis->gbv >> 1; if (pIns->nGlobalVol > 64) pIns->nGlobalVol = 64; - for (UINT j=0; j<NOTE_MAX; j++) + for (UINT j = 0; j < 120; j++) { UINT note = pis->keyboard[j*2]; UINT ins = pis->keyboard[j*2+1]; @@ -295,7 +316,7 @@ if (*((int *)pis->dummy) == 'MPTX') { const ITINSTRUMENTEX *pisex = (const ITINSTRUMENTEX *)pis; - for (UINT k=0; k<NOTE_MAX; k++) + for (UINT k = 0; k < 120; k++) { pIns->Keyboard[k] |= ((UINT)pisex->keyboardhi[k] << 8); } @@ -352,45 +373,21 @@ if (pis->volenv.flags & 2) pIns->dwFlags |= ENV_VOLLOOP; if (pis->volenv.flags & 4) pIns->dwFlags |= ENV_VOLSUSTAIN; if (pis->volenv.flags & 8) pIns->dwFlags |= ENV_VOLCARRY; - pIns->VolEnv.nNodes = pis->volenv.num; - if (pIns->VolEnv.nNodes > 25) pIns->VolEnv.nNodes = 25; - pIns->VolEnv.nLoopStart = pis->volenv.lpb; - pIns->VolEnv.nLoopEnd = pis->volenv.lpe; - pIns->VolEnv.nSustainStart = pis->volenv.slb; - pIns->VolEnv.nSustainEnd = pis->volenv.sle; + ITEnvToMPT(&pis->volenv, &pIns->VolEnv, 0, iEnvMax); // Panning Envelope if (pis->panenv.flags & 1) pIns->dwFlags |= ENV_PANNING; if (pis->panenv.flags & 2) pIns->dwFlags |= ENV_PANLOOP; if (pis->panenv.flags & 4) pIns->dwFlags |= ENV_PANSUSTAIN; if (pis->panenv.flags & 8) pIns->dwFlags |= ENV_PANCARRY; - pIns->PanEnv.nNodes = pis->panenv.num; - if (pIns->PanEnv.nNodes > 25) pIns->PanEnv.nNodes = 25; - pIns->PanEnv.nLoopStart = pis->panenv.lpb; - pIns->PanEnv.nLoopEnd = pis->panenv.lpe; - pIns->PanEnv.nSustainStart = pis->panenv.slb; - pIns->PanEnv.nSustainEnd = pis->panenv.sle; + ITEnvToMPT(&pis->panenv, &pIns->PanEnv, 32, iEnvMax); // Pitch Envelope if (pis->pitchenv.flags & 1) pIns->dwFlags |= ENV_PITCH; if (pis->pitchenv.flags & 2) pIns->dwFlags |= ENV_PITCHLOOP; if (pis->pitchenv.flags & 4) pIns->dwFlags |= ENV_PITCHSUSTAIN; if (pis->pitchenv.flags & 8) pIns->dwFlags |= ENV_PITCHCARRY; if (pis->pitchenv.flags & 0x80) pIns->dwFlags |= ENV_FILTER; - pIns->PitchEnv.nNodes = pis->pitchenv.num; - if (pIns->PitchEnv.nNodes > 25) pIns->PitchEnv.nNodes = 25; - pIns->PitchEnv.nLoopStart = pis->pitchenv.lpb; - pIns->PitchEnv.nLoopEnd = pis->pitchenv.lpe; - pIns->PitchEnv.nSustainStart = pis->pitchenv.slb; - pIns->PitchEnv.nSustainEnd = pis->pitchenv.sle; - // Envelopes Data - for (UINT ev=0; ev<25; ev++) - { - pIns->VolEnv.Values[ev] = pis->volenv.data[ev*3]; - pIns->VolEnv.Ticks[ev] = (pis->volenv.data[ev*3+2] << 8) | (pis->volenv.data[ev*3+1]); - pIns->PanEnv.Values[ev] = pis->panenv.data[ev*3] + 32; - pIns->PanEnv.Ticks[ev] = (pis->panenv.data[ev*3+2] << 8) | (pis->panenv.data[ev*3+1]); - pIns->PitchEnv.Values[ev] = pis->pitchenv.data[ev*3] + 32; - pIns->PitchEnv.Ticks[ev] = (pis->pitchenv.data[ev*3+2] << 8) | (pis->pitchenv.data[ev*3+1]); - } + ITEnvToMPT(&pis->pitchenv, &pIns->PitchEnv, 32, iEnvMax); + pIns->nNNA = pis->nna; pIns->nDCT = pis->dct; pIns->nDNA = pis->dca; @@ -407,9 +404,10 @@ if (pIns->nPan > 256) pIns->nPan = 128; if (pis->dfp < 0x80) pIns->dwFlags |= ENV_SETPANNING; } - if ((pIns->VolEnv.nLoopStart >= 25) || (pIns->VolEnv.nLoopEnd >= 25)) pIns->dwFlags &= ~ENV_VOLLOOP; - if ((pIns->VolEnv.nSustainStart >= 25) || (pIns->VolEnv.nSustainEnd >= 25)) pIns->dwFlags &= ~ENV_VOLSUSTAIN; + if ((pIns->VolEnv.nLoopStart >= iEnvMax) || (pIns->VolEnv.nLoopEnd >= iEnvMax)) pIns->dwFlags &= ~ENV_VOLLOOP; + if ((pIns->VolEnv.nSustainStart >= iEnvMax) || (pIns->VolEnv.nSustainEnd >= iEnvMax)) pIns->dwFlags &= ~ENV_VOLSUSTAIN; + return returnVal; //return offset } @@ -3504,7 +3502,20 @@ WriteInstrumentPropertyForAllInstruments('PTTL', sizeof(m_defaultInstrument.wPitchToTempoLock), f, instruments, nInstruments); WriteInstrumentPropertyForAllInstruments('PVEH', sizeof(m_defaultInstrument.nPluginVelocityHandling), f, instruments, nInstruments); WriteInstrumentPropertyForAllInstruments('PVOH', sizeof(m_defaultInstrument.nPluginVolumeHandling), f, instruments, nInstruments); - + + if(m_nType & MOD_TYPE_MPT) + { + // write full envelope information for MPTM files (more env points) + WriteInstrumentPropertyForAllInstruments('VP[.', sizeof(m_defaultInstrument.VolEnv.Ticks ), f, instruments, nInstruments); + WriteInstrumentPropertyForAllInstruments('VE[.', sizeof(m_defaultInstrument.VolEnv.Values), f, instruments, nInstruments); + + WriteInstrumentPropertyForAllInstruments('PP[.', sizeof(m_defaultInstrument.PanEnv.Ticks), f, instruments, nInstruments); + WriteInstrumentPropertyForAllInstruments('PE[.', sizeof(m_defaultInstrument.PanEnv.Values), f, instruments, nInstruments); + + WriteInstrumentPropertyForAllInstruments('PiP[', sizeof(m_defaultInstrument.PitchEnv.Ticks), f, instruments, nInstruments); + WriteInstrumentPropertyForAllInstruments('PiE[', sizeof(m_defaultInstrument.PitchEnv.Values), f, instruments, nInstruments); + } + return; } Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-09-07 20:24:18 UTC (rev 356) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-09-09 22:43:27 UTC (rev 357) @@ -51,7 +51,7 @@ DWORD shsize; // size of XMSAMPLESTRUCT BYTE snum[96]; WORD venv[24]; - WORD pIns[24]; + WORD penv[24]; BYTE vnum, pnum; BYTE vsustain, vloops, vloope, psustain, ploops, ploope; BYTE vtype, ptype; @@ -354,7 +354,7 @@ for (int i = 0; i < 24; ++i) { xmsh.venv[i] = LittleEndianW(xmsh.venv[i]); - xmsh.pIns[i] = LittleEndianW(xmsh.pIns[i]); + xmsh.penv[i] = LittleEndianW(xmsh.penv[i]); } xmsh.volfade = LittleEndianW(xmsh.volfade); xmsh.res = LittleEndianW(xmsh.res); @@ -473,8 +473,8 @@ { pIns->VolEnv.Ticks[ienv] = (WORD)xmsh.venv[ienv*2]; pIns->VolEnv.Values[ienv] = (BYTE)xmsh.venv[ienv*2+1]; - pIns->PanEnv.Ticks[ienv] = (WORD)xmsh.pIns[ienv*2]; - pIns->PanEnv.Values[ienv] = (BYTE)xmsh.pIns[ienv*2+1]; + pIns->PanEnv.Ticks[ienv] = (WORD)xmsh.penv[ienv*2]; + pIns->PanEnv.Values[ienv] = (BYTE)xmsh.penv[ienv*2+1]; if (ienv) { if (pIns->VolEnv.Ticks[ienv] < pIns->VolEnv.Ticks[ienv-1]) @@ -871,8 +871,8 @@ { xmsh.venv[ienv*2] = pIns->VolEnv.Ticks[ienv]; xmsh.venv[ienv*2+1] = pIns->VolEnv.Values[ienv]; - xmsh.pIns[ienv*2] = pIns->PanEnv.Ticks[ienv]; - xmsh.pIns[ienv*2+1] = pIns->PanEnv.Values[ienv]; + xmsh.penv[ienv*2] = pIns->PanEnv.Ticks[ienv]; + xmsh.penv[ienv*2+1] = pIns->PanEnv.Values[ienv]; } if (pIns->dwFlags & ENV_VOLUME) xmsh.vtype |= 1; if (pIns->dwFlags & ENV_VOLSUSTAIN) xmsh.vtype |= 2; Modified: trunk/OpenMPT/soundlib/Snd_defs.h =================================================================== --- trunk/OpenMPT/soundlib/Snd_defs.h 2009-09-07 20:24:18 UTC (rev 356) +++ trunk/OpenMPT/soundlib/Snd_defs.h 2009-09-09 22:43:27 UTC (rev 357) @@ -71,7 +71,7 @@ #define MAX_BASECHANNELS 127 // Max pattern channels. //#endif // -! BEHAVIOUR_CHANGE#0006 -#define MAX_ENVPOINTS 32 +#define MAX_ENVPOINTS 240 #define MIN_PERIOD 0x0020 #define MAX_PERIOD 0xFFFF #define MAX_PATTERNNAME 32 Modified: trunk/OpenMPT/soundlib/mod_specifications.h =================================================================== --- trunk/OpenMPT/soundlib/mod_specifications.h 2009-09-07 20:24:18 UTC (rev 356) +++ trunk/OpenMPT/soundlib/mod_specifications.h 2009-09-09 22:43:27 UTC (rev 357) @@ -36,6 +36,7 @@ UINT speedMin; UINT speedMax; bool hasComments; + int envelopePointsMax; }; @@ -71,6 +72,7 @@ 1, //Min Speed 255, //Max Speed true, //Has song comments + 240, //Envelope point count }; @@ -101,6 +103,7 @@ 1, //Min Speed 31, //Max Speed false, //No song comments + 0, //Envelope point count }; // MOD with MPT extensions. @@ -129,6 +132,7 @@ 1, //Min Speed 31, //Max Speed false, //No song comments + 0, //Envelope point count }; const CModSpecifications xm = @@ -156,6 +160,7 @@ 1, //Min Speed 31, //Max Speed false, //No song comments + 12, //Envelope point count }; // XM with MPT extensions @@ -184,6 +189,7 @@ 1, //Min Speed 31, //Max Speed true, //Has song comments + 12, //Envelope point count }; const CModSpecifications s3m = @@ -210,6 +216,7 @@ 1, //Min Speed 255, //Max Speed false, //No song comments + 0, //Envelope point count }; // S3M with MPT extensions @@ -238,6 +245,7 @@ 1, //Min Speed 255, //Max Speed false, //No song comments + 0, //Envelope point count }; const CModSpecifications it = @@ -265,6 +273,7 @@ 1, //Min Speed 255, //Max Speed true, //Has song comments + 25, //Envelope point count }; const CModSpecifications itEx = @@ -292,6 +301,7 @@ 1, //Min Speed 255, //Max Speed true, //Has song comments + 25, //Envelope point count }; } //namespace ModSpecs This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-09-10 21:01:07
|
Revision: 360 http://modplug.svn.sourceforge.net/modplug/?rev=360&view=rev Author: saga-games Date: 2009-09-10 21:00:57 +0000 (Thu, 10 Sep 2009) Log Message: ----------- [Fix] Instrument Tab: Proper limits for IT/XM fadeout values [Fix] XM / IT Saver: Limit fadeout values properly [Imp] IT Compatibility Export: Removed stereo sample support [Imp] Updated DE_jojo.mkb keymap (added Save As command) [Imp] Updated IT Mod Specifications [Imp] Comments tab: Usage of existing sample size + bit depth functions to calculate information [Imp] XM Loader: Advanced "made with MPT" detection Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/view_com.cpp trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/mod_specifications.h Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-09-10 13:31:37 UTC (rev 359) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-09-10 21:00:57 UTC (rev 360) @@ -801,7 +801,7 @@ m_ComboDCA.AddString("Note Off"); m_ComboDCA.AddString("Note Fade"); // FadeOut Volume - m_SpinFadeOut.SetRange(0, 32000); + m_SpinFadeOut.SetRange(0, 8192); // Global Volume m_SpinGlobalVol.SetRange(0, 64); // Panning @@ -1072,7 +1072,13 @@ m_SpinMidiPR.EnableWindow(bITandXM); m_SpinMidiBK.EnableWindow(bITandXM); //rewbs.MidiBank //end rewbs.instroVSTi + m_SpinFadeOut.EnableWindow(bITandXM); + if(m_pSndFile->m_nType & MOD_TYPE_XM) + m_SpinFadeOut.SetRange(0, 4095); + else + m_SpinFadeOut.SetRange(0, 8192); + m_NoteMap.EnableWindow(bITandXM); m_CbnResampling.EnableWindow(bITandXM); Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-10 13:31:37 UTC (rev 359) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-10 21:00:57 UTC (rev 360) @@ -768,7 +768,7 @@ //------------------------------------------------------- { // shorten instrument envelope if necessary (for mod conversion) - const int iEnvMax = m_SndFile.GetModSpecifications().envelopePointsMax; + const UINT iEnvMax = m_SndFile.GetModSpecifications().envelopePointsMax; bool bResult = false; #define TRIMENV(i) if(i > iEnvMax) {i = iEnvMax; bResult = true;} Modified: trunk/OpenMPT/mptrack/view_com.cpp =================================================================== --- trunk/OpenMPT/mptrack/view_com.cpp 2009-09-10 13:31:37 UTC (rev 359) +++ trunk/OpenMPT/mptrack/view_com.cpp 2009-09-10 21:00:57 UTC (rev 360) @@ -252,15 +252,13 @@ case SMPLIST_SIZE: if (pSmp->nLength) { - UINT nShift = (pSmp->uFlags & CHN_16BIT) ? 9 : 10; - if (pSmp->uFlags & CHN_STEREO) nShift--; - wsprintf(s, "%d KB", pSmp->nLength >> nShift); + wsprintf(s, "%d KB", pSmp->GetSampleSizeInBytes() >> 10); } break; case SMPLIST_TYPE: if (pSmp->nLength) { - strcpy(s, (pSmp->uFlags & CHN_16BIT) ? "16 Bit" : "8 Bit"); + wsprintf(s, "%d Bit", pSmp->GetElementarySampleSize() << 3); } break; case SMPLIST_INSTR: Modified: trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb =================================================================== --- trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-09-10 13:31:37 UTC (rev 359) +++ trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-09-10 21:00:57 UTC (rev 360) @@ -8,6 +8,7 @@ 0:1346:2:79:1 //File/Open: Ctrl+O (KeyDown) 0:1348:2:87:5 //File/Close: Ctrl+W (KeyDown|KeyHold) 0:1349:2:83:1 //File/Save: Ctrl+S (KeyDown) +0:1350:3:83:1 //File/Save As: Shift+Ctrl+S (KeyDown) 0:1693:0:166:1 //Previous Document: (KeyDown) 0:1694:0:167:1 //Next Document: (KeyDown) 0:1030:0:116:1 //Play song/Pause song: F5 (KeyDown) Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-10 13:31:37 UTC (rev 359) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-10 21:00:57 UTC (rev 360) @@ -301,7 +301,7 @@ } if (pis->mbank<=128) pIns->wMidiBank = pis->mbank; - pIns->nFadeOut = pis->fadeout << 5; // should be 6? + pIns->nFadeOut = pis->fadeout << 5; pIns->nGlobalVol = pis->gbv >> 1; if (pIns->nGlobalVol > 64) pIns->nGlobalVol = 64; for (UINT j = 0; j < 120; j++) @@ -2003,7 +2003,7 @@ //if (pIns->nDCT<DCT_PLUGIN) iti.dct = pIns->nDCT; else iti.dct =0; iti.dct = pIns->nDCT; //rewbs.instroVSTi: will other apps barf if they get an unknown DCT? iti.dca = pIns->nDNA; - iti.fadeout = pIns->nFadeOut >> 5; // should be 6? + iti.fadeout = min(pIns->nFadeOut >> 5 , 256); iti.pps = pIns->nPPS; iti.ppc = pIns->nPPC; iti.gbv = (BYTE)(pIns->nGlobalVol << 1); @@ -2648,7 +2648,7 @@ iti.nna = pIns->nNNA; if (pIns->nDCT<DCT_PLUGIN) iti.dct = pIns->nDCT; else iti.dct =0; iti.dca = pIns->nDNA; - iti.fadeout = pIns->nFadeOut >> 5; + iti.fadeout = min(pIns->nFadeOut >> 5 , 256); iti.pps = pIns->nPPS; iti.ppc = pIns->nPPC; iti.gbv = (BYTE)(pIns->nGlobalVol << 1); @@ -2991,30 +2991,10 @@ if (psmp->uFlags & CHN_PANNING) itss.dfp |= 0x80; if ((psmp->pSample) && (psmp->nLength)) itss.cvt = 0x01; UINT flags = RS_PCM8S; - /* -#ifndef NO_PACKING - if (nPacking) + if (psmp->uFlags & CHN_16BIT) { - if ((!(psmp->uFlags & (CHN_16BIT|CHN_STEREO))) - && (CanPackSample(psmp->pSample, psmp->nLength, nPacking))) - { - flags = RS_ADPCM4; - itss.cvt = 0xFF; - } - } else -#endif // NO_PACKING - */ - { - if (psmp->uFlags & CHN_STEREO) - { - flags = RS_STPCM8S; - itss.flags |= 0x04; - } - if (psmp->uFlags & CHN_16BIT) - { - itss.flags |= 0x02; - flags = (psmp->uFlags & CHN_STEREO) ? RS_STPCM16S : RS_PCM16S; - } + itss.flags |= 0x02; + flags = RS_PCM16S; } itss.samplepointer = dwPos; fseek(f, smppos[nsmp-1], SEEK_SET); Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-09-10 13:31:37 UTC (rev 359) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-09-10 21:00:57 UTC (rev 360) @@ -119,22 +119,6 @@ if ((!channels) || (channels > MAX_BASECHANNELS)) return false; // -! BEHAVIOUR_CHANGE#0006 - if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true; - if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v 2.00 ", 20)) - { - bMadeWithModPlug = true; - m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 00, 00, 00); - } - - if (!memcmp((LPCSTR)lpStream + 0x26, "OpenMPT ", 8)) - { - //bMadeWithModPlug = true; // Don't set it - it's also used by compatibility export - CHAR sVersion[13]; - memcpy(sVersion, lpStream + 0x26 + 8, 12); - sVersion[12] = 0; - m_dwLastSavedWithVersion = MptVersion::ToNum(sVersion); - } - m_nType = MOD_TYPE_XM; m_nMinPeriod = 27; m_nMaxPeriod = 54784; @@ -334,7 +318,10 @@ Instruments[iIns]->nPluginVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE; memcpy(Instruments[iIns]->name, pih->name, 22); - + // look for null-terminated instr name - that's most likely a tune made with modplug + for(int i = 0; i < 22; i++) + if(pih->name[i] == 0) bProbablyMadeWithModPlug = true; + if ((nsamples = pih->samples) > 0) { /* we have samples, so let's read the rest of this instrument @@ -560,6 +547,9 @@ pSmp->nVibRate = xmsh.vibrate; memcpy(pSmp->filename, xmss.name, 22); pSmp->filename[21] = 0; + // look for null-terminated sample name - that's most likely a tune made with modplug + for(int i = 0; i < 22; i++) + if(xmss.name[i] == 0) bProbablyMadeWithModPlug = true; } #if 0 if ((xmsh.reserved2 > nsamples) && (xmsh.reserved2 <= 16)) @@ -648,6 +638,25 @@ bMadeWithModPlug = true; } + // Check various things to find out whether this has been made with MPT. + // Null chars in names -> most likely made with MPT, which disguises as FT2 + if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true; + if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v 2.00 ", 20)) + { + // Early MPT 1.0 alpha/beta versions + bMadeWithModPlug = true; + m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 00, 00, 00); + } + + if (!memcmp((LPCSTR)lpStream + 0x26, "OpenMPT ", 8)) + { + //bMadeWithModPlug = true; // Don't set it - it's also used by compatibility export + CHAR sVersion[13]; + memcpy(sVersion, lpStream + 0x26 + 8, 12); + sVersion[12] = 0; + m_dwLastSavedWithVersion = MptVersion::ToNum(sVersion); + } + if(bMadeWithModPlug) { SetModFlag(MSF_COMPATIBLE_PLAY, false); @@ -862,7 +871,7 @@ { memcpy(xmih.name, pIns->name, 22); xmih.type = pIns->nMidiProgram; - xmsh.volfade = pIns->nFadeOut; + xmsh.volfade = min(pIns->nFadeOut, 0xFFF); // FFF is maximum in FT2 xmsh.vnum = (BYTE)pIns->VolEnv.nNodes; xmsh.pnum = (BYTE)pIns->PanEnv.nNodes; if (xmsh.vnum > 12) xmsh.vnum = 12; Modified: trunk/OpenMPT/soundlib/mod_specifications.h =================================================================== --- trunk/OpenMPT/soundlib/mod_specifications.h 2009-09-10 13:31:37 UTC (rev 359) +++ trunk/OpenMPT/soundlib/mod_specifications.h 2009-09-10 21:00:57 UTC (rev 360) @@ -33,10 +33,10 @@ INSTRUMENTINDEX instrumentsMax; BYTE defaultMixLevels; BYTE MIDIMappingDirectivesMax; - UINT speedMin; - UINT speedMax; - bool hasComments; - int envelopePointsMax; + UINT speedMin; // Minimum ticks per frame + UINT speedMax; // Maximum ticks per frame + bool hasComments; // True if format has a comments field + UINT envelopePointsMax; // Maximum number of points of each envelope }; @@ -103,7 +103,7 @@ 1, //Min Speed 31, //Max Speed false, //No song comments - 0, //Envelope point count + 0, //No instrument envelopes }; // MOD with MPT extensions. @@ -132,7 +132,7 @@ 1, //Min Speed 31, //Max Speed false, //No song comments - 0, //Envelope point count + 0, //No instrument envelopes }; const CModSpecifications xm = @@ -216,7 +216,7 @@ 1, //Min Speed 255, //Max Speed false, //No song comments - 0, //Envelope point count + 0, //No instrument envelopes }; // S3M with MPT extensions @@ -245,7 +245,7 @@ 1, //Min Speed 255, //Max Speed false, //No song comments - 0, //Envelope point count + 0, //No instrument envelopes }; const CModSpecifications it = @@ -266,8 +266,8 @@ 1, //Min pattern rows 256, //Max pattern rows 25, //Max mod name length - 256, //SamplesMax - 200, //instrumentMax + 99, //SamplesMax + 99, //instrumentMax mixLevels_original, //defaultMixLevels 0, //Max MIDI mapping directives 1, //Min Speed This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-09-11 19:33:12
|
Revision: 361 http://modplug.svn.sourceforge.net/modplug/?rev=361&view=rev Author: saga-games Date: 2009-09-11 19:32:52 +0000 (Fri, 11 Sep 2009) Log Message: ----------- [Fix] MPTM Saving: Save Note Fade (~~) properly [Fix] Mod Conversion: Unset release nodes were corrupted when converting modules Modified Paths: -------------- trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/soundlib/Load_it.cpp Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-10 21:00:57 UTC (rev 360) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-11 19:32:52 UTC (rev 361) @@ -778,7 +778,7 @@ TRIMENV(mptEnv->nLoopEnd); TRIMENV(mptEnv->nSustainStart); TRIMENV(mptEnv->nSustainEnd); - TRIMENV(mptEnv->nReleaseNode); + if(mptEnv->nReleaseNode != ENV_RELEASE_NODE_UNSET) TRIMENV(mptEnv->nReleaseNode); #undef TRIMENV Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-10 21:00:57 UTC (rev 360) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-11 19:32:52 UTC (rev 361) @@ -2190,7 +2190,7 @@ UINT note = m->note; if (note) b |= 1; if ((note) && (note < NOTE_MIN_SPECIAL)) note--; - if (note == NOTE_FADE) note = 0xF6; + if (note == NOTE_FADE && GetType() != MOD_TYPE_MPT) note = 0xF6; if (m->instr) b |= 2; if (m->volcmd) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-09-13 13:44:34
|
Revision: 362 http://modplug.svn.sourceforge.net/modplug/?rev=362&view=rev Author: saga-games Date: 2009-09-13 13:44:24 +0000 (Sun, 13 Sep 2009) Log Message: ----------- [Fix] XM Compatibility: Portamento + New Note with no previous note (tentative fix), Offset beyond sample range [Fix] IT Compatibility: Offset beyond sample range [Ref] Replaced some NULLs and BOOL variables by nullptrs and bools Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Snd_flt.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-11 19:32:52 UTC (rev 361) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-13 13:44:24 UTC (rev 362) @@ -849,7 +849,7 @@ else if ((nsmp) && (nsmp < MAX_SAMPLES)) { //Or set sample MODSAMPLE *pSmp = &m_SndFile.Samples[nsmp]; pChn->pCurrentSample = pSmp->pSample; - pChn->pModInstrument = NULL; + pChn->pModInstrument = nullptr; pChn->pModSample = pSmp; pChn->pSample = pSmp->pSample; pChn->nFineTune = pSmp->nFineTune; @@ -864,13 +864,13 @@ pChn->nFadeOutVol = 0x10000; } - m_SndFile.NoteChange(nChn, note, FALSE, TRUE, TRUE); + m_SndFile.NoteChange(nChn, note, false, true, true); if (nVol >= 0) pChn->nVolume = nVol; // handle sample looping. // Fix: Bug report 1700. //if ((loopstart + 16 < loopend) && (loopstart >= 0) && (loopend <= (LONG)pChn->nLength)) { - if ((loopstart + 16 < loopend) && (loopstart >= 0) && (pChn->pModSample != 0)) + if ((loopstart + 16 < loopend) && (loopstart >= 0) && (pChn->pModSample != nullptr)) { pChn->nPos = loopstart; pChn->nPosLo = 0; Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-11 19:32:52 UTC (rev 361) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-13 13:44:24 UTC (rev 362) @@ -142,7 +142,7 @@ // Removing all instrument headers for (UINT i1=0; i1<MAX_CHANNELS; i1++) { - m_SndFile.Chn[i1].pModInstrument = NULL; + m_SndFile.Chn[i1].pModInstrument = nullptr; } for (UINT i2=0; i2<m_SndFile.m_nInstruments; i2++) if (m_SndFile.Instruments[i2]) { Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2009-09-11 19:32:52 UTC (rev 361) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2009-09-13 13:44:24 UTC (rev 362) @@ -126,7 +126,7 @@ { if (Chn[i].pModInstrument == pIns) { - Chn[i].pModInstrument = NULL; + Chn[i].pModInstrument = nullptr; } } delete pIns; @@ -450,7 +450,7 @@ if (pSmp->pSample) { FreeSample(pSmp->pSample); - pSmp->pSample = NULL; + pSmp->pSample = nullptr; pSmp->nLength = 0; } pSmp->nLength = pdata->length / samplesize; @@ -1620,7 +1620,7 @@ if (pSmp->pSample) { FreeSample(pSmp->pSample); - pSmp->pSample = NULL; + pSmp->pSample = nullptr; pSmp->nLength = 0; } pSmp->nLength = dwSSNDLen / samplesize; Modified: trunk/OpenMPT/soundlib/Snd_flt.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_flt.cpp 2009-09-11 19:32:52 UTC (rev 361) +++ trunk/OpenMPT/soundlib/Snd_flt.cpp 2009-09-13 13:44:24 UTC (rev 362) @@ -70,7 +70,7 @@ // Simple 2-poles resonant filter -void CSoundFile::SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier) const +void CSoundFile::SetupChannelFilter(MODCHANNEL *pChn, bool bReset, int flt_modifier) const //---------------------------------------------------------------------------------------- { float fs = (float)gdwMixingFreq; Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-09-11 19:32:52 UTC (rev 361) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-09-13 13:44:24 UTC (rev 362) @@ -538,7 +538,7 @@ // Invalid sample ? if (!pSmp) { - pChn->pModSample = NULL; + pChn->pModSample = nullptr; pChn->nInsVol = 0; return; } @@ -612,7 +612,7 @@ } -void CSoundFile::NoteChange(UINT nChn, int note, BOOL bPorta, BOOL bResetEnv, BOOL bManual) +void CSoundFile::NoteChange(UINT nChn, int note, bool bPorta, bool bResetEnv, bool bManual) //----------------------------------------------------------------------------------------- { if (note < 1) return; @@ -677,6 +677,10 @@ // IT Compatibility: Update multisample instruments frequency even if instrument is not specified if(!bPorta && pSmp && IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nC5Speed = pSmp->nC5Speed; + // XM Compatibility: Ignore notes with portamento if there was no note + if(bPorta && (pChn->nPeriod == 0) && IsCompatibleMode(TRK_FASTTRACKER2)) + return; + if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2|MOD_TYPE_MED)) note += pChn->nTranspose; note = CLAMP(note, 1, 132); pChn->nNote = note; @@ -723,7 +727,7 @@ if (pChn->nPos >= pChn->nLength) pChn->nPos = pChn->nLoopStart; } else - bPorta = FALSE; + bPorta = false; if ((!bPorta) || (!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) || ((pChn->dwFlags & CHN_NOTEFADE) && (!pChn->nFadeOutVol)) @@ -804,12 +808,12 @@ pChn->nAutoVibPos = 0; } pChn->nLeftVol = pChn->nRightVol = 0; - BOOL bFlt = (m_dwSongFlags & SONG_MPTFILTERMODE) ? FALSE : TRUE; + bool bFlt = (m_dwSongFlags & SONG_MPTFILTERMODE) ? false : true; // Setup Initial Filter for this note if (pIns) { - if (pIns->nIFR & 0x80) { pChn->nResonance = pIns->nIFR & 0x7F; bFlt = TRUE; } - if (pIns->nIFC & 0x80) { pChn->nCutOff = pIns->nIFC & 0x7F; bFlt = TRUE; } + if (pIns->nIFR & 0x80) { pChn->nResonance = pIns->nIFR & 0x7F; bFlt = true; } + if (pIns->nIFC & 0x80) { pChn->nCutOff = pIns->nIFC & 0x7F; bFlt = true; } if (bFlt && (pIns->nFilterMode != FLTMODE_UNCHANGED)) { pChn->nFilterMode = pIns->nFilterMode; } @@ -819,7 +823,7 @@ pChn->nCutSwing = pChn->nResSwing = 0; } #ifndef NO_FILTER - if ((pChn->nCutOff < 0x7F) && (bFlt)) SetupChannelFilter(pChn, TRUE); + if ((pChn->nCutOff < 0x7F) && (bFlt)) SetupChannelFilter(pChn, true); #endif // NO_FILTER } // Special case for MPT @@ -913,7 +917,7 @@ note = pHeader->NoteMap[note-1]; if ((n) && (n < MAX_SAMPLES)) pSample = Samples[n].pSample; } - } else pSample = NULL; + } else pSample = nullptr; } MODCHANNEL *p = pChn; //if (!pIns) return; @@ -1337,7 +1341,7 @@ InstrumentChange(pChn, pChn->nNewIns, bPorta, FALSE, (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) ? FALSE : TRUE); pChn->nNewIns = 0; } - NoteChange(nChn, note, bPorta, (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) ? FALSE : TRUE); + NoteChange(nChn, note, bPorta, (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) ? false : true); if ((bPorta) && (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) && (instr)) { pChn->dwFlags |= CHN_FASTVOLRAMP; @@ -2780,7 +2784,7 @@ 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); + SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true); #endif // NO_FILTER } break; @@ -2794,7 +2798,7 @@ } #ifndef NO_FILTER - SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? FALSE : TRUE); + SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true); #endif // NO_FILTER break; @@ -2804,7 +2808,7 @@ { pChn->nFilterMode = (dwParam>>4); #ifndef NO_FILTER - SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? FALSE : TRUE); + SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true); #endif // NO_FILTER } break; @@ -2916,7 +2920,7 @@ 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); + SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true); #endif // NO_FILTER } break; @@ -2935,7 +2939,7 @@ 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); + SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true); #endif // NO_FILTER } @@ -2947,7 +2951,7 @@ { pChn->nFilterMode = (dwParam>>4); #ifndef NO_FILTER - SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? FALSE : TRUE); + SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true); #endif // NO_FILTER } break; @@ -3044,13 +3048,22 @@ pChn->nPos += param; if (pChn->nPos >= pChn->nLength) { + // Offset beyond sample size if (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))) { - pChn->nPos = pChn->nLoopStart; + if(IsCompatibleMode(TRK_IMPULSETRACKER)) + pChn->nPos = 0; // IT Compatibility: Reset to beginning of sample + else + pChn->nPos = pChn->nLoopStart; if ((m_dwSongFlags & SONG_ITOLDEFFECTS) && (pChn->nLength > 4)) { pChn->nPos = pChn->nLength - 2; } + } else if(IsCompatibleMode(TRK_FASTTRACKER2)) + { + // XM Compatibility: Don't play note + pChn->dwFlags |= CHN_FASTVOLRAMP; + pChn->nVolume = pChn->nPeriod = 0; } } } else @@ -3139,7 +3152,7 @@ if ((pChn->nRowInstr) && (param < 0x100)) { InstrumentChange(pChn, pChn->nRowInstr, FALSE, FALSE); bResetEnv = TRUE; } if (param < 0x100) bResetEnv = TRUE; } - NoteChange(nChn, nNote, FALSE, bResetEnv); + NoteChange(nChn, nNote, false, bResetEnv); if (m_nInstruments) { ProcessMidiOut(nChn, pChn); //Send retrig to Midi } Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-09-11 19:32:52 UTC (rev 361) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-09-13 13:44:24 UTC (rev 362) @@ -806,7 +806,7 @@ if (pSmp->pSample) { FreeSample(pSmp->pSample); - pSmp->pSample = NULL; + pSmp->pSample = nullptr; } } for (i=0; i<MAX_INSTRUMENTS; i++) @@ -1449,8 +1449,8 @@ if(resetMask & 2) { Chn[i].nNote = Chn[i].nNewNote = Chn[i].nNewIns = 0; - Chn[i].pModSample = NULL; - Chn[i].pModInstrument = NULL; + Chn[i].pModSample = nullptr; + Chn[i].pModInstrument = nullptr; Chn[i].nPortamentoDest = 0; Chn[i].nCommand = 0; Chn[i].nPatternLoopCount = 0; @@ -1473,9 +1473,9 @@ Chn[i].nLoopStart = 0; Chn[i].nLoopEnd = 0; Chn[i].nROfs = Chn[i].nLOfs = 0; - Chn[i].pSample = NULL; - Chn[i].pModSample = NULL; - Chn[i].pModInstrument = NULL; + Chn[i].pSample = nullptr; + Chn[i].pModSample = nullptr; + Chn[i].pModInstrument = nullptr; Chn[i].nCutOff = 0x7F; Chn[i].nResonance = 0; Chn[i].nFilterMode = 0; @@ -2001,7 +2001,7 @@ { pSmp->nLength = 0; FreeSample(pSmp->pSample); - pSmp->pSample = NULL; + pSmp->pSample = nullptr; MessageBox(0, str_SampleAllocationError, str_Error, MB_ICONERROR); return 0; } @@ -2438,7 +2438,7 @@ { pSmp->nLength = 0; FreeSample(pSmp->pSample); - pSmp->pSample = NULL; + pSmp->pSample = nullptr; } return 0; } @@ -2766,7 +2766,7 @@ if (!Samples[nSample].pSample) return TRUE; MODSAMPLE *pSmp = &Samples[nSample]; LPSTR pSample = pSmp->pSample; - pSmp->pSample = NULL; + pSmp->pSample = nullptr; pSmp->nLength = 0; pSmp->uFlags &= ~(CHN_16BIT); for (UINT i=0; i<MAX_CHANNELS; i++) Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-09-11 19:32:52 UTC (rev 361) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-09-13 13:44:24 UTC (rev 362) @@ -796,7 +796,7 @@ BOOL ProcessEffects(); UINT GetNNAChannel(UINT nChn) const; void CheckNNA(UINT nChn, UINT instr, int note, BOOL bForceCut); - void NoteChange(UINT nChn, int note, BOOL bPorta=FALSE, BOOL bResetEnv=TRUE, BOOL bManual=FALSE); + void NoteChange(UINT nChn, int note, bool bPorta = false, bool bResetEnv = true, bool bManual = false); void InstrumentChange(MODCHANNEL *pChn, UINT instr, BOOL bPorta=FALSE,BOOL bUpdVol=TRUE,BOOL bResetEnv=TRUE); // Channel Effects @@ -834,7 +834,7 @@ void ExtendedChannelEffect(MODCHANNEL *, UINT param); void ProcessMidiMacro(UINT nChn, LPCSTR pszMidiMacro, UINT param=0); void ProcessSmoothMidiMacro(UINT nChn, LPCSTR pszMidiMacro, UINT param=0); //rewbs.smoothVST - void SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier=256) const; + void SetupChannelFilter(MODCHANNEL *pChn, bool bReset, int flt_modifier = 256) const; // Low-Level effect processing void DoFreqSlide(MODCHANNEL *pChn, LONG nFreqSlide); void GlobalVolSlide(UINT param, UINT * nOldGlobalVolSlide); Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-09-11 19:32:52 UTC (rev 361) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-09-13 13:44:24 UTC (rev 362) @@ -698,9 +698,9 @@ Chn[i].dwFlags = ChnSettings[i].dwFlags; Chn[i].nLoopStart = 0; Chn[i].nLoopEnd = 0; - Chn[i].pModInstrument = NULL; - Chn[i].pSample = NULL; - Chn[i].pModSample = NULL; + Chn[i].pModInstrument = nullptr; + Chn[i].pSample = nullptr; + Chn[i].pModSample = nullptr; } } } @@ -1302,7 +1302,7 @@ if (pIns->dwFlags & ENV_FILTER) { #ifndef NO_FILTER - SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? FALSE : TRUE, envpitch); + SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true, envpitch); #endif // NO_FILTER } else // Pitch Envelope This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-09-15 17:15:39
|
Revision: 364 http://modplug.svn.sourceforge.net/modplug/?rev=364&view=rev Author: saga-games Date: 2009-09-15 17:15:29 +0000 (Tue, 15 Sep 2009) Log Message: ----------- [Fix] Wave Export: Order mode was always enabled by default. [Fix] IT Compatibility: Special case of Retrigger + Envelopes [Fix] Instrument / Sample tab: Remove special chars from sample filenames so the "save as" dialog will show up on OSs < Vista [Mod] Instrument tab: Also show values from 0 to 64 for filter envelope (instead of -32 to 32) [Imp] Macro Config: Also show the current preset for Zxx config (Z80 - ZFF) [Ref] Changed some BOOLs into bools, usage of *INDEX types Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/misc_util.h trunk/OpenMPT/mptrack/mod2midi.cpp trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-09-13 20:41:27 UTC (rev 363) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-09-15 17:15:29 UTC (rev 364) @@ -1603,7 +1603,7 @@ void CCtrlInstruments::OnInstrumentSave() //--------------------------------------- { - CHAR szFileName[_MAX_PATH] = "", drive[_MAX_DRIVE], path[_MAX_PATH], ext[_MAX_EXT]; + TCHAR szFileName[_MAX_PATH] = "", drive[_MAX_DRIVE], path[_MAX_PATH], ext[_MAX_EXT]; MODINSTRUMENT *pIns = m_pSndFile->Instruments[m_nInstrument]; if (!pIns) return; @@ -1616,6 +1616,8 @@ memcpy(szFileName, pIns->name, 22); szFileName[22] = 0; } + SanitizeFilename(szFileName); + // -> CODE#0019 // -> DESC="correctly load ITI & XI instruments sample note map" // CFileDialog dlg(FALSE, (m_pSndFile->m_nType & MOD_TYPE_IT) ? "iti" : "xi", Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-09-13 20:41:27 UTC (rev 363) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-09-15 17:15:29 UTC (rev 364) @@ -975,8 +975,8 @@ { if(!m_pSndFile) return; - CHAR szFileName[_MAX_PATH] = ""; - BOOL bBatchSave = CMainFrame::GetInputHandler()->ShiftPressed(); + TCHAR szFileName[_MAX_PATH]; + bool bBatchSave = CMainFrame::GetInputHandler()->ShiftPressed(); if(!bBatchSave) { @@ -993,8 +993,7 @@ } else { memcpy(szFileName, m_pSndFile->m_szNames[m_nSample], 32); - szFileName[32] = 0; - } + szFileName[32] = 0; } if (!szFileName[0]) strcpy(szFileName, "untitled"); } else @@ -1011,6 +1010,7 @@ sPath += ".wav"; _splitpath(sPath, NULL, NULL, szFileName, NULL); } + SanitizeFilename(szFileName); CFileDialog dlg(FALSE, "wav", szFileName, @@ -1027,7 +1027,7 @@ TCHAR ext[_MAX_EXT]; _splitpath(dlg.GetPathName(), NULL, NULL, NULL, ext); - BOOL bOk = FALSE; + bool bOk = false; UINT iMinSmp = m_nSample, iMaxSmp = m_nSample; CString sFilename = dlg.GetPathName(), sNumberFormat; if(bBatchSave) @@ -1037,24 +1037,20 @@ sNumberFormat.Format("%s%d%s", "%.", ((int)log10((float)iMaxSmp)) + 1, "d"); } - const CString sForbiddenChars = "\\/:\"?<>*"; - for(UINT iSmp = iMinSmp; iSmp <= iMaxSmp; iSmp++) { if (m_pSndFile->Samples[iSmp].pSample) { if(bBatchSave) { - CString sSampleNumber, sSampleName, sSampleFilename; + CString sSampleNumber; + TCHAR sSampleName[64], sSampleFilename[64]; sSampleNumber.Format(sNumberFormat, iSmp); - sSampleName = (m_pSndFile->m_szNames[iSmp]) ? m_pSndFile->m_szNames[iSmp] : "untitled"; - sSampleFilename = (m_pSndFile->Samples[iSmp].filename[0]) ? m_pSndFile->Samples[iSmp].filename : m_pSndFile->m_szNames[iSmp]; - for(UINT i = 0; i < sForbiddenChars.GetLength(); i++) - { - sSampleName.Remove(sForbiddenChars.GetAt(i)); - sSampleFilename.Remove(sForbiddenChars.GetAt(i)); - } + strcpy(sSampleName, (m_pSndFile->m_szNames[iSmp]) ? m_pSndFile->m_szNames[iSmp] : "untitled"); + strcpy(sSampleFilename, (m_pSndFile->Samples[iSmp].filename[0]) ? m_pSndFile->Samples[iSmp].filename : m_pSndFile->m_szNames[iSmp]); + SanitizeFilename(sSampleName); + SanitizeFilename(sSampleFilename); sFilename = dlg.GetPathName(); sFilename.Replace("%sample_number%", sSampleNumber); Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-13 20:41:27 UTC (rev 363) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-15 17:15:29 UTC (rev 364) @@ -1388,7 +1388,7 @@ void CModDoc::OnFileWaveConvert() //------------------------------- { - OnFileWaveConvert(0, 0); + OnFileWaveConvert(ORDERINDEX_INVALID, ORDERINDEX_INVALID); } void CModDoc::OnFileWaveConvert(ORDERINDEX nMinOrder, ORDERINDEX nMaxOrder) @@ -2935,7 +2935,7 @@ } HWND CModDoc::GetEditPosition(ROWINDEX &row, PATTERNINDEX &pat, ORDERINDEX &ord) -//------------------------------------------------------------ +//------------------------------------------------------------------------------ { HWND followSonghWnd; PATTERNVIEWSTATE *patternViewState; @@ -2976,7 +2976,7 @@ //ensure order correlates with pattern. if (pSndFile->Order[ord]!=pat) { - int tentativeOrder = pSndFile->FindOrder(pat); + ORDERINDEX tentativeOrder = pSndFile->FindOrder(pat); if (tentativeOrder != -1) { //ensure a valid order exists. ord = tentativeOrder; } @@ -3041,7 +3041,68 @@ return -1; } +// Retrieve Zxx (Z80-ZFF) type from current macro configuration +int CModDoc::GetZxxType(const CHAR (&szMidiZXXExt)[128 * 32]) +//----------------------------------------------------------- +{ + // Compare with all possible preset patterns + for(int i = 1; i <= 5; i++) + { + // Prepare pattern to compare + CHAR szPatterns[128 * 32]; + CreateZxxFromType(szPatterns, i); + bool bFound = true; + for(int j = 0; j < 128; j++) + { + if(strncmp(&szPatterns[j * 32], &szMidiZXXExt[j * 32], 32)) + bFound = false; + } + if(bFound) return i; + } + return 0; // Type 0 - Custom setup +} + +// Create Zxx (Z80 - ZFF) from one out of five presets +void CModDoc::CreateZxxFromType(CHAR (&szMidiZXXExt)[128 * 32], int iZxxType) +//--------------------------------------------------------------------------- +{ + for(int i = 0; i < 128; i++) + { + switch(iZxxType) + { + case 1: + // Type 1 - Z80 - Z8F controls resonance + if (i < 16) wsprintf(&szMidiZXXExt[i * 32], "F0F001%02X", i * 8); + else szMidiZXXExt[i * 32] = 0; + break; + + case 2: + // Type 2 - Z80 - ZFF controls resonance + wsprintf(&szMidiZXXExt[i * 32], "F0F001%02X", i); + break; + + case 3: + // Type 3 - Z80 - ZFF controls cutoff + wsprintf(&szMidiZXXExt[i * 32], "F0F000%02X", i); + break; + + case 4: + // Type 4 - Z80 - ZFF controls filter mode + wsprintf(&szMidiZXXExt[i * 32], "F0F002%02X", i); + break; + + case 5: + // Type 5 - Z80 - Z9F controls resonance + filter mode + if (i < 16) wsprintf(&szMidiZXXExt[i * 32], "F0F001%02X", i * 8); + else if (i < 32) wsprintf(&szMidiZXXExt[i * 32], "F0F002%02X", (i - 16) * 8); + else szMidiZXXExt[i * 32] = 0; + break; + } + } +} + + //////////////////////////////////////////////////////////////////////////////////////// // Playback Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-09-13 20:41:27 UTC (rev 363) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-09-15 17:15:29 UTC (rev 364) @@ -181,6 +181,8 @@ int MacroToPlugParam(CString value); //rewbs.xinfo int MacroToMidiCC(CString value); int FindMacroForParam(long param); + int GetZxxType(const CHAR (&szMidiZXXExt)[128 * 32]); + void CreateZxxFromType(CHAR (&szMidiZXXExt)[128 * 32], int iZxxType); void SongProperties(); // operations public: Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-13 20:41:27 UTC (rev 363) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-15 17:15:29 UTC (rev 364) @@ -1433,7 +1433,7 @@ } } - for (UINT i=1; i<=m_SndFile.m_nInstruments; i++) + for (INSTRUMENTINDEX i = 1; i <= m_SndFile.m_nInstruments; i++) { m_SndFile.DestroyInstrument(i,removeSamples); } @@ -1453,7 +1453,7 @@ CHAR s[512]; UINT nRemoved = 0; UINT nSwap, nIndex; - BOOL bReorg = FALSE; + bool bReorg = false; if (!m_SndFile.m_nInstruments) return FALSE; @@ -1469,7 +1469,7 @@ BeginWaitCursor(); memset(usedmap, 0, sizeof(usedmap)); - for (UINT i=m_SndFile.m_nInstruments; i>=1; i--) + for(INSTRUMENTINDEX i = m_SndFile.m_nInstruments; i >= 1; i--) { if (!m_SndFile.IsInstrumentUsed(i)) { @@ -1477,9 +1477,9 @@ // -> CODE#0003 // -> DESC="remove instrument's samples" // m_SndFile.DestroyInstrument(i); - m_SndFile.DestroyInstrument(i,removeSamples); + m_SndFile.DestroyInstrument(i, removeSamples); // -! BEHAVIOUR_CHANGE#0003 - if ((i == m_SndFile.m_nInstruments) && (i>1)) m_SndFile.m_nInstruments--; else bReorg = TRUE; + if ((i == m_SndFile.m_nInstruments) && (i>1)) m_SndFile.m_nInstruments--; else bReorg = true; END_CRITICAL(); nRemoved++; } else @@ -1701,8 +1701,8 @@ SAMPLEINDEX CModDoc::InsertSample(bool bLimit) //-------------------------------------------- { - UINT i = 1; - for (i=1; i<=m_SndFile.m_nSamples; i++) + SAMPLEINDEX i = 1; + for(i = 1; i <= m_SndFile.m_nSamples; i++) { if ((!m_SndFile.m_szNames[i][0]) && (m_SndFile.Samples[i].pSample == NULL)) { @@ -1802,7 +1802,7 @@ } else if (!pDup) { - for (UINT k=1; k<=m_SndFile.m_nSamples; k++) + for(SAMPLEINDEX k = 1; k <= m_SndFile.m_nSamples; k++) { if (!m_SndFile.IsSampleUsed(k)) { Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2009-09-13 20:41:27 UTC (rev 363) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-09-15 17:15:29 UTC (rev 364) @@ -1614,6 +1614,11 @@ //------------------------------------------------ { CModDoc *pModDoc = GetDocument(); + if(pModDoc == nullptr) return; + CSoundFile *pSndFile = pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return; + MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; + BOOL bSplitCursor = FALSE; CHAR s[256]; @@ -1632,7 +1637,7 @@ if (nVal > 64) nVal = 64; if (nTick < 0) nTick = 0; if (nTick <= EnvGetReleaseNodeTick() + 1 || EnvGetReleaseNode() == ENV_RELEASE_NODE_UNSET) { - int displayVal = (m_nEnv != ENV_VOLUME) ? nVal-32 : nVal; + int displayVal = (m_nEnv != ENV_VOLUME && !(m_nEnv == ENV_PITCH && (pIns->dwFlags & ENV_FILTER))) ? nVal - 32 : nVal; wsprintf(s, "Tick %d, [%d]", nTick, displayVal); } else { int displayVal = (nVal - EnvGetReleaseNodeValue()) * 2; Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-13 20:41:27 UTC (rev 363) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-15 17:15:29 UTC (rev 364) @@ -3542,15 +3542,15 @@ case kcNextPattern: { UINT n = m_nPattern + 1; while ((n < pSndFile->Patterns.Size()) && (!pSndFile->Patterns[n])) n++; SetCurrentPattern((n < pSndFile->Patterns.Size()) ? n : 0); - int currentOrder = SendCtrlMessage(CTRLMSG_GETCURRENTORDER); - int newOrder = pSndFile->FindOrder(m_nPattern, currentOrder, true); + ORDERINDEX currentOrder = SendCtrlMessage(CTRLMSG_GETCURRENTORDER); + ORDERINDEX newOrder = pSndFile->FindOrder(m_nPattern, currentOrder, true); SendCtrlMessage(CTRLMSG_SETCURRENTORDER, newOrder); return wParam; } case kcPrevPattern: { UINT n = (m_nPattern) ? m_nPattern - 1 : pSndFile->Patterns.Size()-1; while ((n > 0) && (!pSndFile->Patterns[n])) n--; SetCurrentPattern(n); - int currentOrder = SendCtrlMessage(CTRLMSG_GETCURRENTORDER); - int newOrder = pSndFile->FindOrder(m_nPattern, currentOrder, false); + ORDERINDEX currentOrder = SendCtrlMessage(CTRLMSG_GETCURRENTORDER); + ORDERINDEX newOrder = pSndFile->FindOrder(m_nPattern, currentOrder, false); SendCtrlMessage(CTRLMSG_SETCURRENTORDER, newOrder); return wParam; } case kcSelectWithCopySelect: Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-09-13 20:41:27 UTC (rev 363) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-09-15 17:15:29 UTC (rev 364) @@ -1799,6 +1799,11 @@ BOOL CMidiMacroSetup::OnInitDialog() //---------------------------------- { + m_pModDoc = CMainFrame::GetMainFrame()->GetActiveDoc(); + if (m_pModDoc) m_pSndFile = CMainFrame::GetMainFrame()->GetActiveDoc()->GetSoundFile(); + if (!m_pSndFile) + return FALSE; + CHAR s[128]; CDialog::OnInitDialog(); CheckDlgButton(IDC_CHECK1, m_bEmbed); @@ -1837,7 +1842,7 @@ m_CbnZxxPreset.AddString("Z80-ZFF controls cutoff"); m_CbnZxxPreset.AddString("Z80-ZFF controls filter mode"); m_CbnZxxPreset.AddString("Z80-Z9F controls resonance+mode"); - m_CbnZxxPreset.SetCurSel(0); + m_CbnZxxPreset.SetCurSel(m_pModDoc->GetZxxType(m_MidiCfg.szMidiZXXExt)); UpdateDialog(); int offsetx=108, offsety=30, separatorx=4, separatory=2, @@ -1863,10 +1868,6 @@ } UpdateMacroList(); - m_pModDoc = CMainFrame::GetMainFrame()->GetActiveDoc(); - if (m_pModDoc) m_pSndFile = CMainFrame::GetMainFrame()->GetActiveDoc()->GetSoundFile(); - if (!m_pSndFile) - return FALSE; for (UINT plug=0; plug<MAX_MIXPLUGINS; plug++) { PSNDMIXPLUGIN p = &(m_pSndFile->m_MixPlugins[plug]); @@ -2034,39 +2035,10 @@ { UINT zxx_preset = m_CbnZxxPreset.GetCurSel(); - if (zxx_preset) + if (zxx_preset && m_pModDoc != nullptr) { - BeginWaitCursor(); - for (UINT i=0; i<128; i++) - { - switch(zxx_preset) - { - case 1: - if (i<16) wsprintf(&m_MidiCfg.szMidiZXXExt[i*32], "F0F001%02X", i*8); - else m_MidiCfg.szMidiZXXExt[i*32] = 0; - break; - - case 2: - wsprintf(&m_MidiCfg.szMidiZXXExt[i*32], "F0F001%02X", i); - break; - - case 3: - wsprintf(&m_MidiCfg.szMidiZXXExt[i*32], "F0F000%02X", i); - break; - - case 4: - wsprintf(&m_MidiCfg.szMidiZXXExt[i*32], "F0F002%02X", i); - break; - - case 5: - if (i<16) wsprintf(&m_MidiCfg.szMidiZXXExt[i*32], "F0F001%02X", i*8); - else if (i<32) wsprintf(&m_MidiCfg.szMidiZXXExt[i*32], "F0F002%02X", (i-16)*8); - else m_MidiCfg.szMidiZXXExt[i*32] = 0; - break; - } - } + m_pModDoc->CreateZxxFromType(m_MidiCfg.szMidiZXXExt, zxx_preset); UpdateDialog(); - EndWaitCursor(); } } Modified: trunk/OpenMPT/mptrack/misc_util.h =================================================================== --- trunk/OpenMPT/mptrack/misc_util.h 2009-09-13 20:41:27 UTC (rev 363) +++ trunk/OpenMPT/mptrack/misc_util.h 2009-09-15 17:15:29 UTC (rev 364) @@ -110,4 +110,29 @@ utilImpl::ArrayCopyImpl<std::tr1::has_trivial_assign<T>::value>::Do(pDst, pSrc, n); } +// Sanitize a filename (remove special chars) +template <size_t size> +inline void SanitizeFilename(char (&buffer)[size]) +{ + STATIC_ASSERT(size > 0); + for(int i = 0; i < size; i++) + { + if( buffer[i] == '\\' || + buffer[i] == '\"' || + buffer[i] == '/' || + buffer[i] == ':' || + buffer[i] == '?' || + buffer[i] == '<' || + buffer[i] == '>' || + buffer[i] == '*') + { + for(int j = i + 1; j < size; j++) + { + buffer[j - 1] = buffer[j]; + } + buffer[size - 1] = 0; + } + } +} + #endif Modified: trunk/OpenMPT/mptrack/mod2midi.cpp =================================================================== --- trunk/OpenMPT/mptrack/mod2midi.cpp 2009-09-13 20:41:27 UTC (rev 363) +++ trunk/OpenMPT/mptrack/mod2midi.cpp 2009-09-15 17:15:29 UTC (rev 364) @@ -167,7 +167,7 @@ m_nCurrInstr = 1; if (m_pSndFile->m_nInstruments) { - for (UINT nIns=1; nIns<=m_pSndFile->m_nInstruments; nIns++) + for(INSTRUMENTINDEX nIns = 1; nIns <= m_pSndFile->m_nInstruments; nIns++) { MODINSTRUMENT *pIns = m_pSndFile->Instruments[nIns]; if ((pIns) && (m_pSndFile->IsInstrumentUsed(nIns))) @@ -180,15 +180,15 @@ } } else { - for (UINT nIns=1; nIns<=m_pSndFile->m_nSamples; nIns++) + for(SAMPLEINDEX nSmp = 1; nSmp <= m_pSndFile->m_nSamples; nSmp++) { - if ((m_pSndFile->Samples[nIns].pSample) - && (m_pSndFile->IsSampleUsed(nIns))) + if ((m_pSndFile->Samples[nSmp].pSample) + && (m_pSndFile->IsSampleUsed(nSmp))) { memset(s, 0, sizeof(s)); - wsprintf(s, "%02d: ", nIns); - memcpy(s+strlen(s), m_pSndFile->m_szNames[nIns], 32); - m_CbnInstrument.SetItemData(m_CbnInstrument.AddString(s), nIns); + wsprintf(s, "%02d: ", nSmp); + memcpy(s+strlen(s), m_pSndFile->m_szNames[nSmp], 32); + m_CbnInstrument.SetItemData(m_CbnInstrument.AddString(s), nSmp); } } } Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2009-09-13 20:41:27 UTC (rev 363) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2009-09-15 17:15:29 UTC (rev 364) @@ -14,10 +14,10 @@ #pragma warning(disable:4244) -BOOL CSoundFile::ReadSampleFromFile(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength) -//------------------------------------------------------------------------------------- +bool CSoundFile::ReadSampleFromFile(SAMPLEINDEX nSample, LPBYTE lpMemFile, DWORD dwFileLength) +//-------------------------------------------------------------------------------------------- { - if ((!nSample) || (nSample >= MAX_SAMPLES)) return FALSE; + if ((!nSample) || (nSample >= MAX_SAMPLES)) return false; if ((!ReadWAVSample(nSample, lpMemFile, dwFileLength)) && (!ReadXISample(nSample, lpMemFile, dwFileLength)) && (!ReadAIFFSample(nSample, lpMemFile, dwFileLength)) @@ -25,30 +25,30 @@ && (!ReadPATSample(nSample, lpMemFile, dwFileLength)) && (!Read8SVXSample(nSample, lpMemFile, dwFileLength)) && (!ReadS3ISample(nSample, lpMemFile, dwFileLength))) - return FALSE; - return TRUE; + return false; + return true; } -BOOL CSoundFile::ReadInstrumentFromFile(UINT nInstr, LPBYTE lpMemFile, DWORD dwFileLength) -//---------------------------------------------------------------------------------------- +bool CSoundFile::ReadInstrumentFromFile(INSTRUMENTINDEX nInstr, LPBYTE lpMemFile, DWORD dwFileLength) +//--------------------------------------------------------------------------------------------------- { - if ((!nInstr) || (nInstr >= MAX_INSTRUMENTS)) return FALSE; + if ((!nInstr) || (nInstr >= MAX_INSTRUMENTS)) return false; if ((!ReadXIInstrument(nInstr, lpMemFile, dwFileLength)) && (!ReadPATInstrument(nInstr, lpMemFile, dwFileLength)) && (!ReadITIInstrument(nInstr, lpMemFile, dwFileLength)) // Generic read - && (!ReadSampleAsInstrument(nInstr, lpMemFile, dwFileLength))) return FALSE; + && (!ReadSampleAsInstrument(nInstr, lpMemFile, dwFileLength))) return false; if (nInstr > m_nInstruments) m_nInstruments = nInstr; - return TRUE; + return true; } -BOOL CSoundFile::ReadSampleAsInstrument(UINT nInstr, LPBYTE lpMemFile, DWORD dwFileLength) -//---------------------------------------------------------------------------------------- +bool CSoundFile::ReadSampleAsInstrument(INSTRUMENTINDEX nInstr, LPBYTE lpMemFile, DWORD dwFileLength) +//--------------------------------------------------------------------------------------------------- { LPDWORD psig = (LPDWORD)lpMemFile; - if ((!lpMemFile) || (dwFileLength < 128)) return FALSE; + if ((!lpMemFile) || (dwFileLength < 128)) return false; if (((psig[0] == 0x46464952) && (psig[2] == 0x45564157)) // RIFF....WAVE signature || ((psig[0] == 0x5453494C) && (psig[2] == 0x65766177)) // LIST....wave || (psig[76/4] == 0x53524353) // S3I signature @@ -59,7 +59,7 @@ { // Loading Instrument MODINSTRUMENT *pIns = new MODINSTRUMENT; - if (!pIns) return FALSE; + if (!pIns) return false; memset(pIns, 0, sizeof(MODINSTRUMENT)); pIns->pTuning = pIns->s_DefaultTuning; // -> CODE#0003 @@ -91,21 +91,20 @@ pIns->NoteMap[iinit] = iinit+1; } if (nSample) ReadSampleFromFile(nSample, lpMemFile, dwFileLength); - return TRUE; + return true; } - return FALSE; + return false; } // -> CODE#0003 // -> DESC="remove instrument's samples" // BOOL CSoundFile::DestroyInstrument(UINT nInstr) -BOOL CSoundFile::DestroyInstrument(UINT nInstr, char removeSamples) -// -! BEHAVIOUR_CHANGE#0003 -//--------------------------------------------- +bool CSoundFile::DestroyInstrument(INSTRUMENTINDEX nInstr, char removeSamples) +//---------------------------------------------------------------------------- { - if ((!nInstr) || (nInstr > m_nInstruments)) return FALSE; - if (!Instruments[nInstr]) return TRUE; + if ((!nInstr) || (nInstr > m_nInstruments)) return false; + if (!Instruments[nInstr]) return true; // -> CODE#0003 // -> DESC="remove instrument's samples" @@ -117,7 +116,7 @@ // -> CODE#0023 // -> DESC="IT project files (.itp)" m_szInstrumentPath[nInstr-1][0] = '\0'; - instrumentModified[nInstr-1] = FALSE; + instrumentModified[nInstr-1] = false; // -! NEW_FEATURE#0023 MODINSTRUMENT *pIns = Instruments[nInstr]; @@ -130,14 +129,14 @@ } } delete pIns; - return TRUE; + return true; } -BOOL CSoundFile::IsSampleUsed(UINT nSample) -//----------------------------------------- +bool CSoundFile::IsSampleUsed(SAMPLEINDEX nSample) +//------------------------------------------------ { - if ((!nSample) || (nSample > m_nSamples)) return FALSE; + if ((!nSample) || (nSample > m_nSamples)) return false; if (m_nInstruments) { for (UINT i=1; i<=m_nInstruments; i++) if (Instruments[i]) @@ -145,7 +144,7 @@ MODINSTRUMENT *pIns = Instruments[i]; for (UINT j=0; j<128; j++) { - if (pIns->Keyboard[j] == nSample) return TRUE; + if (pIns->Keyboard[j] == nSample) return true; } } } else @@ -155,33 +154,33 @@ MODCOMMAND *m = Patterns[i]; for (UINT j=m_nChannels*PatternSize[i]; j; m++, j--) { - if (m->instr == nSample) return TRUE; + if (m->instr == nSample) return true; } } } - return FALSE; + return false; } -BOOL CSoundFile::IsInstrumentUsed(UINT nInstr) -//-------------------------------------------- +bool CSoundFile::IsInstrumentUsed(INSTRUMENTINDEX nInstr) +//------------------------------------------------------- { - if ((!nInstr) || (nInstr > m_nInstruments) || (!Instruments[nInstr])) return FALSE; + if ((!nInstr) || (nInstr > m_nInstruments) || (!Instruments[nInstr])) return false; for (UINT i=0; i<Patterns.Size(); i++) if (Patterns[i]) { MODCOMMAND *m = Patterns[i]; for (UINT j=m_nChannels*PatternSize[i]; j; m++, j--) { - if (m->instr == nInstr) return TRUE; + if (m->instr == nInstr) return true; } } - return FALSE; + return false; } // Removing all unused samples -BOOL CSoundFile::RemoveInstrumentSamples(UINT nInstr) -//--------------------------------------------------- +bool CSoundFile::RemoveInstrumentSamples(INSTRUMENTINDEX nInstr) +//-------------------------------------------------------------- { BYTE sampleused[MAX_SAMPLES/8]; @@ -194,23 +193,23 @@ UINT n = p->Keyboard[r]; if (n < MAX_SAMPLES) sampleused[n>>3] |= (1<<(n&7)); } - for (UINT smp=1; smp<MAX_INSTRUMENTS; smp++) if ((Instruments[smp]) && (smp != nInstr)) + for (SAMPLEINDEX nSmp=1; nSmp<MAX_INSTRUMENTS; nSmp++) if ((Instruments[nSmp]) && (nSmp != nInstr)) { - p = Instruments[smp]; + p = Instruments[nSmp]; for (UINT r=0; r<128; r++) { UINT n = p->Keyboard[r]; if (n < MAX_SAMPLES) sampleused[n>>3] &= ~(1<<(n&7)); } } - for (UINT d=1; d<=m_nSamples; d++) if (sampleused[d>>3] & (1<<(d&7))) + for (SAMPLEINDEX d = 1; d <= m_nSamples; d++) if (sampleused[d>>3] & (1<<(d&7))) { DestroySample(d); m_szNames[d][0] = 0; } - return TRUE; + return true; } - return FALSE; + return false; } //////////////////////////////////////////////////////////////////////////////// @@ -218,11 +217,11 @@ // I/O From another song // -BOOL CSoundFile::ReadInstrumentFromSong(UINT nInstr, CSoundFile *pSrcSong, UINT nSrcInstr) -//---------------------------------------------------------------------------------------- +bool CSoundFile::ReadInstrumentFromSong(INSTRUMENTINDEX nInstr, CSoundFile *pSrcSong, UINT nSrcInstr) +//--------------------------------------------------------------------------------------------------- { if ((!pSrcSong) || (!nSrcInstr) || (nSrcInstr > pSrcSong->m_nInstruments) - || (nInstr >= MAX_INSTRUMENTS) || (!pSrcSong->Instruments[nSrcInstr])) return FALSE; + || (nInstr >= MAX_INSTRUMENTS) || (!pSrcSong->Instruments[nSrcInstr])) return false; if (m_nInstruments < nInstr) m_nInstruments = nInstr; // -> CODE#0003 // -> DESC="remove instrument's samples" @@ -277,16 +276,16 @@ { ReadSampleFromSong(samplemap[k], pSrcSong, samplesrc[k]); } - return TRUE; + return true; } - return FALSE; + return false; } -BOOL CSoundFile::ReadSampleFromSong(UINT nSample, CSoundFile *pSrcSong, UINT nSrcSample) -//-------------------------------------------------------------------------------------- +bool CSoundFile::ReadSampleFromSong(SAMPLEINDEX nSample, CSoundFile *pSrcSong, UINT nSrcSample) +//--------------------------------------------------------------------------------------------- { - if ((!pSrcSong) || (!nSrcSample) || (nSrcSample > pSrcSong->m_nSamples) || (nSample >= MAX_SAMPLES)) return FALSE; + if ((!pSrcSong) || (!nSrcSample) || (nSrcSample > pSrcSong->m_nSamples) || (nSample >= MAX_SAMPLES)) return false; MODSAMPLE *psmp = &pSrcSong->Samples[nSrcSample]; UINT nSize = psmp->nLength; if (psmp->uFlags & CHN_16BIT) nSize *= 2; @@ -318,7 +317,7 @@ { FrequencyToTranspose(&Samples[nSample]); } - return TRUE; + return true; } @@ -330,8 +329,8 @@ extern BOOL IMAADPCMUnpack16(signed short *pdest, UINT nLen, LPBYTE psrc, DWORD dwBytes, UINT pkBlkAlign); -BOOL CSoundFile::ReadWAVSample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength, DWORD *pdwWSMPOffset) -//------------------------------------------------------------------------------------------------------ +bool CSoundFile::ReadWAVSample(SAMPLEINDEX nSample, LPBYTE lpMemFile, DWORD dwFileLength, DWORD *pdwWSMPOffset) +//------------------------------------------------------------------------------------------------------------- { DWORD dwMemPos = 0, dwDataPos; WAVEFILEHEADER *phdr = (WAVEFILEHEADER *)lpMemFile; @@ -341,9 +340,9 @@ WAVEEXTRAHEADER *pxh; DWORD dwInfoList, dwFact, dwSamplesPerBlock; - if ((!nSample) || (!lpMemFile) || (dwFileLength < (DWORD)(sizeof(WAVEFILEHEADER)+sizeof(WAVEFORMATHEADER)))) return FALSE; + if ((!nSample) || (!lpMemFile) || (dwFileLength < (DWORD)(sizeof(WAVEFILEHEADER)+sizeof(WAVEFORMATHEADER)))) return false; if (((phdr->id_RIFF != IFFID_RIFF) && (phdr->id_RIFF != IFFID_LIST)) - || ((phdr->id_WAVE != IFFID_WAVE) && (phdr->id_WAVE != IFFID_wave))) return FALSE; + || ((phdr->id_WAVE != IFFID_WAVE) && (phdr->id_WAVE != IFFID_wave))) return false; dwMemPos = sizeof(WAVEFILEHEADER); dwDataPos = 0; pfmt = NULL; @@ -410,7 +409,7 @@ } dwMemPos += dwLen + 8; } - if ((!pdata) || (!pfmt) || (pdata->length < 4)) return FALSE; + if ((!pdata) || (!pfmt) || (pdata->length < 4)) return false; if ((pfmtpk) && (pfmt)) { if (pfmt->format != 1) @@ -419,7 +418,7 @@ pfmt = pfmtpk; pfmtpk = tmp; if ((pfmtpk->format != 0x11) || (pfmtpk->bitspersample != 4) - || (pfmtpk->channels != 1)) return FALSE; + || (pfmtpk->channels != 1)) return false; } else pfmtpk = NULL; } // WAVE_FORMAT_PCM, WAVE_FORMAT_IEEE_FLOAT, WAVE_FORMAT_EXTENSIBLE @@ -430,7 +429,7 @@ || (pfmt->bitspersample & 7) || (!pfmt->bitspersample) || (pfmt->bitspersample > 32) - ) return FALSE; + ) return false; DestroySample(nSample); UINT nType = RS_PCM8U; @@ -570,14 +569,14 @@ } } } - return TRUE; + return true; } /////////////////////////////////////////////////////////////// // Save WAV -BOOL CSoundFile::SaveWAVSample(UINT nSample, LPCSTR lpszFileName) +bool CSoundFile::SaveWAVSample(UINT nSample, LPCSTR lpszFileName) //--------------------------------------------------------------- { LPCSTR lpszMPT = "Modplug Tracker\0"; @@ -590,7 +589,7 @@ MODSAMPLE *pSmp = &Samples[nSample]; FILE *f; - if ((f = fopen(lpszFileName, "wb")) == NULL) return FALSE; + if ((f = fopen(lpszFileName, "wb")) == NULL) return false; memset(&extra, 0, sizeof(extra)); memset(&smpl, 0, sizeof(smpl)); header.id_RIFF = IFFID_RIFF; @@ -679,19 +678,19 @@ extra.nVibRate = pSmp->nVibRate; fwrite(&extra, 1, sizeof(extra), f); fclose(f); - return TRUE; + return true; } /////////////////////////////////////////////////////////////// // Save RAW -BOOL CSoundFile::SaveRAWSample(UINT nSample, LPCSTR lpszFileName) +bool CSoundFile::SaveRAWSample(UINT nSample, LPCSTR lpszFileName) //--------------------------------------------------------------- { MODSAMPLE *pSmp = &Samples[nSample]; FILE *f; - if ((f = fopen(lpszFileName, "wb")) == NULL) return FALSE; + if ((f = fopen(lpszFileName, "wb")) == NULL) return false; UINT nType; if (pSmp->uFlags & CHN_STEREO) @@ -700,7 +699,7 @@ nType = (pSmp->uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S; WriteSample(f, pSmp, nType); fclose(f); - return TRUE; + return true; } ///////////////////////////////////////////////////////////// @@ -867,8 +866,8 @@ } -BOOL CSoundFile::ReadPATSample(UINT nSample, LPBYTE lpStream, DWORD dwMemLength) -//------------------------------------------------------------------------------ +bool CSoundFile::ReadPATSample(SAMPLEINDEX nSample, LPBYTE lpStream, DWORD dwMemLength) +//------------------------------------------------------------------------------------- { DWORD dwMemPos = sizeof(GF1PATCHFILEHEADER)+sizeof(GF1INSTRUMENT)+sizeof(GF1LAYER); GF1PATCHFILEHEADER *phdr = (GF1PATCHFILEHEADER *)lpStream; @@ -877,7 +876,7 @@ if ((!lpStream) || (dwMemLength < 512) || (phdr->gf1p != 0x50314647) || (phdr->atch != 0x48435441) || (phdr->version[3] != 0) || (phdr->id[9] != 0) || (phdr->instrum < 1) - || (!phdr->samples) || (!pinshdr->layers)) return FALSE; + || (!phdr->samples) || (!pinshdr->layers)) return false; DestroySample(nSample); PatchToSample(this, nSample, lpStream+dwMemPos, dwMemLength-dwMemPos); if (pinshdr->name[0] > ' ') @@ -885,13 +884,13 @@ memcpy(m_szNames[nSample], pinshdr->name, 16); m_szNames[nSample][16] = 0; } - return TRUE; + return true; } // PAT Instrument -BOOL CSoundFile::ReadPATInstrument(UINT nInstr, LPBYTE lpStream, DWORD dwMemLength) -//--------------------------------------------------------------------------------- +bool CSoundFile::ReadPATInstrument(INSTRUMENTINDEX nInstr, LPBYTE lpStream, DWORD dwMemLength) +//-------------------------------------------------------------------------------------------- { GF1PATCHFILEHEADER *phdr = (GF1PATCHFILEHEADER *)lpStream; GF1INSTRUMENT *pih = (GF1INSTRUMENT *)(lpStream+sizeof(GF1PATCHFILEHEADER)); @@ -904,7 +903,7 @@ || (phdr->gf1p != 0x50314647) || (phdr->atch != 0x48435441) || (phdr->version[3] != 0) || (phdr->id[9] != 0) || (phdr->instrum < 1) || (!phdr->samples) - || (!pih->layers) || (!plh->samples)) return FALSE; + || (!pih->layers) || (!plh->samples)) return false; if (nInstr > m_nInstruments) m_nInstruments = nInstr; // -> CODE#0003 // -> DESC="remove instrument's samples" @@ -912,7 +911,7 @@ DestroyInstrument(nInstr,1); // -! BEHAVIOUR_CHANGE#0003 pIns = new MODINSTRUMENT; - if (!pIns) return FALSE; + if (!pIns) return false; memset(pIns, 0, sizeof(MODINSTRUMENT)); pIns->pTuning = pIns->s_DefaultTuning; Instruments[nInstr] = pIns; @@ -1004,7 +1003,7 @@ } } } - return TRUE; + return true; } @@ -1032,8 +1031,8 @@ DWORD scrs; } S3ISAMPLESTRUCT; -BOOL CSoundFile::ReadS3ISample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength) -//-------------------------------------------------------------------------------- +bool CSoundFile::ReadS3ISample(SAMPLEINDEX nSample, LPBYTE lpMemFile, DWORD dwFileLength) +//--------------------------------------------------------------------------------------- { S3ISAMPLESTRUCT *pss = (S3ISAMPLESTRUCT *)lpMemFile; MODSAMPLE *pSmp = &Samples[nSample]; @@ -1042,7 +1041,7 @@ if ((!lpMemFile) || (dwFileLength < sizeof(S3ISAMPLESTRUCT)) || (pss->id != 0x01) || (((DWORD)pss->offset << 4) >= dwFileLength) - || (pss->scrs != 0x53524353)) return FALSE; + || (pss->scrs != 0x53524353)) return false; DestroySample(nSample); dwMemPos = pss->offset << 4; memcpy(pSmp->filename, pss->filename, 12); @@ -1063,7 +1062,7 @@ flags = (pss->flags & 0x04) ? RS_PCM16U : RS_PCM8U; if (pss->flags & 0x02) flags |= RSF_STEREO; ReadSample(pSmp, flags, (LPSTR)(lpMemFile+dwMemPos), dwFileLength-dwMemPos); - return TRUE; + return true; } @@ -1112,8 +1111,8 @@ -BOOL CSoundFile::ReadXIInstrument(UINT nInstr, LPBYTE lpMemFile, DWORD dwFileLength) -//---------------------------------------------------------------------------------- +bool CSoundFile::ReadXIInstrument(INSTRUMENTINDEX nInstr, LPBYTE lpMemFile, DWORD dwFileLength) +//--------------------------------------------------------------------------------------------- { XIFILEHEADER *pxh = (XIFILEHEADER *)lpMemFile; XIINSTRUMENTHEADER *pih = (XIINSTRUMENTHEADER *)(lpMemFile+sizeof(XIFILEHEADER)); @@ -1123,11 +1122,11 @@ DWORD dwMemPos = sizeof(XIFILEHEADER)+sizeof(XIINSTRUMENTHEADER); UINT nsamples; - if ((!lpMemFile) || (dwFileLength < sizeof(XIFILEHEADER)+sizeof(XIINSTRUMENTHEADER))) return FALSE; - if (dwMemPos + pxh->shsize - 0x102 >= dwFileLength) return FALSE; - if (memcmp(pxh->extxi, "Extended Instrument", 19)) return FALSE; + if ((!lpMemFile) || (dwFileLength < sizeof(XIFILEHEADER)+sizeof(XIINSTRUMENTHEADER))) return false; + if (dwMemPos + pxh->shsize - 0x102 >= dwFileLength) return false; + if (memcmp(pxh->extxi, "Extended Instrument", 19)) return false; dwMemPos += pxh->shsize - 0x102; - if ((dwMemPos < sizeof(XIFILEHEADER)) || (dwMemPos >= dwFileLength)) return FALSE; + if ((dwMemPos < sizeof(XIFILEHEADER)) || (dwMemPos >= dwFileLength)) return false; if (nInstr > m_nInstruments) m_nInstruments = nInstr; // -> CODE#0003 // -> DESC="remove instrument's samples" @@ -1136,7 +1135,7 @@ // -! BEHAVIOUR_CHANGE#0003 Instruments[nInstr] = new MODINSTRUMENT; MODINSTRUMENT *pIns = Instruments[nInstr]; - if (!pIns) return FALSE; + if (!pIns) return false; memset(pIns, 0, sizeof(MODINSTRUMENT)); pIns->pTuning = pIns->s_DefaultTuning; memcpy(pIns->name, pxh->name, 22); @@ -1295,18 +1294,18 @@ // -> DESC="per-instrument volume ramping setup (refered as attack)" // Leave if no extra instrument settings are available (end of file reached) - if(dwMemPos >= dwFileLength) return TRUE; + if(dwMemPos >= dwFileLength) return true; ReadExtendedInstrumentProperties(pIns, lpMemFile + dwMemPos, dwFileLength - dwMemPos); // -! NEW_FEATURE#0027 - return TRUE; + return true; } -BOOL CSoundFile::SaveXIInstrument(UINT nInstr, LPCSTR lpszFileName) -//----------------------------------------------------------------- +bool CSoundFile::SaveXIInstrument(INSTRUMENTINDEX nInstr, LPCSTR lpszFileName) +//---------------------------------------------------------------------------- { XIFILEHEADER xfh; XIINSTRUMENTHEADER xih; @@ -1316,8 +1315,8 @@ UINT nsamples; FILE *f; - if ((!pIns) || (!lpszFileName)) return FALSE; - if ((f = fopen(lpszFileName, "wb")) == NULL) return FALSE; + if ((!pIns) || (!lpszFileName)) return false; + if ((f = fopen(lpszFileName, "wb")) == NULL) return false; // XI File Header memset(&xfh, 0, sizeof(xfh)); memset(&xih, 0, sizeof(xih)); @@ -1431,12 +1430,12 @@ fclose(f); - return TRUE; + return true; } -BOOL CSoundFile::ReadXISample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength) -//------------------------------------------------------------------------------- +bool CSoundFile::ReadXISample(SAMPLEINDEX nSample, LPBYTE lpMemFile, DWORD dwFileLength) +//-------------------------------------------------------------------------------------- { XIFILEHEADER *pxh = (XIFILEHEADER *)lpMemFile; XIINSTRUMENTHEADER *pih = (XIINSTRUMENTHEADER *)(lpMemFile+sizeof(XIFILEHEADER)); @@ -1445,10 +1444,10 @@ MODSAMPLE *pSmp = &Samples[nSample]; UINT nsamples; - if ((!lpMemFile) || (dwFileLength < sizeof(XIFILEHEADER)+sizeof(XIINSTRUMENTHEADER))) return FALSE; - if (memcmp(pxh->extxi, "Extended Instrument", 19)) return FALSE; + if ((!lpMemFile) || (dwFileLength < sizeof(XIFILEHEADER)+sizeof(XIINSTRUMENTHEADER))) return false; + if (memcmp(pxh->extxi, "Extended Instrument", 19)) return false; dwMemPos += pxh->shsize - 0x102; - if ((dwMemPos < sizeof(XIFILEHEADER)) || (dwMemPos >= dwFileLength)) return FALSE; + if ((dwMemPos < sizeof(XIFILEHEADER)) || (dwMemPos >= dwFileLength)) return false; DestroySample(nSample); nsamples = 0; for (UINT i=0; i<96; i++) @@ -1516,9 +1515,9 @@ memcpy(pSmp->filename, psh->name, 22); pSmp->filename[21] = 0; } - if (dwMemPos >= dwFileLength) return TRUE; + if (dwMemPos >= dwFileLength) return true; ReadSample(pSmp, sampleflags, (LPSTR)(lpMemFile+dwMemPos), dwFileLength-dwMemPos); - return TRUE; + return true; } @@ -1580,8 +1579,8 @@ -BOOL CSoundFile::ReadAIFFSample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength) -//--------------------------------------------------------------------------------- +bool CSoundFile::ReadAIFFSample(SAMPLEINDEX nSample, LPBYTE lpMemFile, DWORD dwFileLength) +//---------------------------------------------------------------------------------------- { DWORD dwMemPos = sizeof(AIFFFILEHEADER); DWORD dwFORMLen, dwCOMMLen, dwSSNDLen; @@ -1590,22 +1589,22 @@ AIFFSSND *psnd; UINT nType; - if ((!lpMemFile) || (dwFileLength < (DWORD)sizeof(AIFFFILEHEADER))) return FALSE; + if ((!lpMemFile) || (dwFileLength < (DWORD)sizeof(AIFFFILEHEADER))) return false; dwFORMLen = BigEndian(phdr->dwLen); if ((phdr->dwFORM != 0x4D524F46) || (phdr->dwAIFF != 0x46464941) - || (dwFORMLen > dwFileLength) || (dwFORMLen < (DWORD)sizeof(AIFFCOMM))) return FALSE; + || (dwFORMLen > dwFileLength) || (dwFORMLen < (DWORD)sizeof(AIFFCOMM))) return false; pcomm = (AIFFCOMM *)(lpMemFile+dwMemPos); dwCOMMLen = BigEndian(pcomm->dwLen); - if ((pcomm->dwCOMM != 0x4D4D4F43) || (dwCOMMLen < 0x12) || (dwCOMMLen >= dwFileLength)) return FALSE; - if ((pcomm->wChannels != 0x0100) && (pcomm->wChannels != 0x0200)) return FALSE; - if ((pcomm->wSampleSize != 0x0800) && (pcomm->wSampleSize != 0x1000)) return FALSE; + if ((pcomm->dwCOMM != 0x4D4D4F43) || (dwCOMMLen < 0x12) || (dwCOMMLen >= dwFileLength)) return false; + if ((pcomm->wChannels != 0x0100) && (pcomm->wChannels != 0x0200)) return false; + if ((pcomm->wSampleSize != 0x0800) && (pcomm->wSampleSize != 0x1000)) return false; dwMemPos += dwCOMMLen + 8; - if (dwMemPos + sizeof(AIFFSSND) >= dwFileLength) return FALSE; + if (dwMemPos + sizeof(AIFFSSND) >= dwFileLength) return false; psnd = (AIFFSSND *)(lpMemFile+dwMemPos); dwSSNDLen = BigEndian(psnd->dwLen); - if ((psnd->dwSSND != 0x444E5353) || (dwSSNDLen >= dwFileLength) || (dwSSNDLen < 8)) return FALSE; + if ((psnd->dwSSND != 0x444E5353) || (dwSSNDLen >= dwFileLength) || (dwSSNDLen < 8)) return false; dwMemPos += sizeof(AIFFSSND); - if (dwMemPos >= dwFileLength) return FALSE; + if (dwMemPos >= dwFileLength) return false; DestroySample(nSample); if (pcomm->wChannels == 0x0100) { @@ -1641,7 +1640,7 @@ m_szNames[nSample][0] = 0; if (pSmp->nLength > MAX_SAMPLE_LENGTH) pSmp->nLength = MAX_SAMPLE_LENGTH; ReadSample(pSmp, nType, (LPSTR)(lpMemFile+dwMemPos), dwFileLength-dwMemPos); - return TRUE; + return true; } @@ -1651,9 +1650,8 @@ // -> CODE#0027 // -> DESC="per-instrument volume ramping setup (refered as attack)" //BOOL CSoundFile::ReadITSSample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength, DWORD dwOffset) -UINT CSoundFile::ReadITSSample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength, DWORD dwOffset) -// -! NEW_FEATURE#0027 -//------------------------------------------------------------------------------------------------ +UINT CSoundFile::ReadITSSample(SAMPLEINDEX nSample, LPBYTE lpMemFile, DWORD dwFileLength, DWORD dwOffset) +//------------------------------------------------------------------------------------------------------- { ITSAMPLESTRUCT *pis = (ITSAMPLESTRUCT *)lpMemFile; MODSAMPLE *pSmp = &Samples[nSample]; @@ -1728,8 +1726,8 @@ } -BOOL CSoundFile::ReadITIInstrument(UINT nInstr, LPBYTE lpMemFile, DWORD dwFileLength) -//----------------------------------------------------------------------------------- +bool CSoundFile::ReadITIInstrument(INSTRUMENTINDEX nInstr, LPBYTE lpMemFile, DWORD dwFileLength) +//---------------------------------------------------------------------------------------------- { ITINSTRUMENT *pinstr = (ITINSTRUMENT *)lpMemFile; WORD samplemap[NOTE_MAX]; //rewbs.noSamplePerInstroLimit (120 was 64) @@ -1737,7 +1735,7 @@ UINT nsmp, nsamples; if ((!lpMemFile) || (dwFileLength < sizeof(ITINSTRUMENT)) - || (pinstr->id != 0x49504D49)) return FALSE; + || (pinstr->id != 0x49504D49)) return false; if (nInstr > m_nInstruments) m_nInstruments = nInstr; // -> CODE#0003 // -> DESC="remove instrument's samples" @@ -1746,7 +1744,7 @@ // -! BEHAVIOUR_CHANGE#0003 Instruments[nInstr] = new MODINSTRUMENT; MODINSTRUMENT *pIns = Instruments[nInstr]; - if (!pIns) return FALSE; + if (!pIns) return false; memset(pIns, 0, sizeof(MODINSTRUMENT)); pIns->pTuning = pIns->s_DefaultTuning; memset(samplemap, 0, sizeof(samplemap)); @@ -1805,18 +1803,18 @@ ITSAMPLESTRUCT *pis = (ITSAMPLESTRUCT *)ptr; dwMemPos += pis->samplepointer - dwMemPos + lastSampleSize; // Leave if no extra instrument settings are available (end of file reached) - if(dwMemPos >= dwFileLength) return TRUE; + if(dwMemPos >= dwFileLength) return true; ReadExtendedInstrumentProperties(pIns, lpMemFile + dwMemPos, dwFileLength - dwMemPos); // -! NEW_FEATURE#0027 - return TRUE; + return true; } -BOOL CSoundFile::SaveITIInstrument(UINT nInstr, LPCSTR lpszFileName) -//------------------------------------------------------------------ +bool CSoundFile::SaveITIInstrument(INSTRUMENTINDEX nInstr, LPCSTR lpszFileName) +//----------------------------------------------------------------------------- { BYTE buffer[554]; ITINSTRUMENT *iti = (ITINSTRUMENT *)buffer; @@ -1826,8 +1824,8 @@ DWORD dwPos; FILE *f; - if ((!pIns) || (!lpszFileName)) return FALSE; - if ((f = fopen(lpszFileName, "wb")) == NULL) return FALSE; + if ((!pIns) || (!lpszFileName)) return false; + if ((f = fopen(lpszFileName, "wb")) == NULL) return false; memset(buffer, 0, sizeof(buffer)); memset(smpcount, 0, sizeof(smpcount)); memset(smptable, 0, sizeof(smptable)); @@ -1999,7 +1997,7 @@ WriteInstrumentHeaderStruct(pIns, f); // Write full extended header. fclose(f); - return TRUE; + return true; } @@ -2112,8 +2110,8 @@ -BOOL CSoundFile::Read8SVXSample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength) -//-------------------------------------------------------------------------------- +bool CSoundFile::Read8SVXSample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength) +//--------------------------------------------------------------------------------- { IFF8SVXFILEHEADER *pfh = (IFF8SVXFILEHEADER *)lpMemFile; IFFVHDR *pvh = (IFFVHDR *)(lpMemFile + 12); @@ -2122,7 +2120,7 @@ if ((!lpMemFile) || (dwFileLength < sizeof(IFFVHDR)+12) || (pfh->dwFORM != IFFID_FORM) || (pfh->dw8SVX != IFFID_8SVX) || (BigEndian(pfh->dwSize) >= dwFileLength) - || (pvh->dwVHDR != IFFID_VHDR) || (BigEndian(pvh->dwSize) >= dwFileLength)) return FALSE; + || (pvh->dwVHDR != IFFID_VHDR) || (BigEndian(pvh->dwSize) >= dwFileLength)) return false; DestroySample(nSample); // Default values pSmp->nGlobalVol = 64; @@ -2174,7 +2172,7 @@ } dwMemPos += dwChunkLen + 8; } - return TRUE; + return true; } Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-09-13 20:41:27 UTC (rev 363) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-09-15 17:15:29 UTC (rev 364) @@ -3083,7 +3083,7 @@ MODCHANNEL *pChn = &Chn[nChn]; UINT nRetrigSpeed = param & 0x0F; UINT nRetrigCount = pChn->nRetrigCount; - BOOL bDoRetrig = FALSE; + bool bDoRetrig = false; if(IsCompatibleMode(TRK_IMPULSETRACKER)) { @@ -3095,7 +3095,7 @@ else if (!pChn->nRetrigCount || !--pChn->nRetrigCount) { pChn->nRetrigCount = param & 0xf; - bDoRetrig = TRUE; + bDoRetrig = true; } } else @@ -3103,7 +3103,7 @@ if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) { if (!nRetrigSpeed) nRetrigSpeed = 1; - if ((nRetrigCount) && (!(nRetrigCount % nRetrigSpeed))) bDoRetrig = TRUE; + if ((nRetrigCount) && (!(nRetrigCount % nRetrigSpeed))) bDoRetrig = true; nRetrigCount++; } else { @@ -3112,12 +3112,12 @@ if ((m_nTickCount) || (param & 0x100)) { if (!realspeed) realspeed = 1; - if ((!(param & 0x100)) && (m_nMusicSpeed) && (!(m_nTickCount % realspeed))) bDoRetrig = TRUE; + if ((!(param & 0x100)) && (m_nMusicSpeed) && (!(m_nTickCount % realspeed))) bDoRetrig = true; nRetrigCount++; } else if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) nRetrigCount = 0; if (nRetrigCount >= realspeed) { - if ((m_nTickCount) || ((param & 0x100) && (!pChn->nRowNote))) bDoRetrig = TRUE; + if ((m_nTickCount) || ((param & 0x100) && (!pChn->nRowNote))) bDoRetrig = true; } } } @@ -3152,12 +3152,13 @@ if ((pChn->nRowInstr) && (param < 0x100)) { InstrumentChange(pChn, pChn->nRowInstr, FALSE, FALSE); bResetEnv = TRUE; } if (param < 0x100) bResetEnv = TRUE; } - NoteChange(nChn, nNote, false, bResetEnv); + NoteChange(nChn, nNote, IsCompatibleMode(TRK_IMPULSETRACKER) ? true : false, bResetEnv); if (m_nInstruments) { ProcessMidiOut(nChn, pChn); //Send retrig to Midi } if ((m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!pChn->nRowNote) && (nOldPeriod)) pChn->nPeriod = nOldPeriod; if (!(m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT))) nRetrigCount = 0; + if(IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPos = pChn->nPosLo = 0; if (offset) //rewbs.volOffset: apply offset on retrig { Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-09-13 20:41:27 UTC (rev 363) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-09-15 17:15:29 UTC (rev 364) @@ -1337,10 +1337,10 @@ //m_nSeqOverride = 0; } -int CSoundFile::FindOrder(PATTERNINDEX pat, UINT startFromOrder, bool direction) -//---------------------------------------------------------------------- +ORDERINDEX CSoundFile::FindOrder(PATTERNINDEX pat, UINT startFromOrder, bool direction) +//------------------------------------------------------------------------------------- { - int foundAtOrder = -1; + int foundAtOrder = ORDERINDEX_INVALID; int candidateOrder = 0; for (UINT p=0; p<Order.size(); p++) { @@ -1708,15 +1708,15 @@ } -BOOL CSoundFile::CanPackSample(LPSTR pSample, UINT nLen, UINT nPacking, BYTE *result) -//----------------------------------------------------------------------------------- +bool CSoundFile::CanPackSample(LPSTR pSample, UINT nLen, UINT nPacking, BYTE *result/*=NULL*/) +//-------------------------------------------------------------------------------------------- { int pos, old, oldpos, besttable = 0; DWORD dwErr, dwTotal, dwResult; int i,j; if (result) *result = 0; - if ((!pSample) || (nLen < 1024)) return FALSE; + if ((!pSample) || (nLen < 1024)) return false; // Try packing with different tables dwResult = 0; for (j=1; j<MAX_PACK_TABLES; j++) @@ -1746,7 +1746,7 @@ { if (dwResult > 100) *result = 100; else *result = (BYTE)dwResult; } - return (dwResult >= nPacking) ? TRUE : FALSE; + return (dwResult >= nPacking) ? true : false; } #endif // NO_PACKING @@ -2743,10 +2743,10 @@ } -BOOL CSoundFile::RemoveSelectedSamples(BOOL *pbIns) +bool CSoundFile::RemoveSelectedSamples(bool *pbIns) //------------------------------------------------- { - if (!pbIns) return FALSE; + if (!pbIns) return false; for (UINT j=1; j<MAX_SAMPLES; j++) { if ((!pbIns[j]) && (Samples[j].pSample)) @@ -2755,15 +2755,15 @@ if ((j == m_nSamples) && (j > 1)) m_nSamples--; } } - return TRUE; + return true; } -BOOL CSoundFile::DestroySample(UINT nSample) -//------------------------------------------ +bool CSoundFile::DestroySample(SAMPLEINDEX nSample) +//------------------------------------------------- { - if ((!nSample) || (nSample >= MAX_SAMPLES)) return FALSE; - if (!Samples[nSample].pSample) return TRUE; + if ((!nSample) || (nSample >= MAX_SAMPLES)) return false; + if (!Samples[nSample].pSample) return true; MODSAMPLE *pSmp = &Samples[nSample]; LPSTR pSample = pSmp->pSample; pSmp->pSample = nullptr; @@ -2778,13 +2778,13 @@ } } FreeSample(pSample); - return TRUE; + return true; } // -> CODE#0020 // -> DESC="rearrange sample list" -bool CSoundFile::MoveSample(UINT from, UINT to) -//--------------------------------------------- +bool CSoundFile::MoveSample(SAMPLEINDEX from, SAMPLEINDEX to) +//----------------------------------------------------------- { if (!from || from >= MAX_SAMPLES || !to || to >= MAX_SAMPLES) return false; if (/*!Ins[from].pSample ||*/ Samples[to].pSample) return true; Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-09-13 20:41:27 UTC (rev 363) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-09-15 17:15:29 UTC (rev 364) @@ -634,7 +634,7 @@ static const CModSpecifications& GetModSpecifications(const MODTYPE type); double GetCurrentBPM() const; - int FindOrder(PATTERNINDEX pat, UINT startFromOrder=0, bool direction=true); //rewbs.playSongFromCursor + ORDERINDEX FindOrder(PATTERNINDEX pat, UINT startFromOrder=0, bool direction=true); //rewbs.playSongFromCursor void DontLoopPattern(int nPat, int nRow=0); //rewbs.playSongFromCursor void SetCurrentPos(UINT nPos); void SetCurrentOrder(UINT nOrder); @@ -848,55 +848,54 @@ // Read/Write sample functions char GetDeltaValue(char prev, UINT n) const { return (char)(prev + CompressionTable[n & 0x0F]); } UINT PackSample(int &sample, int next); - BOOL CanPackSample(LPSTR pSample, UINT nLen, UINT nPacking, BYTE *result=NULL); + bool CanPackSample(LPSTR pSample, UINT nLen, UINT nPacking, BYTE *result=NULL); UINT ReadSample(MODSAMPLE *pSmp, UINT nFlags, LPCSTR pMemFile, DWORD dwMemLength, const WORD format = 1); - BOOL DestroySample(UINT nSample); + bool DestroySample(SAMPLEINDEX nSample); // -> CODE#0020 // -> DESC="rearrange sample list" - bool MoveSample(UINT from,UINT to); + bool MoveSample(SAMPLEINDEX from, SAMPLEINDEX to); // -! NEW_FEATURE#0020 // -> CODE#0003 // -> DESC="remove instrument's samples" //BOOL DestroyInstrument(UINT nInstr); - BOOL DestroyInstrument(UINT nInstr, char removeSamples = 0); + bool DestroyInstrument(INSTRUMENTINDEX nInstr, char removeSamples = 0); // -! BEHAVIOUR_CHANGE#0003 - BOOL IsSampleUsed(UINT nSample); - BOOL IsInstrumentUsed(UINT nInstr); - BOOL RemoveInstrumentSamples(UINT nInstr); + bool IsSampleUsed(SAMPLEINDEX nSample); + bool IsInstrumentUsed(INSTRUMENTINDEX nInstr); + bool RemoveInstrumentSamples(INSTRUMENTINDEX nInstr); UINT DetectUnusedSamples(BYTE *); // bitmask - BOOL RemoveSelectedSamples(BOOL *); + bool RemoveSelectedSamples(bool *pbIns); void AdjustSampleLoop(MODSAMPLE *pSmp); // Samples file I/O - BOOL ReadSampleFromFile(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength); - BOOL ReadWAVSample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength, DWORD *pdwWSMPOffset=NULL); - BOOL ReadPATSample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength); - BOOL ReadS3ISample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength); - BOOL ReadAIFFSample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength); - BOOL ReadXISample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength); + bool ReadSampleFromFile(SAMPLEINDEX nSample, LPBYTE lpMemFile, DWORD dwFileLength); + bool ReadWAVSample(SAMPLEINDEX nSample, LPBYTE lpMemFile, DWORD dwFileLength, DWORD *pdwWSMPOffset=NULL); + bool ReadPATSample(SAMPLEINDEX nSample, LPBYTE lpMemFile, DWORD dwFileLength); + bool ReadS3ISample(SAMPLEINDEX nSample, LPBYTE lpMemFile, DWORD dwFileLength); + bool ReadAIFFSample(SAMPLEINDEX nSample, LPBYTE lpMemFile, DWORD dwFileLength); + bool ReadXISample(SAMPLEINDEX nSample, LPBYTE lpMemFile, DWORD dwFileLength); // -> CODE#0027 // -> DESC="per-instrument volume ramping setup (refered as attack)" // BOOL ReadITSSample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength, DWORD dwOffset=0); - UINT ReadITSSample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength, DWORD dwOffset=0); + UINT ReadITSSample(SAMPLEINDEX nSample, LPBYTE lpMemFile, DWORD dwFileLength, DWORD dwOffset=0); // -! NEW_FEATURE#0027 - BOOL ReadITISample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength); - BOOL Read8SVXSample(UINT nInstr, LPBYTE lpMemFile, DWORD dwFileLength); - BOOL SaveWAVSample(UINT nSample, LPCSTR lpszFileName); - BOOL SaveRAWSample(UINT nSample, LPCSTR lpszFileName); + bool Read8SVXSample(UINT nInstr, LPBYTE lpMemFile, DWORD dwFileLength); + bool SaveWAVSample(UINT nSample, LPCSTR lpszFileName); + bool SaveRAWSample(UINT nSample, LPCSTR lpszFileName); // Instrument file I/O - BOOL ReadInstrumentFromFile(UINT nInstr, LPBYTE lpMemFile, DWORD dwFileLength); - BOOL ReadXIInstrument(UINT nInstr, LPBYTE lpMemFile, DWORD dwFileLength); - BOOL ReadITIInstrument(UINT nInstr, LPBYTE lpMemFile, DWORD dwFileLength); - BOOL ReadPATInstrument(UINT nInstr, LPBYTE lpMemFile, DWORD dwFileLength); - BOOL ReadSampleAsInstrument(UINT nInstr, LPBYTE lpMemFile, DWORD dwFileLength); - BOOL SaveXIInstrument(UINT nInstr, LPCSTR lpszFileName); - BOOL SaveITIInstrument(UINT nInstr, LPCSTR lpszFileName); + bool ReadInstrumentFromFile(INSTRUMENTINDEX nInstr, LPBYTE lpMemFile, DWORD dwFileLength); + bool ReadXIInstrument(INSTRUMENTINDEX nInstr, LPBYTE lpMemFile, DWORD dwFileLength); + bool ReadITIInstrument(INSTRUMENTINDEX nInstr, LPBYTE lpMemFile, DWORD dwFileLength); + bool ReadPATInstrument(INSTRUMENTINDEX nInstr, LPBYTE lpMemFile, DWORD dwFileLength); + bool ReadSampleAsInstrument(INSTRUMENTINDEX nInstr, LPBYTE lpMemFile, DWORD dwFileLength); + bool SaveXIInstrument(INSTRUMENTINDEX nInstr, LPCSTR lpszFileName); + bool SaveITIInstrument(INSTRUMENTINDEX nInstr, LPCSTR lpszFileName); // I/O from another sound file - BOOL ReadInstrumentFromSong(UINT nInstr, CSoundFile *, UINT nSrcInstrument); - BOOL ReadSampleFromSong(UINT nSample, CSoundFile *, UINT nSrcSample); + bool ReadInstrumentFromSong(INSTRUMENTINDEX nInstr, CSoundFile *pSrcSong, UINT nSrcInstrument); + bool ReadSampleFromSong(SAMPLEINDEX nSample, CSoundFile *pSrcSong, UINT nSrcSample); // Period/Note functions UINT GetNoteFromPeriod(UINT period) const; UINT GetPeriodFromNote(UINT note, int nFineTune, UINT nC5Speed) const; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-09-16 19:05:12
|
Revision: 366 http://modplug.svn.sourceforge.net/modplug/?rev=366&view=rev Author: relabsoluness Date: 2009-09-16 19:05:00 +0000 (Wed, 16 Sep 2009) Log Message: ----------- [New] MPTM: Can now have multiple sequences in a module (access from orderlist context menu). [Fix] MPTM save/load: Loading extensions was broken in the case of not having any instruments. [Ref] Internal: minor changes and cleanup. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_pat.cpp trunk/OpenMPT/mptrack/Ctrl_pat.h trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/mptrack/Draw_pat.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/mptrack/View_tre.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/mptrack/serialization_utils.cpp trunk/OpenMPT/mptrack/serialization_utils.h trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/ModSequence.cpp trunk/OpenMPT/soundlib/ModSequence.h trunk/OpenMPT/soundlib/Snd_defs.h trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-09-16 19:05:00 UTC (rev 366) @@ -66,6 +66,7 @@ ON_COMMAND(IDC_PATINSTROPLUGGUI2, ToggleSplitPluginEditor) //rewbs.instroVST ON_EN_CHANGE(IDC_EDIT_SPACING, OnSpacingChanged) ON_EN_CHANGE(IDC_EDIT_PATTERNNAME, OnPatternNameChanged) + ON_EN_CHANGE(IDC_EDIT_SEQUENCE_NAME, OnSequenceNameChanged) ON_EN_KILLFOCUS(IDC_EDIT_ORDERLIST_MARGINS, OnOrderListMarginsChanged) ON_UPDATE_COMMAND_UI(IDC_PATTERN_RECORD,OnUpdateRecord) ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText) @@ -278,6 +279,9 @@ m_OrderList.UpdateView(dwHintMask, pObj); if (!m_pSndFile) return; + if (dwHintMask & HINT_MODSEQUENCE) + SetDlgItemText(IDC_EDIT_SEQUENCE_NAME, m_pSndFile->Order.m_sName); + //rewbs.instroVST if (dwHintMask & (HINT_MIXPLUGINS|HINT_MODTYPE)) { @@ -289,6 +293,10 @@ ::EnableWindow(::GetDlgItem(m_hWnd, IDC_PATINSTROPLUGGUI2), true); else ::EnableWindow(::GetDlgItem(m_hWnd, IDC_PATINSTROPLUGGUI2), false); + + // Show/hide multisequence controls according the current modtype. + GetDlgItem(IDC_STATIC_SEQUENCE_NAME)->ShowWindow( (m_pSndFile->GetType() == MOD_TYPE_MPT) ? SW_SHOW : SW_HIDE); + GetDlgItem(IDC_EDIT_SEQUENCE_NAME)->ShowWindow( (m_pSndFile->GetType() == MOD_TYPE_MPT) ? SW_SHOW : SW_HIDE); } //end rewbs.instroVST if (dwHintMask & HINT_MPTOPTIONS) @@ -611,7 +619,7 @@ //Restore all save pattern state, except pattern number which we might have just set. PATTERNVIEWSTATE* patternViewState = pFrame->GetPatternViewState(); - patternViewState->nPattern = SendViewMessage(VIEWMSG_GETCURRENTPATTERN); + patternViewState->nPattern = static_cast<PATTERNINDEX>(SendViewMessage(VIEWMSG_GETCURRENTPATTERN)); if (pFrame) SendViewMessage(VIEWMSG_LOADSTATE, (LPARAM)patternViewState); SwitchToView(); @@ -919,7 +927,7 @@ nNewPat = pReplaceIndex[nCurPat]; // take care of patterns that have been duplicated before else nNewPat= pSndFile->Order[selection.nOrdLo + i]; - if (selection.nOrdLo + i + nInsertCount + 1 < pSndFile->Order.GetCount()) + if (selection.nOrdLo + i + nInsertCount + 1 < pSndFile->Order.GetLength()) pSndFile->Order[selection.nOrdLo + i + nInsertCount + 1] = nNewPat; } } @@ -927,7 +935,7 @@ { m_OrderList.InvalidateRect(NULL, FALSE); m_OrderList.SetCurSel(nInsertWhere); - SetCurrentPattern(pSndFile->Order[min(nInsertWhere, pSndFile->Order.GetCount()-1)]); + SetCurrentPattern(pSndFile->Order[min(nInsertWhere, pSndFile->Order.GetLastIndex())]); m_pModDoc->SetModified(); m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE|HINT_PATNAMES, this); if(selection.nOrdHi != selection.nOrdLo) m_OrderList.m_nScrollPos2nd = nInsertWhere + nInsertCount; @@ -1140,6 +1148,22 @@ } +void CCtrlPatterns::OnSequenceNameChanged() +//----------------------------------------- +{ + if (m_pSndFile) + { + CString str; + GetDlgItemText(IDC_EDIT_SEQUENCE_NAME, str); + if (str != m_pSndFile->Order.m_sName) + { + m_pSndFile->Order.m_sName = str; + m_pModDoc->SetModified(); + } + } +} + + void CCtrlPatterns::OnSetupZxxMacros() //------------------------------------ { Modified: trunk/OpenMPT/mptrack/Ctrl_pat.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-09-16 19:05:00 UTC (rev 366) @@ -47,13 +47,15 @@ // make the current selection the secondary selection (used for keyboard orderlist navigation) inline void SetCurSelTo2ndSel() {if(m_bShift && m_nScrollPos2nd == ORDERINDEX_INVALID) m_nScrollPos2nd = m_nScrollPos; else if(!m_bShift && m_nScrollPos2nd != ORDERINDEX_INVALID) m_nScrollPos2nd = ORDERINDEX_INVALID;}; - bool SetCurSel(ORDERINDEX sel, bool bEdit = true, bool bShiftClick = false); + bool SetCurSel(ORDERINDEX sel, bool bEdit = true, bool bShiftClick = false, bool bIgnoreCurSel = false); BOOL ProcessKeyDown(UINT nChar); BOOL ProcessChar(UINT nChar); BOOL UpdateScrollInfo(); void UpdateInfoText(); int GetFontWidth(); + ORDERINDEX GetOrderFromPoint(const CRect& rect, const CPoint& pt) const; + // Sets target margin value and returns the effective margin value. BYTE SetMargins(int); @@ -113,6 +115,7 @@ afx_msg void OnPatternPaste(); afx_msg LRESULT OnDragonDropping(WPARAM bDoDrop, LPARAM lParam); afx_msg LRESULT OnHelpHitTest(WPARAM, LPARAM lParam); + afx_msg void OnSelectSequence(UINT nid); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; @@ -218,6 +221,7 @@ afx_msg void OnNextInstrument(); afx_msg void OnSpacingChanged(); afx_msg void OnPatternNameChanged(); + afx_msg void OnSequenceNameChanged(); afx_msg void OnOrderListMarginsChanged(); afx_msg void OnSetupZxxMacros(); afx_msg void OnChordEditor(); Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-09-16 19:05:00 UTC (rev 366) @@ -54,6 +54,7 @@ ON_COMMAND(ID_ORDERLIST_COPY, OnDuplicatePattern) ON_COMMAND(ID_PATTERNCOPY, OnPatternCopy) ON_COMMAND(ID_PATTERNPASTE, OnPatternPaste) + ON_COMMAND_RANGE(ID_SEQUENCE_ITEM, ID_SEQUENCE_ITEM + MAX_SEQUENCES + 1, OnSelectSequence) ON_MESSAGE(WM_MOD_DRAGONDROPPING, OnDragonDropping) ON_MESSAGE(WM_HELPHITTEST, OnHelpHitTest) //}}AFX_MSG_MAP @@ -87,6 +88,13 @@ } +ORDERINDEX COrderList::GetOrderFromPoint(const CRect& rect, const CPoint& pt) const +//--------------------------------------------------------------------------------- +{ + return static_cast<ORDERINDEX>(m_nXScroll + (pt.x - rect.left) / m_cxFont); +} + + BOOL COrderList::Init(const CRect &rect, CCtrlPatterns *pParent, CModDoc *pModDoc, HFONT hFont) //--------------------------------------------------------------------------------------------- { @@ -216,18 +224,20 @@ else result.nOrdHi = m_nScrollPos2nd; } + LimitMax(result.nOrdLo, m_pModDoc->GetSoundFile()->Order.GetLastIndex()); + LimitMax(result.nOrdHi, m_pModDoc->GetSoundFile()->Order.GetLastIndex()); return result; } -bool COrderList::SetCurSel(ORDERINDEX sel, bool bEdit, bool bShiftClick) -//---------------------------------------------------------------------- +bool COrderList::SetCurSel(ORDERINDEX sel, bool bEdit, bool bShiftClick, bool bIgnoreCurSel) +//------------------------------------------------------------------------------------------ { CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); ORDERINDEX *nOrder = (bShiftClick) ? &m_nScrollPos2nd : &m_nScrollPos; - if ((sel < 0) || (sel >= int(pSndFile->Order.size())) || (!m_pParent) || (!pMainFrm)) return false; - if (sel == *nOrder) return true; + if ((sel < 0) || (sel >= pSndFile->Order.GetLength()) || (!m_pParent) || (!pMainFrm)) return false; + if (!bIgnoreCurSel && sel == *nOrder) return true; const BYTE nShownLength = GetLength(); InvalidateSelection(); *nOrder = sel; @@ -281,7 +291,7 @@ END_CRITICAL(); } m_pParent->SetCurrentPattern(n); - m_pModDoc->SetElapsedTime(static_cast<ORDERINDEX>(m_nScrollPos), 0); + m_pModDoc->SetElapsedTime(m_nScrollPos, 0); } } UpdateInfoText(); @@ -294,7 +304,7 @@ //---------------------------------------- { CSoundFile* pSndFile = m_pModDoc ? m_pModDoc->GetSoundFile() : NULL; - if ((pSndFile) && (m_nScrollPos < pSndFile->Patterns.Size())) + if ((pSndFile) && (m_nScrollPos < pSndFile->Order.GetLength())) { return pSndFile->Order[m_nScrollPos]; } @@ -316,11 +326,11 @@ if (m_pModDoc) { CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); - ORDERINDEX i = 0; - const int nSeqLength = pSndFile->Order.size(); - for (i=0; i+1 < nSeqLength; i++) if (pSndFile->Order[i+1] == pSndFile->Order.GetInvalidPatIndex()) break; + ORDERINDEX nLast = pSndFile->Order.GetLengthFirstEmpty(); + if (nLast) + nLast--; SetCurSelTo2ndSel(); - SetCurSel(i); + SetCurSel(nLast); } break; case VK_DELETE: OnDeleteOrder(); break; @@ -484,7 +494,7 @@ m_nScrollPos, pSndFile->GetNumPatterns(), m_nScrollPos, pSndFile->GetNumPatterns()); } - if (m_nScrollPos < int(pSndFile->Order.size())) + if (m_nScrollPos < pSndFile->Order.GetLength()) { UINT nPat = pSndFile->Order[m_nScrollPos]; if ((nPat < pSndFile->Patterns.Size()) && (nPat < pSndFile->m_nPatternNames)) @@ -535,7 +545,7 @@ while (rect.left < rcClient.right) { bool bHighLight = ((bFocus) && (nIndex >= selection.nOrdLo && nIndex <= selection.nOrdHi)) ? true : false; - ORDERINDEX nOrder = ((nIndex >= 0) && (nIndex < int(pSndFile->Order.size()))) ? pSndFile->Order[nIndex] : -1; + const PATTERNINDEX nPat = ((nIndex >= 0) && (nIndex < pSndFile->Order.GetLength())) ? pSndFile->Order[nIndex] : PATTERNINDEX_INVALID; if ((rect.right = rect.left + m_cxFont) > rcClient.right) rect.right = rcClient.right; rect.right--; if (bHighLight) { @@ -546,7 +556,7 @@ //Drawing the shown pattern-indicator or drag position. - if (nIndex == ((m_bDragging) ? (int)m_nDropPos : m_nScrollPos)) + if (nIndex == ((m_bDragging) ? m_nDropPos : m_nScrollPos)) { rect.InflateRect(-1, -1); dc.DrawFocusRect(&rect); @@ -555,7 +565,7 @@ MoveToEx(dc.m_hDC, rect.right, rect.top, NULL); LineTo(dc.m_hDC, rect.right, rect.bottom); //Drawing the 'ctrl-transition' indicator - if (nIndex == (int)pSndFile->m_nSeqOverride-1) + if (nIndex == pSndFile->m_nSeqOverride-1) { MoveToEx(dc.m_hDC, rect.left+4, rect.bottom-4, NULL); LineTo(dc.m_hDC, rect.right-4, rect.bottom-4); @@ -564,21 +574,18 @@ CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); //Drawing 'playing'-indicator. - if(nIndex == (int)pSndFile->GetCurrentOrder() && pMainFrm->IsPlaying() ) + if(nIndex == pSndFile->GetCurrentOrder() && pMainFrm->IsPlaying() ) { MoveToEx(dc.m_hDC, rect.left+4, rect.top+2, NULL); LineTo(dc.m_hDC, rect.right-4, rect.top+2); } s[0] = 0; - if ((nOrder >= 0) && (rect.left + m_cxFont - 4 <= rcClient.right)) + if ((nIndex < pSndFile->Order.GetLength()) && (rect.left + m_cxFont - 4 <= rcClient.right)) { - if (nIndex < pSndFile->Order.GetCount()) - { - if (nOrder == pSndFile->Order.GetInvalidPatIndex()) strcpy(s, "---"); - else if (nOrder == pSndFile->Order.GetIgnoreIndex()) strcpy(s, "+++"); - else if (nOrder < pSndFile->Patterns.Size()) wsprintf(s, "%d", nOrder); - else strcpy(s, "???"); - } + if (nPat == pSndFile->Order.GetInvalidPatIndex()) strcpy(s, "---"); + else if (nPat == pSndFile->Order.GetIgnoreIndex()) strcpy(s, "+++"); + else if (nPat < pSndFile->Patterns.Size()) wsprintf(s, "%u", nPat); + else strcpy(s, "???"); } dc.SetTextColor((bHighLight) ? colorTextSel : colorText); dc.DrawText(s, -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); @@ -626,8 +633,8 @@ if (m_pModDoc) { CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); - ORDERINDEX nOrder = m_nXScroll + (pt.x - rect.left) / m_cxFont; - if ((nOrder >= 0) && (nOrder < int(pSndFile->Order.size()))) + ORDERINDEX nOrder = GetOrderFromPoint(rect, pt); + if ((nOrder >= 0) && (nOrder < pSndFile->Order.GetLength())) { if (pSndFile->m_nSeqOverride == static_cast<UINT>(nOrder)+1) { pSndFile->m_nSeqOverride=0; @@ -642,7 +649,7 @@ // mark pattern (+skip to) const int oldXScroll = m_nXScroll; - ORDERINDEX nOrder = m_nXScroll + (pt.x - rect.left) / m_cxFont; + ORDERINDEX nOrder = GetOrderFromPoint(rect, pt); ORD_SELECTION selection = GetCurSel(false); // check if cursor is in selection - if it is, only react on MouseUp as the user might want to drag those orders @@ -678,7 +685,7 @@ ReleaseCapture(); if (rect.PtInRect(pt)) { - int n = m_nXScroll + (pt.x - rect.left) / m_cxFont; + ORDERINDEX n = GetOrderFromPoint(rect, pt); if ((n >= 0) && (n == m_nDropPos) && (m_pModDoc)) { // drag multiple orders (not quite as easy...) @@ -719,7 +726,7 @@ } else { - ORDERINDEX nOrder = m_nXScroll + (pt.x - rect.left) / m_cxFont; + ORDERINDEX nOrder = GetOrderFromPoint(rect, pt); ORD_SELECTION selection = GetCurSel(false); // this should actually have equal signs but that breaks multiselect: nOrder >= selection.nOrdLo && nOrder <= section.nOrdHi @@ -728,7 +735,7 @@ // Remove selection if we didn't drag anything but multiselect was active m_nScrollPos2nd = ORDERINDEX_INVALID; SetFocus(); - SetCurSel(m_nXScroll + (pt.x - rect.left) / m_cxFont); + SetCurSel(GetOrderFromPoint(rect, pt)); } } } @@ -752,8 +759,8 @@ if (rect.PtInRect(pt)) { CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); - n = m_nXScroll + (pt.x - rect.left) / m_cxFont; - if (n >= int(pSndFile->Order.size()) || n >= pSndFile->GetModSpecifications().ordersMax) n = ORDERINDEX_INVALID; + n = GetOrderFromPoint(rect, pt); + if (n >= pSndFile->Order.GetLength() || n >= pSndFile->GetModSpecifications().ordersMax) n = ORDERINDEX_INVALID; } if (n != (int)m_nDropPos) { @@ -775,6 +782,43 @@ } +void COrderList::OnSelectSequence(UINT nid) +//----------------------------------------- +{ + BEGIN_CRITICAL(); + CMainFrame::GetMainFrame()->ResetNotificationBuffer(); + const SEQUENCEINDEX nId = static_cast<SEQUENCEINDEX>(nid - ID_SEQUENCE_ITEM); + CSoundFile& rSf = *m_pModDoc->GetSoundFile(); + if (nId == MAX_SEQUENCES + 1) + { + CString strParam; strParam.Format(TEXT("%u: %s"), rSf.Order.GetCurrentSequenceIndex(), rSf.Order.m_sName); + CString str; + AfxFormatString1(str, IDS_CONFIRM_SEQUENCE_DELETE, strParam); + if (AfxMessageBox(str, MB_YESNO | MB_ICONQUESTION) == IDYES) + rSf.Order.RemoveSequence(); + else + { + END_CRITICAL(); + return; + } + } + else if (nId == MAX_SEQUENCES) + rSf.Order.AddSequence(); + else if (nId < rSf.Order.GetNumSequences()) + rSf.Order.SetSequence(nId); + ORDERINDEX nPosCandidate = rSf.Order.GetLengthTailTrimmed() - 1; + SetCurSel(min(m_nScrollPos, nPosCandidate), true, false, true); + if (m_pParent) + m_pParent->SetCurrentPattern(rSf.Order[m_nScrollPos]); + + UpdateScrollInfo(); + END_CRITICAL(); + UpdateView(HINT_MODSEQUENCE); + m_pModDoc->SetModified(); + m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this); +} + + void COrderList::OnRButtonDown(UINT nFlags, CPoint pt) //---------------------------------------------------- { @@ -791,7 +835,7 @@ bool bMultiSelection = (m_nScrollPos2nd != ORDERINDEX_INVALID); - if(!bMultiSelection) SetCurSel(m_nXScroll + (pt.x - rect.left) / m_cxFont); + if(!bMultiSelection) SetCurSel(GetOrderFromPoint(rect, pt)); SetFocus(); HMENU hMenu = ::CreatePopupMenu(); if(!hMenu) return; @@ -826,11 +870,31 @@ AppendMenu(hMenu, MF_STRING | greyed, ID_ORDERLIST_COPY, "&Duplicate Pattern"); AppendMenu(hMenu, MF_STRING | greyed, ID_PATTERNCOPY, "&Copy Pattern"); AppendMenu(hMenu, MF_STRING | greyed, ID_PATTERNPASTE, "P&aste Pattern"); - if ((m_pModDoc) && (m_pModDoc->GetSoundFile()->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT))) + if (pSndFile->TypeIsIT_MPT_XM()) { AppendMenu(hMenu, MF_SEPARATOR, NULL, ""); - AppendMenu(hMenu, MF_STRING | greyed, ID_PATTERN_PROPERTIES, "&Properties..."); + AppendMenu(hMenu, MF_STRING | greyed, ID_PATTERN_PROPERTIES, "&Pattern properties..."); } + if (pSndFile->GetType() == MOD_TYPE_MPT) + { + AppendMenu(hMenu, MF_SEPARATOR, NULL, ""); + + HMENU menuSequence = ::CreatePopupMenu(); + AppendMenu(hMenu, MF_POPUP, (UINT_PTR)menuSequence, TEXT("Sequences")); + + const SEQUENCEINDEX numSequences = pSndFile->Order.GetNumSequences(); + for(SEQUENCEINDEX i = 0; i < numSequences; i++) + { + CString str; + str.Format(TEXT("%u: %s"), i, (LPCTSTR)pSndFile->Order.GetSequence(i).m_sName); + const UINT flags = (pSndFile->Order.GetCurrentSequenceIndex() == i) ? MF_STRING|MF_CHECKED : MF_STRING; + AppendMenu(menuSequence, flags, ID_SEQUENCE_ITEM + i, str); + } + if (pSndFile->Order.GetNumSequences() < MAX_SEQUENCES) + AppendMenu(menuSequence, MF_STRING, ID_SEQUENCE_ITEM + MAX_SEQUENCES, TEXT("Create new sequence")); + if (pSndFile->Order.GetNumSequences() > 1) + AppendMenu(menuSequence, MF_STRING, ID_SEQUENCE_ITEM + MAX_SEQUENCES + 1, TEXT("Delete current sequence")); + } } AppendMenu(hMenu, MF_SEPARATOR, NULL, ""); AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_RENDER, "Render to &Wave"); @@ -857,7 +921,7 @@ void COrderList::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar*) //-------------------------------------------------------------- { - ORDERINDEX nNewPos = m_nXScroll; + UINT nNewPos = m_nXScroll; UINT smin, smax; GetScrollRange(SB_HORZ, (LPINT)&smin, (LPINT)&smax); @@ -874,9 +938,9 @@ case SB_ENDSCROLL: m_bScrolling = false; break; } if (nNewPos > smax) nNewPos = smax; - if (nNewPos != (UINT)m_nXScroll) + if (nNewPos != m_nXScroll) { - m_nXScroll = nNewPos; + m_nXScroll = static_cast<ORDERINDEX>(nNewPos); SetScrollPos(SB_HORZ, m_nXScroll); InvalidateRect(NULL, FALSE); } @@ -886,17 +950,17 @@ void COrderList::OnSize(UINT nType, int cx, int cy) //------------------------------------------------- { - ORDERINDEX nPos; + int nPos; int smin, smax; CWnd::OnSize(nType, cx, cy); UpdateScrollInfo(); GetScrollRange(SB_HORZ, &smin, &smax); - nPos = (ORDERINDEX)GetScrollPos(SB_HORZ); + nPos = GetScrollPos(SB_HORZ); if (nPos > smax) nPos = smax; if (m_nXScroll != nPos) { - m_nXScroll = nPos; + m_nXScroll = static_cast<ORDERINDEX>(nPos); SetScrollPos(SB_HORZ, m_nXScroll); InvalidateRect(NULL, FALSE); } @@ -916,25 +980,26 @@ for(ORDERINDEX i = 0; i <= nInsertCount; i++) { - //Checking whether there is some pattern at the end of orderlist. - if(pSndFile->Order[pSndFile->Order.size() - 1] < pSndFile->Patterns.Size()) + if (pSndFile->Order.GetLength() < 1 || pSndFile->Order.Last() < pSndFile->Patterns.Size()) { - if(pSndFile->Order.size() < pSndFile->GetModSpecifications().ordersMax) - pSndFile->Order.push_back(pSndFile->Order.GetInvalidPatIndex()); + if(pSndFile->Order.GetLength() < pSndFile->GetModSpecifications().ordersMax) + pSndFile->Order.Append(); } - - for(int j = pSndFile->Order.size() - 1; j > nInsertEnd; j--) pSndFile->Order[j] = pSndFile->Order[j - 1]; + for(int j = pSndFile->Order.GetLastIndex(); j > nInsertEnd; j--) + pSndFile->Order[j] = pSndFile->Order[j - 1]; } // now that there is enough space in the order list, overwrite the orders for(ORDERINDEX i = 0; i <= nInsertCount; i++) { - if(nInsertEnd + i + 1 < pSndFile->GetModSpecifications().ordersMax) + if(nInsertEnd + i + 1 < pSndFile->GetModSpecifications().ordersMax + && + nInsertEnd + i + 1 < pSndFile->Order.GetLength()) pSndFile->Order[nInsertEnd + i + 1] = pSndFile->Order[nInsertEnd - nInsertCount + i]; } - m_nScrollPos = min(nInsertEnd + 1, pSndFile->Order.GetCount() - 1); + m_nScrollPos = min(nInsertEnd + 1, pSndFile->Order.GetLastIndex()); if(nInsertCount > 0) - m_nScrollPos2nd = min(m_nScrollPos + nInsertCount, pSndFile->Order.GetCount() - 1); + m_nScrollPos2nd = min(m_nScrollPos + nInsertCount, pSndFile->Order.GetLastIndex()); else m_nScrollPos2nd = ORDERINDEX_INVALID; InvalidateRect(NULL, FALSE); @@ -1053,7 +1118,7 @@ //----------------------------------------------------------------- { LPDRAGONDROP pDropInfo = (LPDRAGONDROP)lParam; - UINT posdest; + ORDERINDEX posdest; BOOL bCanDrop; CSoundFile *pSndFile; CPoint pt; @@ -1073,8 +1138,8 @@ GetCursorPos(&pt); ScreenToClient(&pt); if (pt.x < 0) pt.x = 0; - posdest = m_nXScroll + (pt.x / m_cxFont); - if (posdest >= pSndFile->Order.size()) return FALSE; + posdest = static_cast<ORDERINDEX>(m_nXScroll + (pt.x / m_cxFont)); + if (posdest >= pSndFile->Order.GetLength()) return FALSE; switch(pDropInfo->dwDropType) { case DRAGONDROP_PATTERN: Modified: trunk/OpenMPT/mptrack/Draw_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Draw_pat.cpp 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/mptrack/Draw_pat.cpp 2009-09-16 19:05:00 UTC (rev 366) @@ -620,7 +620,7 @@ ORDERINDEX nNextOrder; nNextOrder = pSndFile->Order.GetNextOrderIgnoringSkips(startOrder); //Ignore skip items(+++) from sequence. - const ORDERINDEX ordCount = pSndFile->Order.GetCount(); + const ORDERINDEX ordCount = pSndFile->Order.GetLength(); if ((nNextOrder < ordCount) && (pSndFile->Order[startOrder] == m_nPattern)) { Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-16 19:05:00 UTC (rev 366) @@ -2977,7 +2977,7 @@ //ensure order correlates with pattern. if (pSndFile->Order[ord]!=pat) { ORDERINDEX tentativeOrder = pSndFile->FindOrder(pat); - if (tentativeOrder != -1) { //ensure a valid order exists. + if (tentativeOrder != ORDERINDEX_INVALID) { //ensure a valid order exists. ord = tentativeOrder; } } Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-16 19:05:00 UTC (rev 366) @@ -940,6 +940,12 @@ BOOL CModDoc::RemoveUnusedPatterns(BOOL bRemove) //---------------------------------------------- { + if (GetSoundFile()->GetType() == MOD_TYPE_MPT && GetSoundFile()->Order.GetNumSequences() > 1) + { // Multiple sequences are not taken into account in the code below. For now just make + // removing unused patterns disabled in this case. + AfxMessageBox(IDS_PATTERN_CLEANUP_UNAVAILABLE, MB_ICONINFORMATION); + return FALSE; + } const UINT maxPatIndex = m_SndFile.Patterns.Size(); const UINT maxOrdIndex = m_SndFile.Order.size(); vector<UINT> nPatMap(maxPatIndex, 0); @@ -1668,10 +1674,10 @@ //Increasing orderlist size if given order is beyond current limit, //or if the last order already has a pattern. if((nOrd == m_SndFile.Order.size() || - m_SndFile.Order.back() < m_SndFile.Patterns.Size() ) && - m_SndFile.Order.size() < m_SndFile.GetModSpecifications().ordersMax) + m_SndFile.Order.Last() < m_SndFile.Patterns.Size() ) && + m_SndFile.Order.GetLength() < m_SndFile.GetModSpecifications().ordersMax) { - m_SndFile.Order.push_back(m_SndFile.Order.GetInvalidPatIndex()); + m_SndFile.Order.Append(); } for (UINT j=0; j<m_SndFile.Order.size(); j++) Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-16 19:05:00 UTC (rev 366) @@ -2853,9 +2853,6 @@ } - - - LRESULT CViewPattern::OnPlayerNotify(MPTNOTIFICATION *pnotify) //------------------------------------------------------------ { @@ -2897,7 +2894,7 @@ } */ - if (pSndFile->Order[nOrd] != nPat) { + if (nOrd >= pSndFile->Order.GetLength() || pSndFile->Order[nOrd] != nPat) { //order doesn't correlate with pattern, so mark it as invalid nOrd = 0xFFFF; } Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2009-09-16 19:05:00 UTC (rev 366) @@ -688,8 +688,12 @@ if ((pInfo->hOrders) && (hintFlagPart != HINT_INSNAMES) && (hintFlagPart != HINT_SMPNAMES)) { const DWORD nPat = (lHint >> HINT_SHIFT_PAT); - pInfo->tiOrders.resize(pSndFile->Order.size(), NULL); - UINT imin=0, imax=pSndFile->Order.size()-1; + // If there are items past the new sequence length, delete them. + for(size_t i = pSndFile->Order.GetLength(); i < pInfo->tiOrders.size(); i++) if (pInfo->tiOrders[i]) + {DeleteItem(pInfo->tiOrders[i]); pInfo->tiOrders[i] = NULL;} + if (pInfo->tiOrders.size() < pSndFile->Order.GetLength()) // Resize tiOrders if needed. + pInfo->tiOrders.resize(pSndFile->Order.GetLength(), NULL); + UINT imin=0, imax = pSndFile->Order.GetLastIndex(); const bool patNamesOnly = (hintFlagPart == HINT_PATNAMES); //if (hintFlagPart == HINT_PATNAMES) && (dwHintParam < pSndFile->Order.size())) imin = imax = dwHintParam; BOOL bEnded = FALSE; @@ -1260,53 +1264,53 @@ //-------------------------------------------- { DWORD dwItemType = GetModItem(hItem); - DWORD dwItem = dwItemType >> 16; + WORD nItem = WORD(dwItemType >> 16); PMODTREEDOCINFO pInfo = DocInfo[m_nDocNdx]; CModDoc *pModDoc = (pInfo) ? pInfo->pModDoc : NULL; switch(dwItemType & 0xFFFF) { case MODITEM_ORDER: - if ((pModDoc) && (pModDoc->RemoveOrder(dwItem))) + if ((pModDoc) && (pModDoc->RemoveOrder(nItem))) { pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, NULL); } break; case MODITEM_PATTERN: - if ((pModDoc) && (pModDoc->RemovePattern(dwItem))) + if ((pModDoc) && (pModDoc->RemovePattern(nItem))) { //pModDoc->UpdateAllViews(NULL, (dwItem << 16)|HINT_PATTERNDATA|HINT_PATNAMES); - pModDoc->UpdateAllViews(NULL, (dwItem << HINT_SHIFT_PAT) | HINT_PATTERNDATA|HINT_PATNAMES); + pModDoc->UpdateAllViews(NULL, (UINT(nItem) << HINT_SHIFT_PAT) | HINT_PATTERNDATA|HINT_PATNAMES); } break; case MODITEM_SAMPLE: - if ((pModDoc) && (pModDoc->RemoveSample(dwItem))) + if ((pModDoc) && (pModDoc->RemoveSample(nItem))) { //pModDoc->UpdateAllViews(NULL, (dwItem << 16) | HINT_SMPNAMES|HINT_SAMPLEDATA|HINT_SAMPLEINFO); - pModDoc->UpdateAllViews(NULL, (dwItem << HINT_SHIFT_SMP) | HINT_SMPNAMES|HINT_SAMPLEDATA|HINT_SAMPLEINFO); + pModDoc->UpdateAllViews(NULL, (UINT(nItem) << HINT_SHIFT_SMP) | HINT_SMPNAMES|HINT_SAMPLEDATA|HINT_SAMPLEINFO); } break; case MODITEM_INSTRUMENT: - if ((pModDoc) && (pModDoc->RemoveInstrument(dwItem))) + if ((pModDoc) && (pModDoc->RemoveInstrument(nItem))) { //pModDoc->UpdateAllViews(NULL, (dwItem << 16)|HINT_MODTYPE|HINT_ENVELOPE|HINT_INSTRUMENT); - pModDoc->UpdateAllViews(NULL, (dwItem << HINT_SHIFT_INS) | HINT_MODTYPE|HINT_ENVELOPE|HINT_INSTRUMENT); + pModDoc->UpdateAllViews(NULL, (UINT(nItem) << HINT_SHIFT_INS) | HINT_MODTYPE|HINT_ENVELOPE|HINT_INSTRUMENT); } break; case MODITEM_MIDIINSTRUMENT: - SetMidiInstrument(dwItem, ""); + SetMidiInstrument(nItem, ""); RefreshMidiLibrary(); break; case MODITEM_MIDIPERCUSSION: - SetMidiPercussion(dwItem, ""); + SetMidiPercussion(nItem, ""); RefreshMidiLibrary(); break; case MODITEM_DLSBANK_FOLDER: - CTrackApp::RemoveDLSBank(dwItem); + CTrackApp::RemoveDLSBank(nItem); RefreshDlsBanks(); break; @@ -2147,7 +2151,7 @@ if (pSndFile) { PSNDMIXPLUGIN pPlugin = &pSndFile->m_MixPlugins[dwItemNo]; if (pPlugin) { - bool bypassed = pPlugin->Info.dwInputRouting&MIXPLUG_INPUTF_BYPASS; + bool bypassed = ((pPlugin->Info.dwInputRouting&MIXPLUG_INPUTF_BYPASS) != 0); AppendMenu(hMenu, (bypassed?MF_CHECKED:0)|MF_STRING, ID_MODTREE_MUTE, "&Bypass"); } } Modified: trunk/OpenMPT/mptrack/View_tre.h =================================================================== --- trunk/OpenMPT/mptrack/View_tre.h 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/mptrack/View_tre.h 2009-09-16 19:05:00 UTC (rev 366) @@ -61,7 +61,7 @@ if(pSndFile != NULL) { tiPatterns.resize(pSndFile->Patterns.Size(), NULL); - tiOrders.resize(pSndFile->Order.size(), NULL); + tiOrders.resize(pSndFile->Order.GetLength(), NULL); } memset(tiSamples, 0, sizeof(tiSamples)); memset(tiInstruments, 0, sizeof(tiInstruments)); Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/mptrack/mptrack.rc 2009-09-16 19:05:00 UTC (rev 366) @@ -358,8 +358,8 @@ CONTROL "Follow Song",IDC_PATTERN_FOLLOWSONG,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | BS_FLAT,432,34,55,10 COMBOBOX IDC_COMBO_INSTRUMENT,22,74,95,137,CBS_DROPDOWNLIST | WS_VSCROLL CTEXT "Row spacing",IDC_STATIC,172,32,54,12,SS_CENTERIMAGE,WS_EX_STATICEDGE - EDITTEXT IDC_EDIT_SPACING,225,32,40,12,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_TABSTOP - CONTROL "Spin1",IDC_SPIN_SPACING,"msctls_updown32",UDS_WRAP | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,256,33,9,11 + EDITTEXT IDC_EDIT_SPACING,225,32,28,12,ES_AUTOHSCROLL | ES_NUMBER | NOT WS_TABSTOP + CONTROL "Spin1",IDC_SPIN_SPACING,"msctls_updown32",UDS_WRAP | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,245,32,11,11 PUSHBUTTON "<<",IDC_BUTTON2,2,99,14,15,NOT WS_TABSTOP,WS_EX_STATICEDGE PUSHBUTTON ">>",IDC_BUTTON1,14,99,14,15,NOT WS_TABSTOP,WS_EX_STATICEDGE CTEXT "Pattern name",IDC_STATIC,9,32,52,12,SS_CENTERIMAGE,WS_EX_STATICEDGE @@ -380,9 +380,11 @@ GROUPBOX "Keyboard Split",IDC_STATIC,167,53,328,40 LTEXT "Octave shift",IDC_STATIC,382,65,52,8 GROUPBOX "",IDC_STATIC,2,22,493,27 - CONTROL "Loop Pattern",IDC_PATTERN_LOOP,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | BS_FLAT | WS_TABSTOP,355,34,57,10 + CONTROL "Loop Pattern",IDC_PATTERN_LOOP,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | BS_FLAT | WS_TABSTOP,370,34,55,10 EDITTEXT IDC_EDIT_ORDERLIST_MARGINS,2,113,28,12,ES_AUTOHSCROLL | ES_READONLY CONTROL "",IDC_SPIN_ORDERLIST_MARGINS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,15,118,11,11 + EDITTEXT IDC_EDIT_SEQUENCE_NAME,317,32,47,12,ES_AUTOHSCROLL + CTEXT "Sequence name",IDC_STATIC_SEQUENCE_NAME,261,32,55,12,SS_CENTERIMAGE,WS_EX_STATICEDGE END IDD_CONTROL_SAMPLES DIALOGEX 0, 0, 544, 106 @@ -2211,6 +2213,9 @@ IDS_UNABLE_TO_LOAD_KEYBINDINGS "Loading keybindings failed. The keyboard won't work properly." IDS_CANT_OPEN_FILE_FOR_WRITING "Can't open file for writing." + IDS_CONFIRM_SEQUENCE_DELETE "Delete sequence %1?" + IDS_PATTERN_CLEANUP_UNAVAILABLE + "Removing unused patterns is not available when using multiple sequences." END #endif // English (U.S.) resources Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/mptrack/resource.h 2009-09-16 19:05:00 UTC (rev 366) @@ -50,6 +50,8 @@ #define IDS_CANT_OPEN_KEYBINDING_FILE 211 #define IDS_UNABLE_TO_LOAD_KEYBINDINGS 212 #define IDS_CANT_OPEN_FILE_FOR_WRITING 213 +#define IDS_CONFIRM_SEQUENCE_DELETE 214 +#define IDS_PATTERN_CLEANUP_UNAVAILABLE 215 #define IDB_MAINBAR 300 #define IDB_IMAGELIST 301 #define IDB_PATTERNS 302 @@ -885,6 +887,8 @@ #define IDC_CHECK_PATRECORD 2386 #define IDC_LOAD_COLORSCHEME 2387 #define IDC_SAVE_COLORSCHEME 2388 +#define IDC_EDIT_SEQUENCE_NAME 2389 +#define IDC_STATIC_SEQUENCE_NAME 2390 #define ID_FILE_NEWMOD 32771 #define ID_FILE_NEWXM 32772 #define ID_FILE_NEWS3M 32773 @@ -1078,6 +1082,7 @@ #define ID_CLEAR_SELECTION 38000 #define ID_PLUG_PASSKEYS 38001 #define ID_VIEW_SONGPROPERTIES 38002 +#define ID_SEQUENCE_ITEM 38003 #define ID_GROW_SELECTION 40001 #define ID_SHRINK_SELECTION 40002 #define ID_RUN_SCRIPT 40003 @@ -1127,7 +1132,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 521 #define _APS_NEXT_COMMAND_VALUE 59230 -#define _APS_NEXT_CONTROL_VALUE 2389 +#define _APS_NEXT_CONTROL_VALUE 2391 #define _APS_NEXT_SYMED_VALUE 901 #endif #endif Modified: trunk/OpenMPT/mptrack/serialization_utils.cpp =================================================================== --- trunk/OpenMPT/mptrack/serialization_utils.cpp 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/mptrack/serialization_utils.cpp 2009-09-16 19:05:00 UTC (rev 366) @@ -131,15 +131,15 @@ } -void WriteItemString(OutStream& oStrm, const std::string& str) -//------------------------------------------------------------ +void WriteItemString(OutStream& oStrm, const char* const pStr, const size_t nSize) +//-------------------------------------------------------------------------------- { - uint32 id = (std::min)(str.size(), (uint32_max >> 4)) << 4; + uint32 id = (std::min)(nSize, (uint32_max >> 4)) << 4; id |= 12; // 12 == 1100b Binarywrite<uint32>(oStrm, id); id >>= 4; if(id > 0) - oStrm.write(str.c_str(), id); + oStrm.write(pStr, id); } Modified: trunk/OpenMPT/mptrack/serialization_utils.h =================================================================== --- trunk/OpenMPT/mptrack/serialization_utils.h 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/mptrack/serialization_utils.h 2009-09-16 19:05:00 UTC (rev 366) @@ -344,11 +344,13 @@ Binarywrite(oStrm, data); } -void WriteItemString(OutStream& oStrm, const std::string& str); +void WriteItemString(OutStream& oStrm, const char* const pStr, const size_t nSize); template <> -inline void WriteItem<std::string>(OutStream& oStrm, const std::string& str) {WriteItemString(oStrm, str);} +inline void WriteItem<std::string>(OutStream& oStrm, const std::string& str) {WriteItemString(oStrm, str.c_str(), str.length());} +template <> +inline void WriteItem<LPCSTR>(OutStream& oStrm, const LPCSTR& psz) {WriteItemString(oStrm, psz, strlen(psz));} template<class T> inline void Binaryread(InStream& iStrm, T& data) @@ -416,6 +418,25 @@ ReadItemString(iStrm, str, nSize); } + +template <class T> +struct ArrayWriter +//================ +{ + ArrayWriter(size_t nCount) : m_nCount(nCount) {} + void operator()(srlztn::OutStream& oStrm, const T* pData) {oStrm.write(reinterpret_cast<const char*>(pData), m_nCount * sizeof(T));} + size_t m_nCount; +}; + +template <class T> +struct ArrayReader +//================ +{ + ArrayReader(size_t nCount) : m_nCount(nCount) {} + void operator()(srlztn::InStream& iStrm, T* pData, const size_t) {iStrm.read(reinterpret_cast<char*>(pData), m_nCount * sizeof(T));} + size_t m_nCount; +}; + } //namespace srlztn. Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-16 19:05:00 UTC (rev 366) @@ -1004,8 +1004,8 @@ Order.ReadAsByte(lpStream + dwMemPos, nordsize, dwMemLength - dwMemPos); dwMemPos += pifh->ordnum; //Replacing 0xFF and 0xFE with new corresponding indexes - replace(Order.begin(), Order.end(), static_cast<PATTERNINDEX>(0xFE), Order.GetIgnoreIndex()); - replace(Order.begin(), Order.end(), static_cast<PATTERNINDEX>(0xFF), Order.GetInvalidPatIndex()); + Order.Replace(0xFE, Order.GetIgnoreIndex()); + Order.Replace(0xFF, Order.GetInvalidPatIndex()); } } @@ -1493,8 +1493,9 @@ ssb.BeginRead("mptm", 1); ssb.ReadItem(GetTuneSpecificTunings(), "0", 1, &ReadTuningCollection); ssb.ReadItem(*this, "1", 1, &ReadTuningMap); - ssb.ReadItem(Order, "2", 1, &ReadModSequence); + ssb.ReadItem(Order, "2", 1, &ReadModSequenceOld); ssb.ReadItem(Patterns, FileIdPatterns, strlen(FileIdPatterns), &ReadModPatterns); + ssb.ReadItem(Order, FileIdSequences, strlen(FileIdSequences), &ReadModSequences); if (ssb.m_Status & srlztn::SNT_FAILURE) AfxMessageBox("Unknown error occured.", MB_ICONERROR); @@ -2421,9 +2422,10 @@ if (AreNonDefaultTuningsUsed(*this)) ssb.WriteItem(*this, "1", 1, &WriteTuningMap); if (Order.NeedsExtraDatafield()) - ssb.WriteItem(Order, "2", 1, &WriteModSequence); + ssb.WriteItem(Order, "2", 1, &WriteModSequenceOld); if (bNeedsMptPatSave) ssb.WriteItem(Patterns, FileIdPatterns, strlen(FileIdPatterns), &WriteModPatterns); + ssb.WriteItem(Order, FileIdSequences, strlen(FileIdSequences), &WriteModSequences); ssb.FinishWrite(); @@ -3463,6 +3465,9 @@ code = 'MPTX'; // write extension header code fwrite(&code, 1, sizeof(__int32), f); + + if (nInstruments == 0) + return; WriteInstrumentPropertyForAllInstruments('VR..', sizeof(m_defaultInstrument.nVolRamp), f, instruments, nInstruments); WriteInstrumentPropertyForAllInstruments('MiP.', sizeof(m_defaultInstrument.nMixPlug), f, instruments, nInstruments); Modified: trunk/OpenMPT/soundlib/Load_psm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-09-16 19:05:00 UTC (rev 366) @@ -259,7 +259,7 @@ // every pattern in the order will be unique, so store the pointer + pattern ID orderOffsets.push_back(patternOffsets[i]); - Order.push_back(numPatterns); + Order.Append(numPatterns); numPatterns++; break; } @@ -359,7 +359,7 @@ } // separate subsongs by "---" patterns orderOffsets.push_back(nullptr); - Order.push_back(Order.GetInvalidPatIndex()); + Order.Append(); } break; Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-09-16 19:05:00 UTC (rev 366) @@ -737,8 +737,8 @@ header.norder++; if ((Order[i] >= header.patterns) && (Order[i] < MAX_PATTERNS)) header.patterns = Order[i]+1; }*/ - if(Order.GetCount() < MAX_ORDERS) - Order.resize(MAX_ORDERS, Order.GetInvalidPatIndex()); + if(Order.GetLength() < MAX_ORDERS) + Order.resize(MAX_ORDERS); for (i=MAX_ORDERS-1; i>=0; i--) { // walk backwards over orderlist if ((Order[i]!=0xFF) && (header.norder==0)) { Modified: trunk/OpenMPT/soundlib/ModSequence.cpp =================================================================== --- trunk/OpenMPT/soundlib/ModSequence.cpp 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/soundlib/ModSequence.cpp 2009-09-16 19:05:00 UTC (rev 366) @@ -1,127 +1,96 @@ #include "stdafx.h" #include "sndfile.h" #include "ModSequence.h" +#include "../mptrack/version.h" #include "../mptrack/serialization_utils.h" #define str_SequenceTruncationNote (GetStrI18N((_TEXT("Module has sequence of length %u; it will be truncated to maximum supported length, %u.")))) -DWORD COrderToPatternTable::Deserialize(const BYTE* const src, const DWORD memLength) -//------------------------------------------------------------------------- -{ - if(memLength < 2 + 4) return 0; - uint16 version = 0; - uint32 s = 0; - DWORD memPos = 0; - memcpy(&version, src, sizeof(version)); - memPos += sizeof(version); - if(version != 0) return memPos; - memcpy(&s, src+memPos, sizeof(s)); - memPos += sizeof(s); - if(s > 65000) return true; - if(memLength < memPos+s*4) return memPos; +#define new DEBUG_NEW - const uint32 nOriginalSize = s; - if(s > ModSpecs::mptm.ordersMax) - s = ModSpecs::mptm.ordersMax; - resize(max(s, MAX_ORDERS)); - for(size_t i = 0; i<s; i++, memPos +=4 ) - { - uint32 temp; - memcpy(&temp, src+memPos, 4); - (*this)[i] = static_cast<PATTERNINDEX>(temp); - } - memPos += 4*(nOriginalSize - s); - return memPos; -} +ModSequence::ModSequence(const CSoundFile& rSf, + PATTERNINDEX* pArray, + ORDERINDEX nSize, + ORDERINDEX nCapacity, + const bool bDeletableArray) : + m_pSndFile(&rSf), + m_pArray(pArray), + m_nSize(nSize), + m_nCapacity(nCapacity), + m_bDeletableArray(bDeletableArray), + m_nInvalidIndex(0xFF), + m_nIgnoreIndex(0xFE) +//------------------------------------------------------- +{} -size_t COrderToPatternTable::WriteToByteArray(BYTE* dest, const UINT numOfBytes, const UINT destSize) -//----------------------------------------------------------------------------- +ModSequence::ModSequence(const CSoundFile& rSf, ORDERINDEX nSize) : + m_pSndFile(&rSf), + m_bDeletableArray(true), + m_nInvalidIndex(GetInvalidPatIndex(MOD_TYPE_MPT)), + m_nIgnoreIndex(GetIgnoreIndex(MOD_TYPE_MPT)) +//------------------------------------------------------------------- { - if(numOfBytes > destSize) return true; - if(size() < numOfBytes) resize(numOfBytes, 0xFF); - UINT i = 0; - for(i = 0; i<numOfBytes; i++) - { - dest[i] = static_cast<BYTE>((*this)[i]); - } - return i; //Returns the number of bytes written. + m_nSize = nSize; + m_nCapacity = m_nSize; + m_pArray = new PATTERNINDEX[m_nCapacity]; + std::fill(begin(), end(), GetInvalidPatIndex(MOD_TYPE_MPT)); } -size_t COrderToPatternTable::WriteAsByte(FILE* f, const UINT count) -//--------------------------------------------------------------- +ModSequence::ModSequence(const ModSequence& seq) : + m_pSndFile(seq.m_pSndFile), + m_bDeletableArray(false), + m_nInvalidIndex(0xFF), + m_nIgnoreIndex(0xFE), + m_nSize(0), + m_nCapacity(0), + m_pArray(nullptr) +//------------------------------------------ { - if(size() < count) resize(count, GetInvalidPatIndex()); - - size_t i = 0; - - for(i = 0; i<count; i++) - { - const PATTERNINDEX pat = (*this)[i]; - BYTE temp = static_cast<BYTE>((*this)[i]); - - if(pat > 0xFD) - { - if(pat == GetInvalidPatIndex()) temp = 0xFF; - else temp = 0xFE; - } - fwrite(&temp, 1, 1, f); - } - return i; //Returns the number of bytes written. + *this = seq; } -bool COrderToPatternTable::ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength) -//------------------------------------------------------------------------- -{ - if(howMany < 0 || howMany > memLength) return true; - if(m_rSndFile.GetType() != MOD_TYPE_MPT && howMany > MAX_ORDERS) return true; - - if(size() < static_cast<size_t>(howMany)) - resize(howMany, GetInvalidPatIndex()); - - for(int i = 0; i<howMany; i++, pFrom++) - (*this)[i] = *pFrom; - return false; -} - -bool COrderToPatternTable::NeedsExtraDatafield() const -//---------------------------------------------- +bool ModSequence::NeedsExtraDatafield() const +//------------------------------------------- { - if(m_rSndFile.GetType() == MOD_TYPE_MPT && m_rSndFile.Patterns.Size() > 0xFD) + if(m_pSndFile->GetType() == MOD_TYPE_MPT && m_pSndFile->Patterns.Size() > 0xFD) return true; else return false; } -void COrderToPatternTable::OnModTypeChanged(const MODTYPE oldtype) -//---------------------------------------------------------------- +void ModSequence::OnModTypeChanged(const MODTYPE oldtype) +//------------------------------------------------------- { - const CModSpecifications specs = m_rSndFile.GetModSpecifications(); + const CModSpecifications specs = m_pSndFile->GetModSpecifications(); + m_nInvalidIndex = GetInvalidPatIndex(m_pSndFile->GetType()); + m_nIgnoreIndex = GetIgnoreIndex(m_pSndFile->GetType()); + //Resize orderlist if needed. Because old orderlist had MAX_ORDERS(256) elements, not making it //smaller than that even if the modtype doesn't support that many orders. - if(specs.ordersMax < GetCount()) + if (specs.ordersMax < GetLength()) { resize(max(MAX_ORDERS, specs.ordersMax)); - for(ORDERINDEX i = GetCount(); i>specs.ordersMax; --i) (*this)[i-1] = GetInvalidPatIndex(); + std::fill(begin() + specs.ordersMax, end(), GetInvalidPatIndex()); } - if (GetCount() < MAX_ORDERS) - resize(MAX_ORDERS, GetInvalidPatIndex()); + if (GetLength() < MAX_ORDERS) + resize(MAX_ORDERS, GetInvalidPatIndex(oldtype)); //Replace items used to denote end of song/skip order. - replace(begin(), end(), GetInvalidPatIndex(oldtype), GetInvalidPatIndex()); - replace(begin(), end(), GetIgnoreIndex(oldtype), GetIgnoreIndex()); + Replace(GetInvalidPatIndex(oldtype), GetInvalidPatIndex()); + Replace(GetIgnoreIndex(oldtype), GetIgnoreIndex()); } -ORDERINDEX COrderToPatternTable::GetLengthTailTrimmed() const -//----------------------------------------------------------- +ORDERINDEX ModSequence::GetLengthTailTrimmed() const +//-------------------------------------------------- { - ORDERINDEX nEnd = GetCount(); + ORDERINDEX nEnd = GetLength(); if(nEnd == 0) return 0; nEnd--; const PATTERNINDEX iInvalid = GetInvalidPatIndex(); @@ -131,59 +100,275 @@ } -ORDERINDEX COrderToPatternTable::GetLengthFirstEmpty() const -//---------------------------------------------------------- +ORDERINDEX ModSequence::GetLengthFirstEmpty() const +//------------------------------------------------- { - const ORDERINDEX nLength = GetCount(); - ORDERINDEX nMax = 0; - while ((nMax < nLength) && ((*this)[nMax] != (*this).GetInvalidPatIndex())) nMax++; - return nMax; + return static_cast<ORDERINDEX>(std::find(begin(), end(), GetInvalidPatIndex()) - begin()); } -ORDERINDEX COrderToPatternTable::GetNextOrderIgnoringSkips(const ORDERINDEX start) const -//------------------------------------------------------------------------------------- +ORDERINDEX ModSequence::GetNextOrderIgnoringSkips(const ORDERINDEX start) const +//----------------------------------------------------------------------------- { - const ORDERINDEX count = GetCount(); - if(count == 0) return 0; - ORDERINDEX next = min(count-1, start+1); - while(next+1 < count && (*this)[next] == GetIgnoreIndex()) next++; + const ORDERINDEX nLength = GetLength(); + if(nLength == 0) return 0; + ORDERINDEX next = min(nLength-1, start+1); + while(next+1 < nLength && (*this)[next] == GetIgnoreIndex()) next++; return next; } -ORDERINDEX COrderToPatternTable::GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const -//------------------------------------------------------------------------------------- + +ORDERINDEX ModSequence::GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const +//--------------------------------------------------------------------------------- { - const ORDERINDEX count = GetCount(); - if(start == 0 || count == 0) return 0; - ORDERINDEX prev = min(start-1, count-1); + const ORDERINDEX nLength = GetLength(); + if(start == 0 || nLength == 0) return 0; + ORDERINDEX prev = min(start-1, nLength-1); while(prev > 0 && (*this)[prev] == GetIgnoreIndex()) prev--; return prev; } -void COrderToPatternTable::Init() -//------------------------------- +void ModSequence::Init() +//---------------------- { - resize(MAX_ORDERS, GetInvalidPatIndex()); - for(ORDERINDEX i = 0; i < GetCount(); i++) + resize(MAX_ORDERS); + std::fill(begin(), end(), GetInvalidPatIndex()); +} + + +void ModSequence::Append(PATTERNINDEX nPat) +//----------------------------------------- +{ + resize(m_nSize + 1, nPat); +} + + +void ModSequence::resize(ORDERINDEX nNewSize, PATTERNINDEX nFill) +//--------------------------------------------------------------- +{ + if (nNewSize == m_nSize) return; + if (nNewSize <= m_nCapacity) { - (*this)[i] = GetInvalidPatIndex(); + if (nNewSize > m_nSize) + std::fill(begin() + m_nSize, begin() + nNewSize, nFill); + m_nSize = nNewSize; } + else + { + const PATTERNINDEX* const pOld = m_pArray; + m_nCapacity = nNewSize + 100; + m_pArray = new PATTERNINDEX[m_nCapacity]; + ArrayCopy(m_pArray, pOld, m_nSize); + std::fill(m_pArray + m_nSize, m_pArray + nNewSize, nFill); + m_nSize = nNewSize; + if (m_bDeletableArray) + delete[] pOld; + m_bDeletableArray = true; + } } +void ModSequence::clear() +//----------------------- +{ + m_nSize = 0; +} -PATTERNINDEX COrderToPatternTable::GetInvalidPatIndex(const MODTYPE type) {return type == MOD_TYPE_MPT ? 65535 : 0xFF;} -PATTERNINDEX COrderToPatternTable::GetIgnoreIndex(const MODTYPE type) {return type == MOD_TYPE_MPT ? 65534 : 0xFE;} -PATTERNINDEX COrderToPatternTable::GetInvalidPatIndex() const {return GetInvalidPatIndex(m_rSndFile.GetType());} -PATTERNINDEX COrderToPatternTable::GetIgnoreIndex() const {return GetIgnoreIndex(m_rSndFile.GetType());} +ModSequence& ModSequence::operator=(const ModSequence& seq) +//--------------------------------------------------------- +{ + if (&seq == this) + return *this; + m_nIgnoreIndex = seq.m_nIgnoreIndex; + m_nInvalidIndex = seq.m_nInvalidIndex; + resize(seq.GetLength()); + ArrayCopy(begin(), seq.begin(), m_nSize); + m_sName = seq.m_sName; + return *this; +} -void ReadModSequence(std::istream& iStrm, COrderToPatternTable& seq, const size_t) -//-------------------------------------------------------------------------------- + +///////////////////////////////////// +// ModSequenceSet +///////////////////////////////////// + + +ModSequenceSet::ModSequenceSet(const CSoundFile& sndFile) + : ModSequence(sndFile, m_Cache, s_nCacheSize, s_nCacheSize, NoArrayDelete), + m_nCurrentSeq(0) +//------------------------------------------------------------------- { + m_Sequences.push_back(ModSequence(sndFile, s_nCacheSize)); +} + + +const ModSequence& ModSequenceSet::GetSequence(SEQUENCEINDEX nSeq) +//---------------------------------------------------------------- +{ + if (nSeq == GetCurrentSequenceIndex()) + CopyCacheToStorage(); + return m_Sequences[nSeq]; +} + + +void ModSequenceSet::CopyCacheToStorage() +//--------------------------------------- +{ + m_Sequences[m_nCurrentSeq] = *this; +} + + +void ModSequenceSet::CopyStorageToCache() +//--------------------------------------- +{ + const ModSequence& rSeq = m_Sequences[m_nCurrentSeq]; + if (rSeq.GetLength() <= s_nCacheSize) + { + PATTERNINDEX* pOld = m_pArray; + m_pArray = m_Cache; + m_nSize = rSeq.GetLength(); + m_nCapacity = s_nCacheSize; + m_sName = rSeq.m_sName; + ArrayCopy(m_pArray, rSeq.m_pArray, m_nSize); + if (m_bDeletableArray) + delete[] pOld; + m_bDeletableArray = false; + } + else + ModSequence::operator=(rSeq); +} + + +void ModSequenceSet::SetSequence(SEQUENCEINDEX n) +//----------------------------------------------- +{ + CopyCacheToStorage(); + m_nCurrentSeq = n; + CopyStorageToCache(); +} + + +void ModSequenceSet::AddSequence(bool bDuplicate) +//----------------------------------------------- +{ + m_Sequences.push_back(ModSequence(*m_pSndFile, s_nCacheSize)); + if (bDuplicate) + { + m_Sequences.back() = *this; + m_Sequences.back().m_sName = ""; // Don't copy sequence name. + } + SetSequence(GetNumSequences() - 1); +} + + +void ModSequenceSet::RemoveSequence(SEQUENCEINDEX i) +//-------------------------------------------------- +{ + // Do nothing if index is invalid or if there's only one sequence left. + if (i >= m_Sequences.size() || m_Sequences.size() <= 1) + return; + const bool bSequenceChanges = (i == m_nCurrentSeq); + m_Sequences.erase(m_Sequences.begin() + i); + if (i < m_nCurrentSeq || m_nCurrentSeq >= GetNumSequences()) + m_nCurrentSeq--; + if (bSequenceChanges) + CopyStorageToCache(); +} + + +///////////////////////////////////// +// Read/Write +///////////////////////////////////// + + +DWORD ModSequence::Deserialize(const BYTE* const src, const DWORD memLength) +//-------------------------------------------------------------------------- +{ + if(memLength < 2 + 4) return 0; + uint16 version = 0; + uint16 s = 0; + DWORD memPos = 0; + memcpy(&version, src, sizeof(version)); + memPos += sizeof(version); + if(version != 0) return memPos; + memcpy(&s, src+memPos, sizeof(s)); + memPos += 4; + if(s > 65000) return true; + if(memLength < memPos+s*4) return memPos; + + const uint16 nOriginalSize = s; + LimitMax(s, ModSpecs::mptm.ordersMax); + + resize(max(s, MAX_ORDERS)); + for(size_t i = 0; i<s; i++, memPos +=4 ) + { + uint32 temp; + memcpy(&temp, src+memPos, 4); + (*this)[i] = static_cast<PATTERNINDEX>(temp); + } + memPos += 4*(nOriginalSize - s); + return memPos; +} + + +size_t ModSequence::WriteToByteArray(BYTE* dest, const UINT numOfBytes, const UINT destSize) +//----------------------------------------------------------------------------- +{ + if(numOfBytes > destSize || numOfBytes > MAX_ORDERS) return true; + if(GetLength() < numOfBytes) resize(ORDERINDEX(numOfBytes), 0xFF); + UINT i = 0; + for(i = 0; i<numOfBytes; i++) + { + dest[i] = static_cast<BYTE>((*this)[i]); + } + return i; //Returns the number of bytes written. +} + + +size_t ModSequence::WriteAsByte(FILE* f, const uint16 count) +//---------------------------------------------------------- +{ + if(GetLength() < count) resize(count); + + size_t i = 0; + + for(i = 0; i<count; i++) + { + const PATTERNINDEX pat = (*this)[i]; + BYTE temp = static_cast<BYTE>((*this)[i]); + + if(pat > 0xFD) + { + if(pat == GetInvalidPatIndex()) temp = 0xFF; + else temp = 0xFE; + } + fwrite(&temp, 1, 1, f); + } + return i; //Returns the number of bytes written. +} + + +bool ModSequence::ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength) +//------------------------------------------------------------------------------------- +{ + if(howMany < 0 || howMany > memLength) return true; + if(m_pSndFile->GetType() != MOD_TYPE_MPT && howMany > MAX_ORDERS) return true; + + if(GetLength() < static_cast<size_t>(howMany)) + resize(ORDERINDEX(howMany)); + + for(int i = 0; i<howMany; i++, pFrom++) + (*this)[i] = *pFrom; + return false; +} + + +void ReadModSequenceOld(std::istream& iStrm, ModSequenceSet& seq, const size_t) +//----------------------------------------------------------------------------- +{ uint16 size; srlztn::Binaryread<uint16>(iStrm, size); if(size > ModSpecs::mptm.ordersMax) @@ -193,7 +378,7 @@ AfxMessageBox(str, MB_ICONWARNING); size = ModSpecs::mptm.ordersMax; } - seq.resize(max(size, MAX_ORDERS), seq.GetInvalidPatIndex()); + seq.resize(max(size, MAX_ORDERS)); if(size == 0) { seq.Init(); return; } @@ -206,16 +391,91 @@ } -void WriteModSequence(std::ostream& oStrm, const COrderToPatternTable& seq) +void WriteModSequenceOld(std::ostream& oStrm, const ModSequenceSet& seq) //------------------------------------------------------------------------- { - uint16 size = seq.GetCount(); + const uint16 size = seq.GetLength(); srlztn::Binarywrite<uint16>(oStrm, size); - const COrderToPatternTable::const_iterator endIter = seq.end(); - for(COrderToPatternTable::const_iterator citer = seq.begin(); citer != endIter; citer++) + const ModSequenceSet::const_iterator endIter = seq.end(); + for(ModSequenceSet::const_iterator citer = seq.begin(); citer != endIter; citer++) { const uint16 temp = static_cast<uint16>(*citer); srlztn::Binarywrite<uint16>(oStrm, temp); } } + +void WriteModSequence(std::ostream& oStrm, const ModSequence& seq) +//---------------------------------------------------------------- +{ + srlztn::Ssb ssb(oStrm); + ssb.BeginWrite(FileIdSequence, MptVersion::num); + ssb.WriteItem((LPCSTR)seq.m_sName, "n"); + const uint16 nLength = seq.GetLengthTailTrimmed(); + ssb.WriteItem<uint16>(nLength, "l"); + ssb.WriteItem(seq.m_pArray, "a", 1, srlztn::ArrayWriter<uint16>(nLength)); + ssb.FinishWrite(); +} + + +void ReadModSequence(std::istream& iStrm, ModSequence& seq, const size_t) +//----------------------------------------------------------------------- +{ + srlztn::Ssb ssb(iStrm); + ssb.BeginRead(FileIdSequence, MptVersion::num); + if ((ssb.m_Status & srlztn::SNT_FAILURE) != 0) + return; + std::string str; + ssb.ReadItem(str, "n"); + seq.m_sName = str.c_str(); + uint16 nSize = MAX_ORDERS; + ssb.ReadItem<uint16>(nSize, "l"); + LimitMax(nSize, ModSpecs::mptm.ordersMax); + seq.resize(max(nSize, ModSequenceSet::s_nCacheSize)); + ssb.ReadItem(seq.m_pArray, "a", 1, srlztn::ArrayReader<uint16>(nSize)); +} + + +void WriteModSequences(std::ostream& oStrm, const ModSequenceSet& seq) +//-------------------------------------------------------------------- +{ + srlztn::Ssb ssb(oStrm); + ssb.BeginWrite(FileIdSequences, MptVersion::num); + const uint8 nSeqs = seq.GetNumSequences(); + const uint8 nCurrent = seq.GetCurrentSequenceIndex(); + ssb.WriteItem(nSeqs, "n"); + ssb.WriteItem(nCurrent, "c"); + for(uint8 i = 0; i < nSeqs; i++) + { + if (i == seq.GetCurrentSequenceIndex()) + ssb.WriteItem(seq, &i, sizeof(i), &WriteModSequence); + else + ssb.WriteItem(seq.m_Sequences[i], &i, sizeof(i), &WriteModSequence); + } + ssb.FinishWrite(); +} + + +void ReadModSequences(std::istream& iStrm, ModSequenceSet& seq, const size_t) +//--------------------------------------------------------------------------- +{ + srlztn::Ssb ssb(iStrm); + ssb.BeginRead(FileIdSequences, MptVersion::num); + if ((ssb.m_Status & srlztn::SNT_FAILURE) != 0) + return; + uint8 nSeqs; + uint8 nCurrent; + ssb.ReadItem(nSeqs, "n"); + if (nSeqs == 0) + return; + LimitMax(nSeqs, MAX_SEQUENCES); + ssb.ReadItem(nCurrent, "c"); + if (seq.GetNumSequences() < nSeqs) + seq.m_Sequences.resize(nSeqs, ModSequence(*seq.m_pSndFile, seq.s_nCacheSize)); + + for(uint8 i = 0; i < nSeqs; i++) + ssb.ReadItem(seq.m_Sequences[i], &i, sizeof(i), &ReadModSequence); + seq.m_nCurrentSeq = (nCurrent < seq.GetNumSequences()) ? nCurrent : 0; + seq.CopyStorageToCache(); +} + Modified: trunk/OpenMPT/soundlib/ModSequence.h =================================================================== --- trunk/OpenMPT/soundlib/ModSequence.h 2009-09-15 22:10:35 UTC (rev 365) +++ trunk/OpenMPT/soundlib/ModSequence.h 2009-09-16 19:05:00 UTC (rev 366) @@ -1,68 +1,160 @@ -#ifndef ORDERTOPATTERNTABLE_H -#define ORDERTOPATTERNTABLE_H +#ifndef MOD_SEQUENCE_H +#define MOD_SEQUENCE_H #include <vector> -using std::vector; class CSoundFile; +class ModSequenceSet; - -#pragma warning(disable:4244) //conversion from 'type1' to 'type2', possible loss of data. - - -//============================================== -class COrderToPatternTable : public vector<PATTERNINDEX> -//============================================== +class ModSequence +//=============== { public: - COrderToPatternTable(const CSoundFile& sndFile) : m_rSndFile(sndFile) {} + friend class ModSequenceSet; + typedef PATTERNINDEX* iterator; + typedef const PATTERNINDEX* const_iterator; + + friend void WriteModSequence(std::ostream& oStrm, const ModSequence& seq); + friend void ReadModSequence(std::istream& iStrm, ModSequence& seq, const size_t); + virtual ~ModSequence() {if (m_bDeletableArray) delete[] m_pArray;} + ModSequence(const ModSequence&); + ModSequence(const CSoundFile& rSf, ORDERINDEX nSize); + ModSequence(const CSoundFile& rSf, PATTERNINDEX* pArray, ORDERINDEX nSize, ORDERINDEX nCapacity, bool bDeletableArray); + // Initialize default sized sequence. void Init(); - bool ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength); + PATTERNINDEX& operator[](const size_t i) {ASSERT(i < m_nSize); return m_pArray[i];} + const PATTERNINDEX& operator[](const size_t i) const {ASSERT(i < m_nSize); return m_pArray[i];} - size_t WriteAsByte(FILE* f, const UINT count); + PATTERNINDEX& Last() {ASSERT(m_nSize > 0); return m_pArray[m_nSize-1];} + const PATTERNINDEX& L... [truncated message content] |
From: <sag...@us...> - 2009-09-16 22:46:55
|
Revision: 367 http://modplug.svn.sourceforge.net/modplug/?rev=367&view=rev Author: saga-games Date: 2009-09-16 22:46:46 +0000 (Wed, 16 Sep 2009) Log Message: ----------- [Fix] XM Loader: Can now load XM Version 1.02 and 1.03. Made XM Loader and Saver a bit more readable. [Imp] XM Loader: Detect non-mpt modules more reliably [Mod] Color Presets: Use app directory as default directory in file dialog [Ref] Made GetZxxType / CreateZxxFromType static so they can be used in CTrackApp for initialization Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Moptions.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/soundlib/Load_xm.cpp Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-09-16 19:05:00 UTC (rev 366) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-09-16 22:46:46 UTC (rev 367) @@ -181,8 +181,8 @@ int MacroToPlugParam(CString value); //rewbs.xinfo int MacroToMidiCC(CString value); int FindMacroForParam(long param); - int GetZxxType(const CHAR (&szMidiZXXExt)[128 * 32]); - void CreateZxxFromType(CHAR (&szMidiZXXExt)[128 * 32], int iZxxType); + static int GetZxxType(const CHAR (&szMidiZXXExt)[128 * 32]); + static void CreateZxxFromType(CHAR (&szMidiZXXExt)[128 * 32], int iZxxType); void SongProperties(); // operations public: Modified: trunk/OpenMPT/mptrack/Moptions.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moptions.cpp 2009-09-16 19:05:00 UTC (rev 366) +++ trunk/OpenMPT/mptrack/Moptions.cpp 2009-09-16 22:46:46 UTC (rev 367) @@ -562,8 +562,8 @@ "OpenMPT Color Schemes|*.mptcolor|" "All Files (*.*)|*.*||", this); + dlg.m_ofn.lpstrInitialDir = CMainFrame::m_csExecutableDirectoryPath; if (dlg.DoModal() != IDOK) return; - TCHAR sFilename[MAX_PATH]; strcpy(sFilename, dlg.GetPathName()); @@ -584,6 +584,7 @@ OFN_HIDEREADONLY| OFN_ENABLESIZING | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_NOREADONLYRETURN, "OpenMPT Color Schemes|*.mptcolor|", this); + dlg.m_ofn.lpstrInitialDir = CMainFrame::m_csExecutableDirectoryPath; if (dlg.DoModal() != IDOK) return; TCHAR sFilename[MAX_PATH]; Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2009-09-16 19:05:00 UTC (rev 366) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2009-09-16 22:46:46 UTC (rev 367) @@ -622,7 +622,7 @@ strcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_NOTEOFF*32], "9c n 0"); strcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_PROGRAM*32], "Cc p"); strcpy(&m_MidiCfg.szMidiSFXExt[0], "F0F000z"); - for (int iz=0; iz<16; iz++) wsprintf(&m_MidiCfg.szMidiZXXExt[iz*32], "F0F001%02X", iz*8); + CModDoc::CreateZxxFromType(m_MidiCfg.szMidiZXXExt, 1); #ifdef UPDATECHECKENABLED m_pRequestContext = NULL; Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-09-16 19:05:00 UTC (rev 366) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-09-16 22:46:46 UTC (rev 367) @@ -24,16 +24,16 @@ #pragma pack(1) typedef struct tagXMFILEHEADER { - DWORD size; - WORD norder; - WORD restartpos; - WORD channels; - WORD patterns; - WORD instruments; - WORD flags; - WORD speed; - WORD tempo; - BYTE order[256]; + WORD xmversion; // current: 0x0104 + DWORD size; // header size + WORD orders; // number of orders + WORD restartpos; // restart position + WORD channels; // number of channels + WORD patterns; // number of patterns + WORD instruments; // number of instruments + WORD flags; // song flags + WORD speed; // default speed + WORD tempo; // default tempo } XMFILEHEADER; @@ -57,8 +57,13 @@ BYTE vtype, ptype; BYTE vibtype, vibsweep, vibdepth, vibrate; WORD volfade; - WORD res; - BYTE reserved1[20]; + // midi extensions (not read by MPT) + BYTE midienabled; // 0/1 + BYTE midichannel; // 0...15 + WORD midiprogram; // 0...127 + WORD pitchwheelrange; // 0...36 (halftones) + BYTE mutecomputer; // 0/1 + BYTE reserved1[15]; } XMSAMPLEHEADER; typedef struct tagXMSAMPLESTRUCT @@ -77,138 +82,80 @@ #pragma pack() -bool CSoundFile::ReadXM(const BYTE *lpStream, DWORD dwMemLength) -//-------------------------------------------------------------- +// Read .XM patterns +DWORD ReadXMPatterns(const BYTE *lpStream, DWORD dwMemLength, DWORD dwMemPos, XMFILEHEADER *xmheader, CSoundFile *pSndFile) +//------------------------------------------------------------------------------------------------------------------------- { - XMSAMPLEHEADER xmsh; - XMSAMPLESTRUCT xmss; - DWORD dwMemPos, dwHdrSize; - WORD norders=0, restartpos=0, channels=0, patterns=0, instruments=0; - WORD xmflags=0; - BYTE InstUsed[256]; -// -> CODE#0006 -// -> DESC="misc quantity changes" -// BYTE channels_used[MAX_CHANNELS]; - BYTE channels_used[MAX_BASECHANNELS]; -// -! BEHAVIOUR_CHANGE#0006 + BYTE patterns_used[256]; BYTE pattern_map[256]; - BYTE samples_used[(MAX_SAMPLES+7)/8]; - UINT unused_samples; - bool bMadeWithModPlug = false, bProbablyMadeWithModPlug = false; - // set this here already because XMs compressed with BoobieSqueezer will exit the function early - SetModFlag(MSF_COMPATIBLE_PLAY, true); - - m_nChannels = 0; - if ((!lpStream) || (dwMemLength < 0xAA)) return false; // the smallest XM I know is 174 Bytes - if (_strnicmp((LPCSTR)lpStream, "Extended Module", 15)) return false; - - memcpy(m_szNames[0], lpStream + 17, 20); - // look for null-terminated song name - that's most likely a tune made with modplug - for(int i = 0; i < 20; i++) - if(lpStream[17 + i] == 0) bProbablyMadeWithModPlug = true; - - dwHdrSize = LittleEndian(*((DWORD *)(lpStream+60))); - norders = LittleEndianW(*((WORD *)(lpStream+64))); - if ((!norders) || (norders > MAX_ORDERS)) return false; - restartpos = LittleEndianW(*((WORD *)(lpStream+66))); - channels = LittleEndianW(*((WORD *)(lpStream+68))); -// -> CODE#0006 -// -> DESC="misc quantity changes" -// if ((!channels) || (channels > 64)) return false; - if ((!channels) || (channels > MAX_BASECHANNELS)) return false; -// -! BEHAVIOUR_CHANGE#0006 - - m_nType = MOD_TYPE_XM; - m_nMinPeriod = 27; - m_nMaxPeriod = 54784; - m_nChannels = channels; - if (restartpos < norders) m_nRestartPos = restartpos; - patterns = CLAMP(LittleEndianW(*((WORD *)(lpStream+70))), 0, 256); - instruments = LittleEndianW(*((WORD *)(lpStream+72))); - if (instruments >= MAX_INSTRUMENTS) instruments = MAX_INSTRUMENTS-1; - m_nInstruments = instruments; - m_nSamples = 0; - memcpy(&xmflags, lpStream + 74, 2); - xmflags = LittleEndianW(xmflags); - if (xmflags & 1) m_dwSongFlags |= SONG_LINEARSLIDES; - if (xmflags & 0x1000) m_dwSongFlags |= SONG_EXFILTERRANGE; - m_nDefaultSpeed = CLAMP(LittleEndianW(*((WORD *)(lpStream+76))), 1, 31); -// -> CODE#0016 -// -> DESC="default tempo update" - m_nDefaultTempo = CLAMP(LittleEndianW(*((WORD *)(lpStream+78))), 32, 512); -// -! BEHAVIOUR_CHANGE#0016 - Order.ReadAsByte(lpStream+80, norders, dwMemLength-80); - memset(InstUsed, 0, sizeof(InstUsed)); - if (patterns > MAX_PATTERNS) + memset(patterns_used, 0, sizeof(patterns_used)); + if (xmheader->patterns > MAX_PATTERNS) { UINT i, j; - for (i=0; i<norders; i++) + for (i = 0; i < xmheader->orders; i++) { - if (Order[i] < patterns) InstUsed[Order[i]] = true; + if (pSndFile->Order[i] < xmheader->patterns) patterns_used[pSndFile->Order[i]] = true; } j = 0; - for (i=0; i<256; i++) + for (i = 0; i < 256; i++) { - if (InstUsed[i]) pattern_map[i] = j++; + if (patterns_used[i]) pattern_map[i] = j++; } - for (i=0; i<256; i++) + for (i = 0; i < 256; i++) { - if (!InstUsed[i]) + if (!patterns_used[i]) { pattern_map[i] = (j < MAX_PATTERNS) ? j : 0xFE; j++; } } - for (i=0; i<norders; i++) + for (i = 0; i < xmheader->orders; i++) { - Order[i] = pattern_map[Order[i]]; + pSndFile->Order[i] = pattern_map[pSndFile->Order[i]]; } } else { - for (UINT i=0; i<256; i++) pattern_map[i] = i; + for (UINT i = 0; i < 256; i++) pattern_map[i] = i; } - memset(InstUsed, 0, sizeof(InstUsed)); - dwMemPos = dwHdrSize + 60; - if (dwMemPos + 8 >= dwMemLength) return true; + if (dwMemPos + 8 >= dwMemLength) return dwMemPos; // Reading patterns - memset(channels_used, 0, sizeof(channels_used)); - for (UINT ipat=0; ipat<patterns; ipat++) + for (UINT ipat = 0; ipat < xmheader->patterns; ipat++) { UINT ipatmap = pattern_map[ipat]; DWORD dwSize = 0; - WORD rows=64, packsize=0; + WORD rows = 64, packsize = 0; dwSize = LittleEndian(*((DWORD *)(lpStream + dwMemPos))); - /*while ((dwMemPos + dwSize >= dwMemLength) || (dwSize & 0xFFFFFF00)) + + if(xmheader->xmversion == 0x0102) { - if (dwMemPos + 4 >= dwMemLength) break; - dwMemPos++; - dwSize = LittleEndian(*((DWORD *)(lpStream+dwMemPos))); - }*/ - rows = LittleEndianW(*((WORD *)(lpStream + dwMemPos + 5))); -// -> CODE#0008 -// -> DESC="#define to set pattern size" -// if ((!rows) || (rows > 256)) rows = 64; + rows = *((BYTE *)(lpStream + dwMemPos + 5)) + 1; + packsize = LittleEndianW(*((WORD *)(lpStream + dwMemPos + 6))); + } + else + { + rows = LittleEndianW(*((WORD *)(lpStream + dwMemPos + 5))); + packsize = LittleEndianW(*((WORD *)(lpStream + dwMemPos + 7))); + } + if ((!rows) || (rows > MAX_PATTERN_ROWS)) rows = 64; -// -> BEHAVIOUR_CHANGE#0008 - packsize = LittleEndianW(*((WORD *)(lpStream + dwMemPos + 7))); - if (dwMemPos + dwSize + 4 > dwMemLength) return true; + if (dwMemPos + dwSize + 4 > dwMemLength) return 0; dwMemPos += dwSize; - if (dwMemPos + packsize > dwMemLength) return true; + if (dwMemPos + packsize > dwMemLength) return 0; MODCOMMAND *p; if (ipatmap < MAX_PATTERNS) { - if(Patterns.Insert(ipatmap, rows)) + if(pSndFile->Patterns.Insert(ipatmap, rows)) return true; if (!packsize) continue; - p = Patterns[ipatmap]; + p = pSndFile->Patterns[ipatmap]; } else p = NULL; const BYTE *src = lpStream+dwMemPos; UINT j=0; for (UINT row=0; row<rows; row++) { - for (UINT chn=0; chn<m_nChannels; chn++) + for (UINT chn=0; chn < xmheader->channels; chn++) { if ((p) && (j < packsize)) { @@ -231,10 +178,8 @@ } if (p->note == 97) p->note = 0xFF; else if ((p->note) && (p->note < 97)) p->note += 12; - if (p->note) channels_used[chn] = 1; - if (p->command | p->param) ConvertModCommand(p); + if (p->command | p->param) pSndFile->ConvertModCommand(p); if (p->instr == 0xff) p->instr = 0; - if (p->instr) InstUsed[p->instr] = TRUE; if ((vol >= 0x10) && (vol <= 0x50)) { p->volcmd = VOLCMD_VOLUME; @@ -287,17 +232,77 @@ } dwMemPos += packsize; } - // Wrong offset check - while (dwMemPos + 4 < dwMemLength) + return dwMemPos; +} + +bool CSoundFile::ReadXM(const BYTE *lpStream, DWORD dwMemLength) +//-------------------------------------------------------------- +{ + XMFILEHEADER xmheader; + XMSAMPLEHEADER xmsh; + XMSAMPLESTRUCT xmss; + DWORD dwMemPos; + BYTE samples_used[(MAX_SAMPLES + 7) / 8]; // for removing unused samples + UINT unused_samples; // dito + + bool bMadeWithModPlug = false, bProbablyMadeWithModPlug = false, bIsFT2 = false; + // set this here already because XMs compressed with BoobieSqueezer will exit the function early + SetModFlag(MSF_COMPATIBLE_PLAY, true); + + m_nChannels = 0; + if ((!lpStream) || (dwMemLength < 0xAA)) return false; // the smallest XM I know is 174 Bytes + if (_strnicmp((LPCSTR)lpStream, "Extended Module", 15)) return false; + + memcpy(m_szNames[0], lpStream + 17, 20); + // look for null-terminated song name - that's most likely a tune made with modplug + for(int i = 0; i < 20; i++) + if(lpStream[17 + i] == 0) bProbablyMadeWithModPlug = true; + + // load and convert header + memcpy(&xmheader, lpStream + 58, sizeof(XMFILEHEADER)); + xmheader.size = LittleEndian(xmheader.size); + xmheader.xmversion = LittleEndianW(xmheader.xmversion); + xmheader.orders = LittleEndianW(xmheader.orders); + xmheader.restartpos = LittleEndianW(xmheader.restartpos); + xmheader.channels = LittleEndianW(xmheader.channels); + xmheader.patterns = LittleEndianW(xmheader.patterns); + xmheader.instruments = LittleEndianW(xmheader.instruments); + xmheader.flags = LittleEndianW(xmheader.flags); + xmheader.speed = LittleEndianW(xmheader.speed); + xmheader.tempo = LittleEndianW(xmheader.tempo); + + m_nType = MOD_TYPE_XM; + m_nMinPeriod = 27; + m_nMaxPeriod = 54784; + + if ((!xmheader.orders) || (xmheader.orders > MAX_ORDERS)) return false; + if ((!xmheader.channels) || (xmheader.channels > MAX_BASECHANNELS)) return false; + if (xmheader.channels > 32) bMadeWithModPlug = true; + m_nRestartPos = xmheader.restartpos; + m_nChannels = xmheader.channels; + m_nInstruments = min(xmheader.instruments, MAX_INSTRUMENTS - 1); + m_nSamples = 0; + m_nDefaultSpeed = CLAMP(xmheader.speed, 1, 31); + m_nDefaultTempo = CLAMP(xmheader.tempo, 32, 512); + + if(xmheader.flags & 1) m_dwSongFlags |= SONG_LINEARSLIDES; + if(xmheader.flags & 0x1000) m_dwSongFlags |= SONG_EXFILTERRANGE; + + Order.ReadAsByte(lpStream + 80, xmheader.orders, dwMemLength - 80); + + dwMemPos = xmheader.size + 60; + + if(xmheader.xmversion >= 0x0104) { - DWORD d = LittleEndian(*((DWORD *)(lpStream+dwMemPos))); - if (d < 0x300) break; - dwMemPos++; + if (dwMemPos + 8 >= dwMemLength) return true; + dwMemPos = ReadXMPatterns(lpStream, dwMemLength, dwMemPos, &xmheader, this); + if(dwMemPos == 0) return true; } + memset(samples_used, 0, sizeof(samples_used)); unused_samples = 0; // Reading instruments - for (UINT iIns=1; iIns<=instruments; iIns++) + for (INSTRUMENTINDEX iIns = 1; iIns <= m_nInstruments; iIns++) { XMINSTRUMENTHEADER *pih; BYTE flags[32]; @@ -318,9 +323,6 @@ Instruments[iIns]->nPluginVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE; memcpy(Instruments[iIns]->name, pih->name, 22); - // look for null-terminated instr name - that's most likely a tune made with modplug - for(int i = 0; i < 22; i++) - if(pih->name[i] == 0) bProbablyMadeWithModPlug = true; if ((nsamples = pih->samples) > 0) { @@ -344,7 +346,12 @@ xmsh.penv[i] = LittleEndianW(xmsh.penv[i]); } xmsh.volfade = LittleEndianW(xmsh.volfade); - xmsh.res = LittleEndianW(xmsh.res); + xmsh.midiprogram = LittleEndianW(xmsh.midiprogram); + xmsh.pitchwheelrange = LittleEndianW(xmsh.pitchwheelrange); + + if(xmsh.midichannel != 0 || xmsh.midienabled != 0 || xmsh.midiprogram != 0 || xmsh.mutecomputer != 0 || xmsh.pitchwheelrange != 0) + bIsFT2 = true; // definitely not MPT. (or any other tracker) + dwMemPos += LittleEndian(pih->size); } else { @@ -547,9 +554,6 @@ pSmp->nVibRate = xmsh.vibrate; memcpy(pSmp->filename, xmss.name, 22); pSmp->filename[21] = 0; - // look for null-terminated sample name - that's most likely a tune made with modplug - for(int i = 0; i < 22; i++) - if(xmss.name[i] == 0) bProbablyMadeWithModPlug = true; } #if 0 if ((xmsh.reserved2 > nsamples) && (xmsh.reserved2 <= 16)) @@ -557,16 +561,35 @@ dwMemPos += (((UINT)xmsh.reserved2) - nsamples) * xmsh.shsize; } #endif - for (UINT ismpd=0; ismpd<nsamples; ismpd++) + if(xmheader.xmversion >= 0x0104) { - if ((samplemap[ismpd]) && (samplesize[ismpd]) && (dwMemPos < dwMemLength)) + for (UINT ismpd = 0; ismpd < nsamples; ismpd++) { - ReadSample(&Samples[samplemap[ismpd]], flags[ismpd], (LPSTR)(lpStream + dwMemPos), dwMemLength - dwMemPos); + if ((samplemap[ismpd]) && (samplesize[ismpd]) && (dwMemPos < dwMemLength)) + { + ReadSample(&Samples[samplemap[ismpd]], flags[ismpd], (LPSTR)(lpStream + dwMemPos), dwMemLength - dwMemPos); + } + dwMemPos += samplesize[ismpd]; + if (dwMemPos >= dwMemLength) break; } - dwMemPos += samplesize[ismpd]; + } + } + + if(xmheader.xmversion < 0x0104) + { + // Load Patterns and Samples (Version 1.02 and 1.03) + if (dwMemPos + 8 >= dwMemLength) return true; + dwMemPos = ReadXMPatterns(lpStream, dwMemLength, dwMemPos, &xmheader, this); + if(dwMemPos == 0) return true; + + for(SAMPLEINDEX iSmp = 1; iSmp <= m_nSamples; iSmp++) + { + ReadSample(&Samples[iSmp], (Samples[iSmp].uFlags & CHN_16BIT) ? RS_PCM16D : RS_PCM8D, (LPSTR)(lpStream + dwMemPos), dwMemLength - dwMemPos); + dwMemPos += Samples[iSmp].GetSampleSizeInBytes(); if (dwMemPos >= dwMemLength) break; } } + // Read song comments: "TEXT" if ((dwMemPos + 8 < dwMemLength) && (LittleEndian(*((DWORD *)(lpStream+dwMemPos))) == 0x74786574)) { @@ -640,7 +663,7 @@ // Check various things to find out whether this has been made with MPT. // Null chars in names -> most likely made with MPT, which disguises as FT2 - if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true; + if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug && !bIsFT2) bMadeWithModPlug = true; if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v 2.00 ", 20)) { // Early MPT 1.0 alpha/beta versions @@ -701,7 +724,7 @@ //BYTE s[64*64*5]; vector<BYTE> s(64*64*5, 0); - XMFILEHEADER header; + XMFILEHEADER xmheader; XMINSTRUMENTHEADER xmih; XMSAMPLEHEADER xmsh; XMSAMPLESTRUCT xmss; @@ -718,21 +741,22 @@ fwrite(m_szNames[0], 20, 1, f); s[0] = 0x1A; lstrcpy((LPSTR)&s[1], (nPacking) ? "MOD Plugin packed " : "OpenMPT " MPT_VERSION_STR " "); - s[21] = 0x04; // Version number - s[22] = 0x01; // XM Format v1.04 - fwrite(&s[0], 23, 1, f); + fwrite(&s[0], 21, 1, f); + // Writing song header - memset(&header, 0, sizeof(header)); - header.size = sizeof(XMFILEHEADER); - header.norder = 0; - header.restartpos = m_nRestartPos; + memset(&xmheader, 0, sizeof(xmheader)); + xmheader.xmversion = LittleEndianW(0x0104); // XM Format v1.04 + xmheader.size = sizeof(XMFILEHEADER) - 2; // minus the version field + xmheader.restartpos = LittleEndianW(m_nRestartPos); - header.channels = (m_nChannels + 1) & 0xFFFE; // avoid odd channel count for FT2 compatibility + xmheader.channels = (m_nChannels + 1) & 0xFFFE; // avoid odd channel count for FT2 compatibility if(m_nChannels & 1) bAddChannel = true; - if(bCompatibilityExport && header.channels > 32) - header.channels = 32; + if(bCompatibilityExport && xmheader.channels > 32) + xmheader.channels = 32; + if(xmheader.channels > MAX_BASECHANNELS) xmheader.channels = MAX_BASECHANNELS; + xmheader.channels = LittleEndianW(xmheader.channels); - header.patterns = 0; + xmheader.patterns = 0; /*for (i=0; i<MAX_ORDERS; i++) { header.norder++; if ((Order[i] >= header.patterns) && (Order[i] < MAX_PATTERNS)) header.patterns = Order[i]+1; @@ -740,33 +764,37 @@ if(Order.GetLength() < MAX_ORDERS) Order.resize(MAX_ORDERS); - for (i=MAX_ORDERS-1; i>=0; i--) { // walk backwards over orderlist - if ((Order[i]!=0xFF) && (header.norder==0)) { - header.norder=i+1; //find last used order + WORD nOrders = Order.GetLengthTailTrimmed(), nPatterns = 0; + xmheader.orders = LittleEndianW(nOrders); + xmheader.size = LittleEndian(xmheader.size + nOrders); + + for (i = 0; i < nOrders; i++) { // walk over orderlist and find last used pattern + if((Order[i] >= nPatterns) && (Order[i] < MAX_PATTERNS)) { + nPatterns = Order[i] + 1; } - if ((Order[i] >= header.patterns) && (Order[i] < MAX_PATTERNS)) { - header.patterns = Order[i]+1; //find last pattern - } } + xmheader.patterns = LittleEndianW(nPatterns); - header.instruments = m_nInstruments; - if (!header.instruments) header.instruments = m_nSamples; - header.flags = (m_dwSongFlags & SONG_LINEARSLIDES) ? 0x01 : 0x00; - if (m_dwSongFlags & SONG_EXFILTERRANGE) header.flags |= 0x1000; + if(m_nInstruments > 0) + xmheader.instruments = LittleEndianW(m_nInstruments); + else + xmheader.instruments = LittleEndianW(m_nSamples); + + xmheader.flags = (m_dwSongFlags & SONG_LINEARSLIDES) ? 0x01 : 0x00; + if (m_dwSongFlags & SONG_EXFILTERRANGE) xmheader.flags |= 0x1000; + xmheader.flags = LittleEndianW(xmheader.flags); + if(bCompatibilityExport) - { - header.tempo = CLAMP(m_nDefaultTempo, 32, 255); - } + xmheader.tempo = LittleEndianW(CLAMP(m_nDefaultTempo, 32, 255)); else - { - header.tempo = m_nDefaultTempo; - } - header.speed = CLAMP(m_nDefaultSpeed, 1, 31); - Order.WriteToByteArray(header.order, header.norder, 256); + xmheader.tempo = LittleEndianW(CLAMP(m_nDefaultTempo, 32, 512)); + xmheader.speed = LittleEndianW(CLAMP(m_nDefaultSpeed, 1, 31)); - fwrite(&header, 1, sizeof(header), f); + fwrite(&xmheader, 1, sizeof(xmheader), f); + Order.WriteAsByte(f, nOrders); + // Writing patterns - for (i=0; i<header.patterns; i++) if (Patterns[i]) + for (i = 0; i < nPatterns; i++) if (Patterns[i]) { MODCOMMAND *p = Patterns[i]; UINT len = 0; @@ -851,7 +879,7 @@ fwrite(xmph, 1, 9, f); } // Writing instruments - for (i=1; i<=header.instruments; i++) + for (i = 1; i <= xmheader.instruments; i++) { MODSAMPLE *pSmp; WORD smptable[32]; @@ -860,7 +888,7 @@ memset(&smptable, 0, sizeof(smptable)); memset(&xmih, 0, sizeof(xmih)); memset(&xmsh, 0, sizeof(xmsh)); - xmih.size = sizeof(xmih) + sizeof(xmsh); + xmih.size = LittleEndian(sizeof(xmih) + sizeof(xmsh)); memcpy(xmih.name, m_szNames[i], 22); xmih.type = 0; xmih.samples = 0; @@ -871,17 +899,17 @@ { memcpy(xmih.name, pIns->name, 22); xmih.type = pIns->nMidiProgram; - xmsh.volfade = min(pIns->nFadeOut, 0xFFF); // FFF is maximum in FT2 + xmsh.volfade = LittleEndianW(min(pIns->nFadeOut, 0xFFF)); // FFF is maximum in FT2 xmsh.vnum = (BYTE)pIns->VolEnv.nNodes; xmsh.pnum = (BYTE)pIns->PanEnv.nNodes; if (xmsh.vnum > 12) xmsh.vnum = 12; if (xmsh.pnum > 12) xmsh.pnum = 12; for (UINT ienv=0; ienv<12; ienv++) { - xmsh.venv[ienv*2] = pIns->VolEnv.Ticks[ienv]; - xmsh.venv[ienv*2+1] = pIns->VolEnv.Values[ienv]; - xmsh.penv[ienv*2] = pIns->PanEnv.Ticks[ienv]; - xmsh.penv[ienv*2+1] = pIns->PanEnv.Values[ienv]; + xmsh.venv[ienv*2] = LittleEndianW(pIns->VolEnv.Ticks[ienv]); + xmsh.venv[ienv*2+1] = LittleEndianW(pIns->VolEnv.Values[ienv]); + xmsh.penv[ienv*2] = LittleEndianW(pIns->PanEnv.Ticks[ienv]); + xmsh.penv[ienv*2+1] = LittleEndianW(pIns->PanEnv.Values[ienv]); } if (pIns->dwFlags & ENV_VOLUME) xmsh.vtype |= 1; if (pIns->dwFlags & ENV_VOLSUSTAIN) xmsh.vtype |= 2; @@ -914,15 +942,13 @@ if (xmih.samples >= 32) break; xmsh.snum[j] = k; //record sample table offset in instrument's note map } -// xmsh.reserved2 = xmih.samples; } } else { xmih.samples = 1; -// xmsh.reserved2 = 1; smptable[0] = i; } - xmsh.shsize = (xmih.samples) ? 40 : 0; + xmsh.shsize = LittleEndianW((xmih.samples) ? 40 : 0); fwrite(&xmih, 1, sizeof(xmih), f); if (smptable[0]) { @@ -932,9 +958,11 @@ xmsh.vibdepth = pvib->nVibDepth; xmsh.vibrate = pvib->nVibRate; } - fwrite(&xmsh, 1, xmih.size - sizeof(xmih), f); + WORD samples = xmih.samples; + xmih.samples = LittleEndianW(xmih.samples); + fwrite(&xmsh, 1, sizeof(xmsh), f); if (!xmih.samples) continue; - for (UINT ins=0; ins<xmih.samples; ins++) + for (UINT ins = 0; ins < samples; ins++) { memset(&xmss, 0, sizeof(xmss)); if (smptable[ins]) memcpy(xmss.name, m_szNames[smptable[ins]], 22); @@ -979,6 +1007,9 @@ xmss.pan = 255; if (pSmp->nPan < 256) xmss.pan = (BYTE)pSmp->nPan; xmss.relnote = (signed char)pSmp->RelativeTone; + xmss.samplen = LittleEndianW(xmss.samplen); + xmss.loopstart = LittleEndianW(xmss.loopstart); + xmss.looplen = LittleEndianW(xmss.looplen); fwrite(&xmss, 1, xmsh.shsize, f); } for (UINT ismpd=0; ismpd<xmih.samples; ismpd++) @@ -1050,7 +1081,7 @@ //Save hacked-on extra info SaveMixPlugins(f); - SaveExtendedInstrumentProperties(Instruments, header.instruments, f); + SaveExtendedInstrumentProperties(Instruments, xmheader.instruments, f); SaveExtendedSongProperties(f); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-09-17 16:11:58
|
Revision: 368 http://modplug.svn.sourceforge.net/modplug/?rev=368&view=rev Author: saga-games Date: 2009-09-17 16:11:47 +0000 (Thu, 17 Sep 2009) Log Message: ----------- [Fix] Sample Editor: Limit sample vibrato fields properly. Vibrato Sweep ranges from 0 to 255 now. [Fix] IT Compatibility: Better sample vibrato compatibility. Vibrato Sweep isn't perfect yet, though. [Mod] Sequence view: Also grey out "Render to wave" menu item if no valid order is selected Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-09-16 22:46:46 UTC (rev 367) +++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-09-17 16:11:47 UTC (rev 368) @@ -897,7 +897,7 @@ } } AppendMenu(hMenu, MF_SEPARATOR, NULL, ""); - AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_RENDER, "Render to &Wave"); + AppendMenu(hMenu, MF_STRING | greyed, ID_ORDERLIST_RENDER, "Render to &Wave"); ClientToScreen(&pt); ::TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, m_hWnd, NULL); Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-09-16 22:46:46 UTC (rev 367) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-09-17 16:11:47 UTC (rev 368) @@ -228,14 +228,24 @@ m_SpinPanning.SetRange(0, 64); } //end rewbs.fix36944 + + // Auto vibrato m_ComboAutoVib.AddString("Sine"); m_ComboAutoVib.AddString("Square"); m_ComboAutoVib.AddString("Ramp Up"); m_ComboAutoVib.AddString("Ramp Down"); m_ComboAutoVib.AddString("Random"); - m_SpinVibSweep.SetRange(0, 64); - m_SpinVibDepth.SetRange(0, 64); - m_SpinVibRate.SetRange(0, 64); + m_SpinVibSweep.SetRange(0, 255); + if(m_pSndFile->m_nType & MOD_TYPE_XM) + { + m_SpinVibDepth.SetRange(0, 15); + m_SpinVibRate.SetRange(0, 63); + } else + { + m_SpinVibDepth.SetRange(0, 32); + m_SpinVibRate.SetRange(0, 64); + } + for (UINT i=BASENOTE_MIN; i<BASENOTE_MAX; i++) { CHAR s[32]; Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-16 22:46:46 UTC (rev 367) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-17 16:11:47 UTC (rev 368) @@ -751,7 +751,7 @@ pSmp->nVibType = autovibit2xm[pis.vit & 7]; pSmp->nVibRate = pis.vis; pSmp->nVibDepth = pis.vid & 0x7F; - pSmp->nVibSweep = (pis.vir + 3) / 4; + pSmp->nVibSweep = pis.vir; if(pis.length){ pSmp->nLength = pis.length; if (pSmp->nLength > MAX_SAMPLE_LENGTH) pSmp->nLength = MAX_SAMPLE_LENGTH; @@ -1231,7 +1231,7 @@ pSmp->nVibType = autovibit2xm[pis->vit & 7]; pSmp->nVibRate = pis->vis; pSmp->nVibDepth = pis->vid & 0x7F; - pSmp->nVibSweep = (pis->vir + 3) / 4; + pSmp->nVibSweep = pis->vir; //(pis->vir + 3) / 4; if ((pis->samplepointer) && (pis->samplepointer < dwMemLength) && (pis->length)) { pSmp->nLength = pis->length; @@ -1719,9 +1719,9 @@ itss.vol = psmp->nVolume >> 2; itss.dfp = psmp->nPan >> 2; itss.vit = autovibxm2it[psmp->nVibType & 7]; - itss.vis = psmp->nVibRate; - itss.vid = psmp->nVibDepth; - itss.vir = (psmp->nVibSweep < 64) ? psmp->nVibSweep * 4 : 255; + itss.vis = min(psmp->nVibRate, 64); + itss.vid = min(psmp->nVibDepth, 32); + itss.vir = min(psmp->nVibSweep, 255); //(psmp->nVibSweep < 64) ? psmp->nVibSweep * 4 : 255; if (psmp->uFlags & CHN_PANNING) itss.dfp |= 0x80; if ((psmp->pSample) && (psmp->nLength)) itss.cvt = 0x01; UINT flags = RS_PCM8S; @@ -2351,9 +2351,9 @@ itss.vol = psmp->nVolume >> 2; itss.dfp = psmp->nPan >> 2; itss.vit = autovibxm2it[psmp->nVibType & 7]; - itss.vis = psmp->nVibRate; - itss.vid = psmp->nVibDepth; - itss.vir = (psmp->nVibSweep < 64) ? psmp->nVibSweep * 4 : 255; + itss.vis = min(psmp->nVibRate, 64); + itss.vid = min(psmp->nVibDepth, 32); + itss.vir = min(psmp->nVibSweep, 255); //(psmp->nVibSweep < 64) ? psmp->nVibSweep * 4 : 255; if (psmp->uFlags & CHN_PANNING) itss.dfp |= 0x80; if ((psmp->pSample) && (psmp->nLength)) itss.cvt = 0x01; UINT flags = RS_PCM8S; @@ -2987,9 +2987,9 @@ itss.vol = psmp->nVolume >> 2; itss.dfp = psmp->nPan >> 2; itss.vit = autovibxm2it[psmp->nVibType & 7]; - itss.vis = psmp->nVibRate; - itss.vid = psmp->nVibDepth; - itss.vir = (psmp->nVibSweep < 64) ? psmp->nVibSweep * 4 : 255; + itss.vis = min(psmp->nVibRate, 64); + itss.vid = min(psmp->nVibDepth, 32); + itss.vir = min(psmp->nVibSweep, 255); if (psmp->uFlags & CHN_PANNING) itss.dfp |= 0x80; if ((psmp->pSample) && (psmp->nLength)) itss.cvt = 0x01; UINT flags = RS_PCM8S; Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-09-16 22:46:46 UTC (rev 367) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-09-17 16:11:47 UTC (rev 368) @@ -954,9 +954,9 @@ { MODSAMPLE *pvib = &Samples[smptable[0]]; xmsh.vibtype = pvib->nVibType; - xmsh.vibsweep = pvib->nVibSweep; - xmsh.vibdepth = pvib->nVibDepth; - xmsh.vibrate = pvib->nVibRate; + xmsh.vibsweep = min(pvib->nVibSweep, 0xFF); + xmsh.vibdepth = min(pvib->nVibDepth, 0x0F); + xmsh.vibrate = min(pvib->nVibRate, 0x3F); } WORD samples = xmih.samples; xmih.samples = LittleEndianW(xmih.samples); Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-09-16 22:46:46 UTC (rev 367) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-09-17 16:11:47 UTC (rev 368) @@ -1448,19 +1448,28 @@ //if(IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPan = pChn->nRealPan; // TODO } int nPeriodFrac = 0; - // Instrument Auto-Vibrato + // Sample Auto-Vibrato if ((pChn->pModSample) && (pChn->pModSample->nVibDepth)) { MODSAMPLE *pSmp = pChn->pModSample; - if (pSmp->nVibSweep == 0) + if (pSmp->nVibSweep == 0 && !IsCompatibleMode(TRK_IMPULSETRACKER)) { pChn->nAutoVibDepth = pSmp->nVibDepth << 8; } else { if (m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) { - pChn->nAutoVibDepth += pSmp->nVibSweep << 3; + if(IsCompatibleMode(TRK_IMPULSETRACKER)) + { + // TODO + pChn->nAutoVibDepth += pSmp->nVibSweep << 3; + } else + { + /* Note: changed bitshift from 3 to 1 as the variable is not divided by 4 in the IT loader anymore + - so we divide sweep by 4 here. */ + pChn->nAutoVibDepth += pSmp->nVibSweep << 1; + } } else if (!(pChn->dwFlags & CHN_KEYOFF)) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-09-18 18:49:14
|
Revision: 369 http://modplug.svn.sourceforge.net/modplug/?rev=369&view=rev Author: saga-games Date: 2009-09-18 18:48:59 +0000 (Fri, 18 Sep 2009) Log Message: ----------- [Fix] ITI Loader/Saver: Forgot to change vibrato sweep settings here in the last commit [Ref] Some more refactoring Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-17 16:11:47 UTC (rev 368) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-18 18:48:59 UTC (rev 369) @@ -1017,13 +1017,13 @@ } -BOOL CModDoc::MuteChannel(UINT nChn, BOOL doMute) +bool CModDoc::MuteChannel(CHANNELINDEX nChn, bool doMute) //---------------------------------------------- { DWORD muteType = (CMainFrame::m_dwPatternSetup&PATTERN_SYNCMUTE)? CHN_SYNCMUTE:CHN_MUTE; if (nChn >= m_SndFile.m_nChannels) { - return FALSE; + return false; } //Mark channel as muted in channel settings @@ -1067,43 +1067,43 @@ CMainFrame::GetMainFrame()->ThreadSafeSetModified(this); } - return TRUE; + return true; } // -> CODE#0012 // -> DESC="midi keyboard split" -BOOL CModDoc::IsChannelSolo(UINT nChn) const -//------------------------------------------ +bool CModDoc::IsChannelSolo(CHANNELINDEX nChn) const +//-------------------------------------------------- { - if (nChn >= m_SndFile.m_nChannels) return TRUE; - return (m_SndFile.ChnSettings[nChn].dwFlags & CHN_SOLO) ? TRUE : FALSE; + if (nChn >= m_SndFile.m_nChannels) return true; + return (m_SndFile.ChnSettings[nChn].dwFlags & CHN_SOLO) ? true : false; } -BOOL CModDoc::SoloChannel(UINT nChn, BOOL bSolo) -//--------------------------------------------- +bool CModDoc::SoloChannel(CHANNELINDEX nChn, bool bSolo) +//------------------------------------------------------ { - if (nChn >= m_SndFile.m_nChannels) return FALSE; + if (nChn >= m_SndFile.m_nChannels) return false; if (m_SndFile.m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) SetModified(); if (bSolo) m_SndFile.ChnSettings[nChn].dwFlags |= CHN_SOLO; else m_SndFile.ChnSettings[nChn].dwFlags &= ~CHN_SOLO; - return TRUE; + return true; } // -! NEW_FEATURE#0012 // -> CODE#0015 // -> DESC="channels management dlg" -BOOL CModDoc::IsChannelNoFx(UINT nChn) const +bool CModDoc::IsChannelNoFx(CHANNELINDEX nChn) const //------------------------------------------ { - if (nChn >= m_SndFile.m_nChannels) return TRUE; - return (m_SndFile.ChnSettings[nChn].dwFlags & CHN_NOFX) ? TRUE : FALSE; + if (nChn >= m_SndFile.m_nChannels) return true; + return (m_SndFile.ChnSettings[nChn].dwFlags & CHN_NOFX) ? true : false; } -BOOL CModDoc::NoFxChannel(UINT nChn, BOOL bNoFx, BOOL updateMix) -//-------------------------------------------------------------- +bool CModDoc::NoFxChannel(CHANNELINDEX nChn, bool bNoFx, bool updateMix) +//---------------------------------------------------------------------- { - if (nChn >= m_SndFile.m_nChannels) return FALSE; + if (nChn >= m_SndFile.m_nChannels) return false; if (m_SndFile.m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) SetModified(); if (bNoFx){ m_SndFile.ChnSettings[nChn].dwFlags |= CHN_NOFX; @@ -1113,33 +1113,33 @@ m_SndFile.ChnSettings[nChn].dwFlags &= ~CHN_NOFX; if(updateMix) m_SndFile.Chn[nChn].dwFlags &= ~CHN_NOFX; } - return TRUE; + return true; } -BOOL CModDoc::IsChannelRecord1(UINT channel) -//------------------------------------------ +bool CModDoc::IsChannelRecord1(CHANNELINDEX channel) +//-------------------------------------------------- { UINT m = 1 << (channel&7); - return (MultiRecordMask[channel>>3] & m) ? TRUE : FALSE; + return (MultiRecordMask[channel>>3] & m) ? true : false; } -BOOL CModDoc::IsChannelRecord2(UINT channel) -//------------------------------------------ +bool CModDoc::IsChannelRecord2(CHANNELINDEX channel) +//-------------------------------------------------- { UINT m = 1 << (channel&7); - return (MultiSplitRecordMask[channel>>3] & m) ? TRUE : FALSE; + return (MultiSplitRecordMask[channel>>3] & m) ? true : false; } -BYTE CModDoc::IsChannelRecord(UINT channel) -//----------------------------------------- +BYTE CModDoc::IsChannelRecord(CHANNELINDEX channel) +//------------------------------------------------- { if(IsChannelRecord1(channel)) return 1; if(IsChannelRecord2(channel)) return 2; return 0; } -void CModDoc::Record1Channel(UINT channel, BOOL select) -//----------------------------------------------------- +void CModDoc::Record1Channel(CHANNELINDEX channel, bool select) +//------------------------------------------------------------- { UINT m = 1 << (channel&7); @@ -1153,8 +1153,8 @@ } } -void CModDoc::Record2Channel(UINT channel, BOOL select) -//----------------------------------------------------- +void CModDoc::Record2Channel(CHANNELINDEX channel, bool select) +//------------------------------------------------------------- { UINT m = 1 << (channel&7); @@ -1168,7 +1168,7 @@ } } -void CModDoc::ReinitRecordState(BOOL unselect) +void CModDoc::ReinitRecordState(bool unselect) //-------------------------------------------- { memset(MultiRecordMask, unselect ? 0 : 0xff, sizeof(MultiRecordMask)); @@ -1177,31 +1177,31 @@ // -! NEW_FEATURE#0015 -BOOL CModDoc::MuteSample(UINT nSample, BOOL bMute) -//------------------------------------------------ +bool CModDoc::MuteSample(SAMPLEINDEX nSample, bool bMute) +//------------------------------------------------------- { - if ((nSample < 1) || (nSample > m_SndFile.m_nSamples)) return FALSE; + if ((nSample < 1) || (nSample > m_SndFile.m_nSamples)) return false; if (bMute) m_SndFile.Samples[nSample].uFlags |= CHN_MUTE; else m_SndFile.Samples[nSample].uFlags &= ~CHN_MUTE; - return TRUE; + return true; } -BOOL CModDoc::MuteInstrument(UINT nInstr, BOOL bMute) -//--------------------------------------------------- +bool CModDoc::MuteInstrument(INSTRUMENTINDEX nInstr, bool bMute) +//-------------------------------------------------------------- { - if ((nInstr < 1) || (nInstr > m_SndFile.m_nInstruments) || (!m_SndFile.Instruments[nInstr])) return FALSE; + if ((nInstr < 1) || (nInstr > m_SndFile.m_nInstruments) || (!m_SndFile.Instruments[nInstr])) return false; if (bMute) m_SndFile.Instruments[nInstr]->dwFlags |= ENV_MUTE; else m_SndFile.Instruments[nInstr]->dwFlags &= ~ENV_MUTE; - return TRUE; + return true; } -BOOL CModDoc::SurroundChannel(UINT nChn, BOOL bSurround) -//------------------------------------------------------ +bool CModDoc::SurroundChannel(CHANNELINDEX nChn, bool bSurround) +//-------------------------------------------------------------- { DWORD d = (bSurround) ? CHN_SURROUND : 0; - if (nChn >= m_SndFile.m_nChannels) return FALSE; + if (nChn >= m_SndFile.m_nChannels) return false; if (!(m_SndFile.m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT))) d = 0; if (d != (m_SndFile.ChnSettings[nChn].dwFlags & CHN_SURROUND)) { @@ -1212,68 +1212,68 @@ } if (d) m_SndFile.Chn[nChn].dwFlags |= CHN_SURROUND; else m_SndFile.Chn[nChn].dwFlags &= ~CHN_SURROUND; - return TRUE; + return true; } -BOOL CModDoc::SetChannelGlobalVolume(UINT nChn, UINT nVolume) -//----------------------------------------------------------- +bool CModDoc::SetChannelGlobalVolume(CHANNELINDEX nChn, UINT nVolume) +//------------------------------------------------------------------- { - BOOL bOk = FALSE; - if ((nChn >= m_SndFile.m_nChannels) || (nVolume > 64)) return FALSE; + bool bOk = false; + if ((nChn >= m_SndFile.m_nChannels) || (nVolume > 64)) return false; if (m_SndFile.ChnSettings[nChn].nVolume != nVolume) { m_SndFile.ChnSettings[nChn].nVolume = nVolume; if (m_SndFile.m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) SetModified(); - bOk = TRUE; + bOk = true; } m_SndFile.Chn[nChn].nGlobalVol = nVolume; return bOk; } -BOOL CModDoc::SetChannelDefaultPan(UINT nChn, UINT nPan) -//------------------------------------------------------ +bool CModDoc::SetChannelDefaultPan(CHANNELINDEX nChn, UINT nPan) +//-------------------------------------------------------------- { - BOOL bOk = FALSE; - if ((nChn >= m_SndFile.m_nChannels) || (nPan > 256)) return FALSE; + bool bOk = false; + if ((nChn >= m_SndFile.m_nChannels) || (nPan > 256)) return false; if (m_SndFile.ChnSettings[nChn].nPan != nPan) { m_SndFile.ChnSettings[nChn].nPan = nPan; if (m_SndFile.m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT | MOD_TYPE_MPT)) SetModified(); - bOk = TRUE; + bOk = true; } m_SndFile.Chn[nChn].nPan = nPan; return bOk; } -BOOL CModDoc::IsChannelMuted(UINT nChn) const -//------------------------------------------- +bool CModDoc::IsChannelMuted(CHANNELINDEX nChn) const +//--------------------------------------------------- { - if (nChn >= m_SndFile.m_nChannels) return TRUE; - return (m_SndFile.ChnSettings[nChn].dwFlags & CHN_MUTE) ? TRUE : FALSE; + if (nChn >= m_SndFile.m_nChannels) return true; + return (m_SndFile.ChnSettings[nChn].dwFlags & CHN_MUTE) ? true : false; } -BOOL CModDoc::IsSampleMuted(UINT nSample) const -//--------------------------------------------- +bool CModDoc::IsSampleMuted(SAMPLEINDEX nSample) const +//---------------------------------------------------- { - if ((!nSample) || (nSample > m_SndFile.m_nSamples)) return FALSE; - return (m_SndFile.Samples[nSample].uFlags & CHN_MUTE) ? TRUE : FALSE; + if ((!nSample) || (nSample > m_SndFile.m_nSamples)) return false; + return (m_SndFile.Samples[nSample].uFlags & CHN_MUTE) ? true : false; } -BOOL CModDoc::IsInstrumentMuted(UINT nInstr) const -//------------------------------------------------ +bool CModDoc::IsInstrumentMuted(INSTRUMENTINDEX nInstr) const +//----------------------------------------------------------- { - if ((!nInstr) || (nInstr > m_SndFile.m_nInstruments) || (!m_SndFile.Instruments[nInstr])) return FALSE; - return (m_SndFile.Instruments[nInstr]->dwFlags & ENV_MUTE) ? TRUE : FALSE; + if ((!nInstr) || (nInstr > m_SndFile.m_nInstruments) || (!m_SndFile.Instruments[nInstr])) return false; + return (m_SndFile.Instruments[nInstr]->dwFlags & ENV_MUTE) ? true : false; } -UINT CModDoc::GetPatternSize(UINT nPat) const -//------------------------------------------- +UINT CModDoc::GetPatternSize(PATTERNINDEX nPat) const +//--------------------------------------------------- { if ((nPat < m_SndFile.Patterns.Size()) && (m_SndFile.Patterns[nPat])) return m_SndFile.PatternSize[nPat]; return 0; Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-09-17 16:11:47 UTC (rev 368) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-09-18 18:48:59 UTC (rev 369) @@ -150,8 +150,8 @@ void PostMessageToAllViews(UINT uMsg, WPARAM wParam=0, LPARAM lParam=0); void SendMessageToActiveViews(UINT uMsg, WPARAM wParam=0, LPARAM lParam=0); UINT GetModType() const { return m_SndFile.m_nType; } - BOOL GetNumInstruments() const { return m_SndFile.m_nInstruments; } - BOOL GetNumSamples() const { return m_SndFile.m_nSamples; } + INSTRUMENTINDEX GetNumInstruments() const { return m_SndFile.m_nInstruments; } + SAMPLEINDEX GetNumSamples() const { return m_SndFile.m_nSamples; } BOOL AddToLog(LPCSTR lpszLog); LPCSTR GetLog() const { return m_lpszLog; } BOOL ClearLog(); @@ -211,33 +211,33 @@ BOOL NoteOff(UINT note, BOOL bFade=FALSE, UINT nins=-1, UINT nCurrentChn=-1); //rewbs.vstiLive: add params BOOL IsNotePlaying(UINT note, UINT nsmp=0, UINT nins=0); - BOOL MuteChannel(UINT nChn, BOOL bMute); - BOOL MuteSample(UINT nSample, BOOL bMute); - BOOL MuteInstrument(UINT nInstr, BOOL bMute); + bool MuteChannel(CHANNELINDEX nChn, bool bMute); + bool MuteSample(SAMPLEINDEX nSample, bool bMute); + bool MuteInstrument(INSTRUMENTINDEX nInstr, bool bMute); // -> CODE#0012 // -> DESC="midi keyboard split" - BOOL SoloChannel(UINT nChn, BOOL bSolo); - BOOL IsChannelSolo(UINT nChn) const; + bool SoloChannel(CHANNELINDEX nChn, bool bSolo); + bool IsChannelSolo(CHANNELINDEX nChn) const; // -! NEW_FEATURE#0012 - BOOL SurroundChannel(UINT nChn, BOOL bSurround); - BOOL SetChannelGlobalVolume(UINT nChn, UINT nVolume); - BOOL SetChannelDefaultPan(UINT nChn, UINT nPan); - BOOL IsChannelMuted(UINT nChn) const; - BOOL IsSampleMuted(UINT nSample) const; - BOOL IsInstrumentMuted(UINT nInstr) const; + bool SurroundChannel(CHANNELINDEX nChn, bool bSurround); + bool SetChannelGlobalVolume(CHANNELINDEX nChn, UINT nVolume); + bool SetChannelDefaultPan(CHANNELINDEX nChn, UINT nPan); + bool IsChannelMuted(CHANNELINDEX nChn) const; + bool IsSampleMuted(SAMPLEINDEX nSample) const; + bool IsInstrumentMuted(INSTRUMENTINDEX nInstr) const; // -> CODE#0015 // -> DESC="channels management dlg" - BOOL NoFxChannel(UINT nChn, BOOL bNoFx, BOOL updateMix = TRUE); - BOOL IsChannelNoFx(UINT nChn) const; - BOOL IsChannelRecord1(UINT channel); - BOOL IsChannelRecord2(UINT channel); - BYTE IsChannelRecord(UINT channel); - void Record1Channel(UINT channel, BOOL select = TRUE); - void Record2Channel(UINT channel, BOOL select = TRUE); - void ReinitRecordState(BOOL unselect = TRUE); + bool NoFxChannel(CHANNELINDEX nChn, bool bNoFx, bool updateMix = true); + bool IsChannelNoFx(CHANNELINDEX nChn) const; + bool IsChannelRecord1(CHANNELINDEX channel); + bool IsChannelRecord2(CHANNELINDEX channel); + BYTE IsChannelRecord(CHANNELINDEX channel); + void Record1Channel(CHANNELINDEX channel, bool select = true); + void Record2Channel(CHANNELINDEX channel, bool select = true); + void ReinitRecordState(bool unselect = true); // -! NEW_FEATURE#0015 - UINT GetNumChannels() const { return m_SndFile.m_nChannels; } - UINT GetPatternSize(UINT nPat) const; + CHANNELINDEX GetNumChannels() const { return m_SndFile.m_nChannels; } + UINT GetPatternSize(PATTERNINDEX nPat) const; BOOL AdjustEndOfSample(UINT nSample); BOOL IsChildSample(UINT nIns, UINT nSmp) const; UINT FindSampleParent(UINT nSmp) const; Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2009-09-17 16:11:47 UTC (rev 368) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2009-09-18 18:48:59 UTC (rev 369) @@ -2537,8 +2537,8 @@ pModDoc = GetDocumentFromItem(hItem); if (pModDoc) { - UINT nSamples = pModDoc->GetNumSamples(); - UINT nInstruments = pModDoc->GetNumInstruments(); + SAMPLEINDEX nSamples = pModDoc->GetNumSamples(); + INSTRUMENTINDEX nInstruments = pModDoc->GetNumInstruments(); if ((dwItemType == MODITEM_SAMPLE) && (!nInstruments)) { for (UINT i=1; i<=nSamples; i++) @@ -2568,8 +2568,8 @@ pModDoc = GetDocumentFromItem(hItem); if (pModDoc) { - UINT nSamples = pModDoc->GetNumSamples(); - UINT nInstruments = pModDoc->GetNumInstruments(); + SAMPLEINDEX nSamples = pModDoc->GetNumSamples(); + INSTRUMENTINDEX nInstruments = pModDoc->GetNumInstruments(); if ((dwItemType == MODITEM_SAMPLE) || (dwItemType == MODITEM_INSTRUMENT)) { for (UINT i=1; i<=nSamples; i++) Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2009-09-17 16:11:47 UTC (rev 368) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2009-09-18 18:48:59 UTC (rev 369) @@ -1362,9 +1362,9 @@ if (!k) { xih.vibtype = Samples[n].nVibType; - xih.vibsweep = Samples[n].nVibSweep; - xih.vibdepth = Samples[n].nVibDepth; - xih.vibrate = Samples[n].nVibRate; + xih.vibsweep = min(Samples[n].nVibSweep, 255); + xih.vibdepth = min(Samples[n].nVibDepth, 15); + xih.vibrate = min(Samples[n].nVibRate, 63); } if (nsamples < 32) smptable[nsamples++] = n; k = nsamples - 1; @@ -1693,7 +1693,7 @@ if (pSmp->nPan > 256) pSmp->nPan = 256; if (pis->dfp & 0x80) pSmp->uFlags |= CHN_PANNING; pSmp->nVibType = autovibit2xm[pis->vit & 7]; - pSmp->nVibSweep = (pis->vir + 3) / 4; + pSmp->nVibSweep = pis->vir; pSmp->nVibDepth = pis->vid; pSmp->nVibRate = pis->vis; UINT flags = (pis->cvt & 1) ? RS_PCM8S : RS_PCM8U; @@ -1944,9 +1944,9 @@ itss.vol = psmp->nVolume >> 2; itss.dfp = psmp->nPan >> 2; itss.vit = autovibxm2it[psmp->nVibType & 7]; - itss.vir = (psmp->nVibSweep < 64) ? psmp->nVibSweep*4 : 255; - itss.vid = psmp->nVibDepth; - itss.vis = psmp->nVibRate; + itss.vir = min(psmp->nVibSweep, 255); + itss.vid = min(psmp->nVibDepth, 32); + itss.vis = min(psmp->nVibRate, 64); if (psmp->uFlags & CHN_PANNING) itss.dfp |= 0x80; itss.cvt = 0x01; smpsize = psmp->nLength; Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-09-17 16:11:47 UTC (rev 368) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-09-18 18:48:59 UTC (rev 369) @@ -40,6 +40,7 @@ BYTE nVibSweep; BYTE nVibDepth; BYTE nVibRate; + CHAR name[32]; CHAR filename[22]; // Return the size of one (elementary) sample in bytes. @@ -545,7 +546,10 @@ public: // for Editing CModDoc* m_pModDoc; - UINT m_nType, m_nChannels, m_nSamples, m_nInstruments; + UINT m_nType; + CHANNELINDEX m_nChannels; + SAMPLEINDEX m_nSamples; + INSTRUMENTINDEX m_nInstruments; UINT m_nDefaultSpeed, m_nDefaultTempo, m_nDefaultGlobalVolume; DWORD m_dwSongFlags; // Song flags SONG_XXXX bool m_bIsRendering; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-09-20 13:09:20
|
Revision: 371 http://modplug.svn.sourceforge.net/modplug/?rev=371&view=rev Author: saga-games Date: 2009-09-20 13:09:10 +0000 (Sun, 20 Sep 2009) Log Message: ----------- [Fix] Sequence Editor: Clicking on an order moved it when the mouse button was released after skipping to another order (e.g. during playback) - Bug was introduced with multi-order dragging. [Fix] S3M Loader: Limit min sample preamp value to 0x10 Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/soundlib/Load_s3m.cpp Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-09-20 13:04:44 UTC (rev 370) +++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-09-20 13:09:10 UTC (rev 371) @@ -659,6 +659,7 @@ SetCurSel(nOrder, true, ih->ShiftPressed()); } m_bDragging = IsOrderInMargins(m_nScrollPos, oldXScroll) ? false : true; + if(m_bDragging == true) { m_nDragOrder = GetCurSel(true).nOrdLo; @@ -695,8 +696,8 @@ // drop before or after the selection bool bMoveBack = !(m_nDragOrder < (UINT)m_nDropPos); // don't do anything if drop position is inside the selection - if(m_nDropPos >= selection.nOrdLo && m_nDropPos <= selection.nOrdHi) return; - // drag or order or multiple orders? + if(m_nDropPos >= selection.nOrdLo && m_nDropPos <= selection.nOrdHi || m_nDragOrder == m_nDropPos) return; + // drag one order or multiple orders? bool bMultiSelection = (selection.nOrdLo != selection.nOrdHi); for(int i = 0; i <= nMoveCount; i++) Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-09-20 13:04:44 UTC (rev 370) +++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-09-20 13:09:10 UTC (rev 371) @@ -276,7 +276,7 @@ m_nDefaultGlobalVolume = psfh.globalvol << 2; if(!m_nDefaultGlobalVolume && psfh.cwtv < 0x1320) m_nDefaultGlobalVolume = 256; // not very reliable, but it fixes a few tunes if(m_nDefaultGlobalVolume > 256) m_nDefaultGlobalVolume = 256; - m_nSamplePreAmp = psfh.mastervol & 0x7F; // Bit 8 = Stereo (we always use stereo) + m_nSamplePreAmp = CLAMP(psfh.mastervol & 0x7F, 0x10, 0x7F); // Bit 8 = Stereo (we always use stereo) // Channels m_nChannels = 4; for (UINT ich=0; ich<32; ich++) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-09-20 13:44:31
|
Revision: 372 http://modplug.svn.sourceforge.net/modplug/?rev=372&view=rev Author: saga-games Date: 2009-09-20 13:44:24 +0000 (Sun, 20 Sep 2009) Log Message: ----------- [Mod] Store configuration and tuning files in %APPDATA% if possible. Can be disabled by adding UseAppDataDirectory=0 to [Paths] in mptrack.ini. Modified Paths: -------------- trunk/OpenMPT/mptrack/AutoSaver.cpp trunk/OpenMPT/mptrack/InputHandler.cpp trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/Moptions.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/Mptrack.h trunk/OpenMPT/soundlib/Sndfile.cpp Modified: trunk/OpenMPT/mptrack/AutoSaver.cpp =================================================================== --- trunk/OpenMPT/mptrack/AutoSaver.cpp 2009-09-20 13:09:10 UTC (rev 371) +++ trunk/OpenMPT/mptrack/AutoSaver.cpp 2009-09-20 13:44:24 UTC (rev 372) @@ -191,8 +191,8 @@ if (m_bUseOriginalPath) { if (pModDoc->m_bHasValidPath) { // Check that the file has a user-chosen path name = pModDoc->GetPathName(); - } else { // if it doesnt, put it in executable dir - name = CMainFrame::m_csExecutableDirectoryPath + pModDoc->GetTitle(); + } else { // if it doesnt, put it in settings dir + name = theApp.GetConfigPath() + pModDoc->GetTitle(); } } else { @@ -271,7 +271,7 @@ CString fullPath = pModDoc->GetPathName(); path = fullPath.Left(fullPath.GetLength()-pModDoc->GetTitle().GetLength()); //remove file name if necessary } else { - path = CMainFrame::m_csExecutableDirectoryPath; + path = theApp.GetConfigPath(); } } else { path = m_csPath; Modified: trunk/OpenMPT/mptrack/InputHandler.cpp =================================================================== --- trunk/OpenMPT/mptrack/InputHandler.cpp 2009-09-20 13:09:10 UTC (rev 371) +++ trunk/OpenMPT/mptrack/InputHandler.cpp 2009-09-20 13:44:24 UTC (rev 372) @@ -23,7 +23,7 @@ activeCommandSet = new CCommandSet(); CCommandSet::s_bShowErrorOnUnknownKeybinding = (CMainFrame::GetMainFrame()->GetPrivateProfileLong("Misc", "ShowErrorOnUnknownKeybinding", 1, theApp.GetConfigFileName()) != 0); - CString sDefaultPath = CMainFrame::m_csExecutableDirectoryPath + TEXT("Keybindings.mkb"); + CString sDefaultPath = CString(theApp.GetConfigPath()) + TEXT("Keybindings.mkb"); if (sDefaultPath.GetLength() > MAX_PATH - 1) sDefaultPath = ""; Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2009-09-20 13:09:10 UTC (rev 371) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2009-09-20 13:44:24 UTC (rev 372) @@ -267,8 +267,6 @@ CAutoSaver *CMainFrame::m_pAutoSaver = NULL; //rewbs.autosave CPerformanceCounter *CMainFrame::m_pPerfCounter = NULL; -CString CMainFrame::m_csExecutableDirectoryPath = ""; - static UINT indicators[] = { ID_SEPARATOR, // status line indicator @@ -285,17 +283,6 @@ CMainFrame::CMainFrame() //---------------------- { - { - char path[_MAX_PATH]; - char exedrive[_MAX_DRIVE]; - char exedir[_MAX_DIR]; - GetModuleFileName(NULL, path, MAX_PATH); - _splitpath(path, exedrive, exedir, NULL, NULL); - memset(path, 0, sizeof(path)); - _makepath(path, exedrive, exedir, NULL, NULL); - m_csExecutableDirectoryPath = path; //path should end with \ - } - m_bModTreeHasFocus = false; //rewbs.customKeys m_pNoteMapHasFocus = NULL; //rewbs.customKeys m_bOptionsLocked = false; //rewbs.customKeys Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2009-09-20 13:09:10 UTC (rev 371) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2009-09-20 13:44:24 UTC (rev 372) @@ -383,7 +383,6 @@ CString m_csRegExt; CString m_csRegSettings; CString m_csRegWindow; - static CString m_csExecutableDirectoryPath; //To contain path of executable directory // Globals static UINT m_nLastOptionsPage, m_nFilterIndex; static BOOL gbMdiMaximize; Modified: trunk/OpenMPT/mptrack/Moptions.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moptions.cpp 2009-09-20 13:09:10 UTC (rev 371) +++ trunk/OpenMPT/mptrack/Moptions.cpp 2009-09-20 13:44:24 UTC (rev 372) @@ -562,7 +562,7 @@ "OpenMPT Color Schemes|*.mptcolor|" "All Files (*.*)|*.*||", this); - dlg.m_ofn.lpstrInitialDir = CMainFrame::m_csExecutableDirectoryPath; + dlg.m_ofn.lpstrInitialDir = theApp.GetConfigPath(); if (dlg.DoModal() != IDOK) return; TCHAR sFilename[MAX_PATH]; @@ -584,7 +584,7 @@ OFN_HIDEREADONLY| OFN_ENABLESIZING | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_NOREADONLYRETURN, "OpenMPT Color Schemes|*.mptcolor|", this); - dlg.m_ofn.lpstrInitialDir = CMainFrame::m_csExecutableDirectoryPath; + dlg.m_ofn.lpstrInitialDir = theApp.GetConfigPath(); if (dlg.DoModal() != IDOK) return; TCHAR sFilename[MAX_PATH]; Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2009-09-20 13:09:10 UTC (rev 371) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2009-09-20 13:44:24 UTC (rev 372) @@ -407,11 +407,11 @@ wsprintf(s, "Midi%d", iMidi); else wsprintf(s, "Perc%d", iMidi & 0x7F); - if ((glpMidiLibrary->MidiMap[iMidi][1] == ':') && (lpszConfigFile[1] == ':') + /*if ((glpMidiLibrary->MidiMap[iMidi][1] == ':') && (lpszConfigFile[1] == ':') && ((glpMidiLibrary->MidiMap[iMidi][0]|0x20) == (lpszConfigFile[0]|0x20))) { strcpy(szFileName, glpMidiLibrary->MidiMap[iMidi]+2); - } else + } else*/ { strcpy(szFileName, glpMidiLibrary->MidiMap[iMidi]); } @@ -669,6 +669,129 @@ exit(-1); } +void CTrackApp::MoveConfigFile(TCHAR sFileName[_MAX_PATH], TCHAR sSubDir[_MAX_PATH], TCHAR sNewFileName[_MAX_PATH]) +//----------------------------------------------------------------------------------------------------------------- +{ + // copy a config file from the exe directory to the new config dirs + TCHAR sOldPath[_MAX_PATH], sNewPath[_MAX_PATH]; + strcpy(sOldPath, m_szExePath); + if(sSubDir[0]) + strcat(sOldPath, sSubDir); + strcat(sOldPath, sFileName); + + strcpy(sNewPath, m_szConfigDirectory); + if(sSubDir[0]) + strcat(sNewPath, sSubDir); + if(sNewFileName[0]) + strcat(sNewPath, sNewFileName); + else + strcat(sNewPath, sFileName); + + if(PathFileExists(sNewPath) == 0 && PathFileExists(sOldPath) != 0) + { + MoveFile(sOldPath, sNewPath); + } +} + + +void CTrackApp::SetupPaths() +//-------------------------- +{ + if(GetModuleFileName(NULL, m_szExePath, _MAX_PATH)) + { + TCHAR szDrive[_MAX_DRIVE] = "", szDir[_MAX_PATH] = ""; + _splitpath(m_szExePath, szDrive, szDir, NULL, NULL); + strcpy(m_szExePath, szDrive); + strcat(m_szExePath, szDir); + } + + m_szConfigDirectory[0] = 0; + // Try to find a nice directory where we should store our settings (default: %APPDATA%) + bool bIsAppDir = false; + if(!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, m_szConfigDirectory))) + { + if(!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, m_szConfigDirectory))) + { + strcpy(m_szConfigDirectory, m_szExePath); + bIsAppDir = true; + } + } + + // Check if the user prefers to use the app's directory + strcpy(m_szConfigFileName, m_szExePath); // config file + strcat(m_szConfigFileName, "mptrack.ini"); + if(GetPrivateProfileInt("Paths", "UseAppDataDirectory", 1, m_szConfigFileName) == 0) + { + strcpy(m_szConfigDirectory, m_szExePath); + bIsAppDir = true; + } + + if(!bIsAppDir) + { + // Store our app settings in %APPDATA% or "My Files" + strcat(m_szConfigDirectory, "\\OpenMPT\\"); + + // Path doesn't exist yet, so it has to be created + if(PathIsDirectory(m_szConfigDirectory) == 0) + { + CreateDirectory(m_szConfigDirectory, 0); + } + + // Move files if necessary. + MoveConfigFile("mptrack.ini"); + MoveConfigFile("plugin.cache"); + MoveConfigFile("mpt_intl.ini"); + MoveConfigFile("default.mkb", "", "Keybindings.mkb"); + } + + // Create tunings dir + strcpy(m_szTuningsDirectory, m_szConfigDirectory); + strcat(m_szTuningsDirectory, "tunings\\"); + + if(PathIsDirectory(m_szTuningsDirectory) == 0) + { + CreateDirectory(m_szTuningsDirectory, 0); + } + + if(!bIsAppDir) + { + // Import old tunings + TCHAR sOldTunings[_MAX_PATH]; + strcpy(sOldTunings, m_szExePath); + strcat(sOldTunings, "tunings\\"); + + if(PathIsDirectory(sOldTunings) != 0) + { + TCHAR sSearchPattern[_MAX_PATH]; + strcpy(sSearchPattern, sOldTunings); + strcat(sSearchPattern, "*.*"); + WIN32_FIND_DATA FindFileData; + HANDLE hFind; + hFind = FindFirstFile(sSearchPattern, &FindFileData); + if(hFind != INVALID_HANDLE_VALUE) + { + do + { + MoveConfigFile(FindFileData.cFileName, "tunings\\"); + } while(FindNextFile(hFind, &FindFileData) != 0); + } + FindClose(hFind); + RemoveDirectory(sOldTunings); + } + } + + // Set up default file locations + strcpy(m_szConfigFileName, m_szConfigDirectory); // config file + strcat(m_szConfigFileName, "mptrack.ini"); + + strcpy(m_szStringsFileName, m_szConfigDirectory); // I18N file + strcat(m_szStringsFileName, "mpt_intl.ini"); + + strcpy(m_szPluginCacheFileName, m_szConfigDirectory); // plugin cache + strcat(m_szPluginCacheFileName, "plugin.cache"); + +} + BOOL CTrackApp::InitInstance() //---------------------------- { @@ -711,35 +834,9 @@ // Disabled by rewbs for smoothVST. Might cause minor perf issues due to increased cache misses? #endif - m_szConfigFileName[0] = 0; - m_szStringsFileName[0] = 0; + // Set up paths to store configuration in + SetupPaths(); - if (GetModuleFileName(NULL, m_szConfigFileName, sizeof(m_szConfigFileName))) - { - CHAR szDrive[_MAX_DRIVE]="", szDir[_MAX_PATH]=""; - _splitpath(m_szConfigFileName, szDrive, szDir, NULL, NULL); - m_szConfigFileName[0] = 0; - lstrcpyn(m_szConfigFileName, szDrive, sizeof(m_szConfigFileName)); - strncat(m_szConfigFileName, szDir, sizeof(m_szConfigFileName)); - m_szConfigFileName[sizeof(m_szConfigFileName)-1] = 0; - strncat(m_szConfigFileName, "mptrack.ini", sizeof(m_szConfigFileName)); - m_szConfigFileName[sizeof(m_szConfigFileName)-1] = 0; - - m_szPluginCacheFileName[0] = 0; - lstrcpyn(m_szPluginCacheFileName, szDrive, sizeof(m_szPluginCacheFileName)); - strncat(m_szPluginCacheFileName, szDir, sizeof(m_szPluginCacheFileName)); - m_szPluginCacheFileName[sizeof(m_szPluginCacheFileName)-1] = 0; - strncat(m_szPluginCacheFileName, "plugin.cache", sizeof(m_szPluginCacheFileName)); - m_szPluginCacheFileName[sizeof(m_szPluginCacheFileName)-1] = 0; - - m_szStringsFileName[0] = 0; - lstrcpyn(m_szStringsFileName, szDrive, sizeof(m_szStringsFileName)); - strncat(m_szStringsFileName, szDir, sizeof(m_szStringsFileName)); - m_szStringsFileName[sizeof(m_szStringsFileName)-1] = 0; - strncat(m_szStringsFileName, "mpt_intl.ini", sizeof(m_szStringsFileName)); - m_szStringsFileName[sizeof(m_szStringsFileName)-1] = 0; - } - //Force use of custom ini file rather than windowsDir\executableName.ini if (m_pszProfileName) { free((void *)m_pszProfileName); Modified: trunk/OpenMPT/mptrack/Mptrack.h =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.h 2009-09-20 13:09:10 UTC (rev 371) +++ trunk/OpenMPT/mptrack/Mptrack.h 2009-09-20 13:44:24 UTC (rev 372) @@ -140,9 +140,12 @@ HANDLE m_hAlternateResourceHandle; // Default macro configuration MODMIDICFG m_MidiCfg; - CHAR m_szConfigFileName[_MAX_PATH]; - CHAR m_szPluginCacheFileName[_MAX_PATH]; - CHAR m_szStringsFileName[_MAX_PATH]; + TCHAR m_szExePath[_MAX_PATH]; + TCHAR m_szConfigDirectory[_MAX_PATH]; + TCHAR m_szTuningsDirectory[_MAX_PATH]; + TCHAR m_szConfigFileName[_MAX_PATH]; + TCHAR m_szPluginCacheFileName[_MAX_PATH]; + TCHAR m_szStringsFileName[_MAX_PATH]; #ifdef UPDATECHECKENABLED // Internet request context @@ -184,6 +187,8 @@ BOOL IsDebug() const { return m_bDebugMode; } LPCSTR GetConfigFileName() const { return m_szConfigFileName; } LPCSTR GetPluginCacheFileName() const { return m_szPluginCacheFileName; } + LPCSTR GetConfigPath() const { return m_szConfigDirectory; } + void SetupPaths(); // Splash Screen protected: @@ -261,6 +266,8 @@ private: static void LoadRegistryDLS(); + + void MoveConfigFile(TCHAR sFileName[_MAX_PATH], TCHAR sSubDir[_MAX_PATH] = "", TCHAR sNewFileName[_MAX_PATH] = ""); }; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-09-20 13:09:10 UTC (rev 371) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-09-20 13:44:24 UTC (rev 372) @@ -2896,7 +2896,7 @@ } // Load local tunings. - s_pTuningsSharedLocal->SetSavefilePath(std::string(CMainFrame::m_csExecutableDirectoryPath + "tunings\\local_tunings" + CTuningCollection::s_FileExtension.c_str())); + s_pTuningsSharedLocal->SetSavefilePath(std::string(std::string(theApp.GetConfigPath()) + "tunings\\local_tunings" + CTuningCollection::s_FileExtension.c_str())); s_pTuningsSharedLocal->Deserialize(); // Enabling adding/removing of tunings for standard collection This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |