From: <sag...@us...> - 2009-10-12 00:45:09
|
Revision: 396 http://modplug.svn.sourceforge.net/modplug/?rev=396&view=rev Author: saga-games Date: 2009-10-12 00:44:56 +0000 (Mon, 12 Oct 2009) Log Message: ----------- [New] MOD Format: Support for the EFx command (Invert Loop). One has to pay attention when working with this command as it effictively trashes samples. [Fix] IT Specs: Original IT specs concerning max orders/patterns were wrong. IT can handle up to 257 orders (as the last order is always ---, so it's actually 256 accessible orders), so the saving routines were also updated a bit. [Fix] Instrument editor: When playing an instrument and disabling its envelopes at the same time, they're stopped (prevents filter envelope from turning into a pitch envelope) [Imp] Instrument editor: Can now enter insanely high values into sample frequency input field (as they are supported by Impulse Tracker), allow only 65536 Hz for S3M files. [Imp] Mod Creation: Ensure that the order length fits the current mod specifications (this was problematic when creating .MOD files) [Imp] Playback: Added some more standard playback frequencies (176KHz, 192KHz) [Imp] XM Loader: Allow to load modules with an empty order list (as they are, in fact, valid XM files) [Ref] Some more internal refactoring. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/Draw_pat.cpp trunk/OpenMPT/mptrack/EffectVis.cpp trunk/OpenMPT/mptrack/Mod2wave.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Mpdlgs.cpp trunk/OpenMPT/mptrack/Mpdlgs.h trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/mod2wave.h trunk/OpenMPT/soundlib/IT_DEFS.H trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_s3m.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/Snd_defs.h trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp trunk/OpenMPT/soundlib/Tables.cpp trunk/OpenMPT/soundlib/mod_specifications.h Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-10-12 00:44:56 UTC (rev 396) @@ -2652,7 +2652,7 @@ int n = GetDlgItemInt(IDC_EDIT5); if (m_pSndFile->m_nType & (MOD_TYPE_IT|MOD_TYPE_S3M|MOD_TYPE_MPT)) { - if ((n >= 2000) && (n <= 256000) && (n != (int)m_pSndFile->Samples[m_nSample].nC5Speed)) + if ((n > 0) && (n <= (m_pSndFile->m_nType & MOD_TYPE_S3M) ? 65535 : 9999999) && (n != (int)m_pSndFile->Samples[m_nSample].nC5Speed)) { m_pSndFile->Samples[m_nSample].nC5Speed = n; int transp = CSoundFile::FrequencyToTranspose(n) >> 7; @@ -2688,7 +2688,7 @@ { LONG ft = CSoundFile::FrequencyToTranspose(m_pSndFile->Samples[m_nSample].nC5Speed) & 0x7f; n = CSoundFile::TransposeToFrequency(n, ft); - if ((n >= 500) && (n <= 256000) && (n != (int)m_pSndFile->Samples[m_nSample].nC5Speed)) + if ((n > 0) && (n <= (m_pSndFile->m_nType & MOD_TYPE_S3M) ? 65535 : 9999999) && (n != (int)m_pSndFile->Samples[m_nSample].nC5Speed)) { CHAR s[32]; m_pSndFile->Samples[m_nSample].nC5Speed = n; @@ -3133,7 +3133,7 @@ UINT d = pSmp->nC5Speed; if (d < 1) d = 8363; d += (pos * m_nFinetuneStep); - pSmp->nC5Speed = CLAMP(d, 579, 139921); // B-8, C-1 + pSmp->nC5Speed = CLAMP(d, 1, 9999999); // 9999999 is max. in Impulse Tracker int transp = CSoundFile::FrequencyToTranspose(pSmp->nC5Speed) >> 7; int basenote = 60 - transp; if (basenote < BASENOTE_MIN) basenote = BASENOTE_MIN; Modified: trunk/OpenMPT/mptrack/Draw_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Draw_pat.cpp 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/mptrack/Draw_pat.cpp 2009-10-12 00:44:56 UTC (rev 396) @@ -1519,7 +1519,7 @@ case 3: case 4: // display effect command - if (!pModDoc->GetEffectName(s, m->command, m->param, FALSE, nChn)) s[0] = 0; + if (!pModDoc->GetEffectName(s, m->command, m->param, false, nChn)) s[0] = 0; break; } } Modified: trunk/OpenMPT/mptrack/EffectVis.cpp =================================================================== --- trunk/OpenMPT/mptrack/EffectVis.cpp 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/mptrack/EffectVis.cpp 2009-10-12 00:44:56 UTC (rev 396) @@ -752,7 +752,7 @@ int k; for (UINT i=0; i<numfx; i++) { - if (m_pModDoc->GetEffectInfo(i, s, TRUE)) + if (m_pModDoc->GetEffectInfo(i, s, true)) { k =m_cmbEffectList.AddString(s); m_cmbEffectList.SetItemData(k, i); Modified: trunk/OpenMPT/mptrack/Mod2wave.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mod2wave.cpp 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/mptrack/Mod2wave.cpp 2009-10-12 00:44:56 UTC (rev 396) @@ -62,9 +62,9 @@ //----------------------------------------------------------------------------------- { m_bGivePlugsIdleTime = false; - m_bNormalize = FALSE; - m_bHighQuality = FALSE; - m_bSelectPlay = FALSE; + m_bNormalize = false; + m_bHighQuality = false; + m_bSelectPlay = false; if(nMinOrder != ORDERINDEX_INVALID && nMaxOrder != ORDERINDEX_INVALID) { // render selection @@ -235,13 +235,13 @@ { if (m_dwFileLimit) m_dwFileLimit = GetDlgItemInt(IDC_EDIT1, NULL, FALSE); if (m_dwSongLimit) m_dwSongLimit = GetDlgItemInt(IDC_EDIT2, NULL, FALSE); - m_bSelectPlay = IsDlgButtonChecked(IDC_RADIO2) ? TRUE : FALSE; - m_nMinOrder = GetDlgItemInt(IDC_EDIT3, NULL, FALSE); - m_nMaxOrder = GetDlgItemInt(IDC_EDIT4, NULL, FALSE); - if (m_nMaxOrder < m_nMinOrder) m_bSelectPlay = FALSE; - //m_bHighQuality = IsDlgButtonChecked(IDC_CHECK3) ? TRUE : FALSE; //rewbs.resamplerConf - we don't want this anymore. - m_bNormalize = IsDlgButtonChecked(IDC_CHECK5) ? TRUE : FALSE; - m_bGivePlugsIdleTime = IsDlgButtonChecked(IDC_GIVEPLUGSIDLETIME) ? TRUE : FALSE; + m_bSelectPlay = IsDlgButtonChecked(IDC_RADIO2) ? true : false; + m_nMinOrder = (ORDERINDEX)GetDlgItemInt(IDC_EDIT3, NULL, FALSE); + m_nMaxOrder = (ORDERINDEX)GetDlgItemInt(IDC_EDIT4, NULL, FALSE); + if (m_nMaxOrder < m_nMinOrder) m_bSelectPlay = false; + //m_bHighQuality = IsDlgButtonChecked(IDC_CHECK3) ? true : false; //rewbs.resamplerConf - we don't want this anymore. + m_bNormalize = IsDlgButtonChecked(IDC_CHECK5) ? true : false; + m_bGivePlugsIdleTime = IsDlgButtonChecked(IDC_GIVEPLUGSIDLETIME) ? true : false; if (m_bGivePlugsIdleTime) { if (MessageBox("You only need slow render if you are experiencing dropped notes with a Kontakt based sampler with Direct-From-Disk enabled.\nIt will make rendering *very* slow.\n\nAre you sure you want to enable slow render?", "Really enable slow render?", MB_YESNO) == IDNO ) { @@ -260,7 +260,7 @@ WaveFormat.Format.wFormatTag = WAVE_FORMAT_PCM; WaveFormat.Format.nSamplesPerSec = m_CbnSampleRate.GetItemData(m_CbnSampleRate.GetCurSel()); if (WaveFormat.Format.nSamplesPerSec < 11025) WaveFormat.Format.nSamplesPerSec = 11025; - if (WaveFormat.Format.nSamplesPerSec > 96000) WaveFormat.Format.nSamplesPerSec = 96000; //ericus' fix: 44100 -> 96000 + if (WaveFormat.Format.nSamplesPerSec > MAX_SAMPLE_RATE) WaveFormat.Format.nSamplesPerSec = MAX_SAMPLE_RATE; WaveFormat.Format.nChannels = (WORD)(dwFormat >> 8); if ((WaveFormat.Format.nChannels != 1) && (WaveFormat.Format.nChannels != 4)) WaveFormat.Format.nChannels = 2; WaveFormat.Format.wBitsPerSample = (WORD)(dwFormat & 0xFF); @@ -627,7 +627,7 @@ if (oldVol > 128) m_pSndFile->SetMasterVolume(128); } else { - m_bNormalize = FALSE; + m_bNormalize = false; } m_pSndFile->ResetChannels(); CSoundFile::InitPlayer(TRUE); Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-12 00:44:56 UTC (rev 396) @@ -148,6 +148,8 @@ // Refresh mix levels now that the correct mod type has been set m_SndFile.m_nMixLevels = m_SndFile.GetModSpecifications().defaultMixLevels; m_SndFile.m_pConfig->SetMixLevels(m_SndFile.m_nMixLevels); + // ...and the order length + m_SndFile.Order.resize(m_SndFile.GetModSpecifications().ordersMax); theApp.GetDefaultMidiMacro(&m_SndFile.m_MidiCfg); ReinitRecordState(); @@ -1962,7 +1964,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 68 //rewbs.smoothVST, increased from 64... I wonder what this will break? +#define MAX_FXINFO 69 const MPTEFFECTINFO gFXInfo[MAX_FXINFO] = @@ -2012,6 +2014,7 @@ {CMD_MODCMDEX, 0xF0,0xD0, 0, MOD_TYPE_MODXM, "Note delay"}, {CMD_MODCMDEX, 0xF0,0xE0, 0, MOD_TYPE_MODXM, "Pattern delay"}, {CMD_MODCMDEX, 0xF0,0xF0, 0, MOD_TYPE_XM, "Set active macro"}, + {CMD_MODCMDEX, 0xF0,0xF0, 0, MOD_TYPE_MOD, "Invert Loop"}, // Extended S3M/IT effects {CMD_S3MCMDEX, 0xF0,0x10, 0, MOD_TYPE_S3MITMPT, "Glissando control"}, {CMD_S3MCMDEX, 0xF0,0x20, 0, MOD_TYPE_S3M, "Set finetune"}, @@ -2059,23 +2062,26 @@ } -BOOL CModDoc::GetEffectName(LPSTR pszDescription, UINT command, UINT param, BOOL bXX, int nChn) //rewbs.xinfo: added chan arg -//--------------------------------------------------------------------------------------------- +bool CModDoc::GetEffectName(LPSTR pszDescription, UINT command, UINT param, bool bXX, CHANNELINDEX nChn) //rewbs.xinfo: added chan arg +//------------------------------------------------------------------------------------------------------ { - BOOL bSupported; - int fxndx = -1; + bool bSupported; + UINT fxndx = MAX_FXINFO; pszDescription[0] = 0; - UINT i = 0; - for (i=0; i<MAX_FXINFO; i++) + for (UINT i = 0; i < MAX_FXINFO; i++) { if ((command == gFXInfo[i].dwEffect) // Effect && ((param & gFXInfo[i].dwParamMask) == gFXInfo[i].dwParamValue)) // Value { fxndx = i; - break; + // if format is compatible, everything is fine. if not, let's still search + // for another command. this fixes searching for the EFx command, which + // does different things in MOD format. + if((m_SndFile.m_nType & gFXInfo[i].dwFormats) != 0) + break; } } - if (fxndx < 0) return FALSE; + if (fxndx == MAX_FXINFO) return false; bSupported = ((m_SndFile.m_nType & gFXInfo[fxndx].dwFormats) != 0); if (gFXInfo[fxndx].pszName) { @@ -2084,13 +2090,13 @@ strcpy(pszDescription, " xx: "); LPCSTR pszCmd = (m_SndFile.m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM)) ? gszModCommands : gszS3mCommands; pszDescription[0] = pszCmd[command]; - if ((gFXInfo[fxndx].dwParamMask & 0xF0) == 0xF0) pszDescription[1] = szHexChar[gFXInfo[i].dwParamValue >> 4]; - if ((gFXInfo[fxndx].dwParamMask & 0x0F) == 0x0F) pszDescription[2] = szHexChar[gFXInfo[i].dwParamValue & 0x0F]; + if ((gFXInfo[fxndx].dwParamMask & 0xF0) == 0xF0) pszDescription[1] = szHexChar[gFXInfo[fxndx].dwParamValue >> 4]; + if ((gFXInfo[fxndx].dwParamMask & 0x0F) == 0x0F) pszDescription[2] = szHexChar[gFXInfo[fxndx].dwParamValue & 0x0F]; } strcat(pszDescription, gFXInfo[fxndx].pszName); //rewbs.xinfo //Get channel specific info - if (nChn>=0 && nChn<m_SndFile.m_nChannels) + if (nChn < m_SndFile.m_nChannels) { CString chanSpec = ""; CString macroText= "_no macro_"; @@ -2098,15 +2104,15 @@ { case CMD_MODCMDEX: case CMD_S3MCMDEX: - if ((param&0xF0) == 0xF0) //Set Macro + if ((param & 0xF0) == 0xF0 && !(m_SndFile.m_nType & MOD_TYPE_MOD)) //Set Macro { - macroText = &m_SndFile.m_MidiCfg.szMidiSFXExt[(param&0x0F)*32]; - chanSpec.Format(" to %d: ", param&0x0F); + macroText = &m_SndFile.m_MidiCfg.szMidiSFXExt[(param & 0x0F) * 32]; + chanSpec.Format(" to %d: ", param & 0x0F); } break; case CMD_MIDI: case CMD_SMOOTHMIDI: - if (param<0x80) + if (param < 0x80 && nChn != CHANNELINDEX_INVALID) { macroText = &m_SndFile.m_MidiCfg.szMidiSFXExt[m_SndFile.Chn[nChn].nActiveMacro*32]; chanSpec.Format(": currently %d: ", m_SndFile.Chn[nChn].nActiveMacro); @@ -2170,15 +2176,18 @@ LONG CModDoc::GetIndexFromEffect(UINT command, UINT param) //-------------------------------------------------------- { - for (UINT i=0; i<MAX_FXINFO; i++) + UINT ndx = MAX_FXINFO; + for (UINT i = 0; i < MAX_FXINFO; i++) { if ((command == gFXInfo[i].dwEffect) // Effect && ((param & gFXInfo[i].dwParamMask) == gFXInfo[i].dwParamValue)) // Value { - return i; + ndx = i; + if((m_SndFile.m_nType & gFXInfo[i].dwFormats) != 0) + break; // found fitting format; this is correct for sure } } - return -1; + return ndx; } @@ -2220,7 +2229,7 @@ } -BOOL CModDoc::GetEffectInfo(UINT ndx, LPSTR s, BOOL bXX, DWORD *prangeMin, DWORD *prangeMax) +bool CModDoc::GetEffectInfo(UINT ndx, LPSTR s, bool bXX, DWORD *prangeMin, DWORD *prangeMax) //------------------------------------------------------------------------------------------ { if (s) s[0] = 0; @@ -2370,12 +2379,12 @@ } -BOOL CModDoc::GetEffectNameEx(LPSTR pszName, UINT ndx, UINT param) +bool CModDoc::GetEffectNameEx(LPSTR pszName, UINT ndx, UINT param) //---------------------------------------------------------------- { CHAR s[64]; if (pszName) pszName[0] = 0; - if ((!pszName) || (ndx >= MAX_FXINFO) || (!gFXInfo[ndx].pszName)) return FALSE; + if ((!pszName) || (ndx >= MAX_FXINFO) || (!gFXInfo[ndx].pszName)) return false; wsprintf(pszName, "%s: ", gFXInfo[ndx].pszName); s[0] = 0; @@ -2530,7 +2539,7 @@ case CMD_TREMOR: if(param) { - BYTE ontime = param >> 4, offtime = param & 0x0F; + BYTE ontime = (BYTE)(param >> 4), offtime = (BYTE)(param & 0x0F); if(m_SndFile.m_dwSongFlags & SONG_ITOLDEFFECTS) { ontime++; @@ -2669,6 +2678,7 @@ strcat(s, " rows"); break; case 0xF0: // macro + if(m_SndFile.m_nType & MOD_TYPE_MOD) wsprintf(s, "SF%X", param & 0x0F); break; default: break; @@ -2710,8 +2720,12 @@ case 0xE0: // pattern delay (rows) strcat(s, " rows"); break; - case 0xF0: // macro - wsprintf(s, "SF%X", param & 0x0F); break; + case 0xF0: + if(m_SndFile.m_nType & MOD_TYPE_MOD) + wsprintf(s, "Speed %d", param & 0x0F); // invert loop + else + wsprintf(s, "SF%X", param & 0x0F); // macro + break; default: break; } @@ -2724,7 +2738,7 @@ } } strcat(pszName, s); - return TRUE; + return true; } Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-10-12 00:44:56 UTC (rev 396) @@ -162,13 +162,13 @@ HWND GetFollowWnd() const { return m_hWndFollow; } void SetFollowWnd(HWND hwnd, DWORD dwType); // Effects Description - BOOL GetEffectName(LPSTR s, UINT command, UINT param, BOOL bXX=FALSE, int nChn=-1); // bXX: Nxx: ... + bool GetEffectName(LPSTR pszDescription, UINT command, UINT param, bool bXX = false, CHANNELINDEX nChn = CHANNELINDEX_INVALID); // bXX: Nxx: ... UINT GetNumEffects() const; - BOOL GetEffectInfo(UINT ndx, LPSTR s, BOOL bXX=FALSE, DWORD *prangeMin=NULL, DWORD *prangeMax=NULL); + bool GetEffectInfo(UINT ndx, LPSTR s, bool bXX = false, DWORD *prangeMin=NULL, DWORD *prangeMax=NULL); LONG GetIndexFromEffect(UINT command, UINT param); UINT GetEffectFromIndex(UINT ndx, int &refParam); UINT GetEffectMaskFromIndex(UINT ndx); - BOOL GetEffectNameEx(LPSTR pszName, UINT ndx, UINT param); + bool GetEffectNameEx(LPSTR pszName, UINT ndx, UINT param); BOOL IsExtendedEffect(UINT ndx) const; UINT MapValueToPos(UINT ndx, UINT param); UINT MapPosToValue(UINT ndx, UINT pos); Modified: trunk/OpenMPT/mptrack/Mpdlgs.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mpdlgs.cpp 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/mptrack/Mpdlgs.cpp 2009-10-12 00:44:56 UTC (rev 396) @@ -79,7 +79,9 @@ 48000, 64000, 88200, - 96000 + 96000, + 176400, + 192000, }; Modified: trunk/OpenMPT/mptrack/Mpdlgs.h =================================================================== --- trunk/OpenMPT/mptrack/Mpdlgs.h 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/mptrack/Mpdlgs.h 2009-10-12 00:44:56 UTC (rev 396) @@ -1,7 +1,7 @@ #ifndef _MODPLUGDLGS_ #define _MODPLUGDLGS_ -#define NUMMIXRATE 14 +#define NUMMIXRATE 16 class CSoundFile; class CMainFrame; Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-10-12 00:44:56 UTC (rev 396) @@ -741,6 +741,11 @@ } else { pIns->dwFlags &= ~ENV_VOLUME; + for(CHANNELINDEX nChn = 0; nChn < MAX_CHANNELS; nChn++) + { + if(pSndFile->Chn[nChn].pModInstrument == pIns) + pSndFile->Chn[nChn].dwFlags &= ~CHN_VOLENV; + } } return true; } @@ -774,6 +779,11 @@ } else { pIns->dwFlags &= ~ENV_PANNING; + for(CHANNELINDEX nChn = 0; nChn < MAX_CHANNELS; nChn++) + { + if(pSndFile->Chn[nChn].pModInstrument == pIns) + pSndFile->Chn[nChn].dwFlags &= ~CHN_PANENV; + } } return true; } @@ -808,6 +818,11 @@ } else { pIns->dwFlags &= ~(ENV_PITCH|ENV_FILTER); + for(CHANNELINDEX nChn = 0; nChn < MAX_CHANNELS; nChn++) + { + if(pSndFile->Chn[nChn].pModInstrument == pIns) + pSndFile->Chn[nChn].dwFlags &= ~CHN_PITCHENV; + } } return true; } @@ -841,6 +856,12 @@ } else { pIns->dwFlags &= ~(ENV_PITCH|ENV_FILTER); + // prevent filter envelop from turning into a pitch envelope :) + for(CHANNELINDEX nChn = 0; nChn < MAX_CHANNELS; nChn++) + { + if(pSndFile->Chn[nChn].pModInstrument == pIns) + pSndFile->Chn[nChn].dwFlags &= ~CHN_PITCHENV; + } } return true; } Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-10-12 00:44:56 UTC (rev 396) @@ -756,7 +756,7 @@ UINT count = m_pModDoc->GetNumEffects(); for (UINT n=0; n<count; n++) { - m_pModDoc->GetEffectInfo(n, s, TRUE); + m_pModDoc->GetEffectInfo(n, s, true); if (s[0]) combo->SetItemData(combo->AddString(s), n); } combo->SetCurSel(0); @@ -1476,7 +1476,7 @@ if (!m_nCommand) combo->SetCurSel(0); for (UINT i=0; i<numfx; i++) { - if (m_pModDoc->GetEffectInfo(i, s, TRUE)) + if (m_pModDoc->GetEffectInfo(i, s, true)) { int k = combo->AddString(s); combo->SetItemData(k, i); @@ -1497,7 +1497,7 @@ { DWORD rangeMin = 0, rangeMax = 0; LONG fxndx = m_pModDoc->GetIndexFromEffect(m_nCommand, m_nParam); - BOOL bEnable = ((fxndx >= 0) && (m_pModDoc->GetEffectInfo(fxndx, NULL, FALSE, &rangeMin, &rangeMax))); + bool bEnable = ((fxndx >= 0) && (m_pModDoc->GetEffectInfo(fxndx, NULL, false, &rangeMin, &rangeMax))); if (bEnable) { slider->EnableWindow(TRUE); Modified: trunk/OpenMPT/mptrack/mod2wave.h =================================================================== --- trunk/OpenMPT/mptrack/mod2wave.h 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/mptrack/mod2wave.h 2009-10-12 00:44:56 UTC (rev 396) @@ -13,7 +13,7 @@ WAVEFORMATEXTENSIBLE WaveFormat; ULONGLONG m_dwFileLimit; DWORD m_dwSongLimit; - BOOL m_bSelectPlay, m_bNormalize, m_bHighQuality, m_bGivePlugsIdleTime; + bool m_bSelectPlay, m_bNormalize, m_bHighQuality, m_bGivePlugsIdleTime; ORDERINDEX m_nMinOrder, m_nMaxOrder; CComboBox m_CbnSampleRate, m_CbnSampleFormat; CEdit m_EditMinOrder, m_EditMaxOrder; @@ -49,19 +49,19 @@ LPCSTR m_lpszFileName; DWORD m_dwFileLimit, m_dwSongLimit; UINT m_nMaxPatterns; - BOOL m_bAbort, m_bNormalize, m_bGivePlugsIdleTime; + bool m_bAbort, m_bNormalize, m_bGivePlugsIdleTime; public: - CDoWaveConvert(CSoundFile *sndfile, LPCSTR fname, PWAVEFORMATEX pwfx, BOOL bNorm, CWnd *parent=NULL):CDialog(IDD_PROGRESS, parent) + CDoWaveConvert(CSoundFile *sndfile, LPCSTR fname, PWAVEFORMATEX pwfx, bool bNorm, CWnd *parent = NULL):CDialog(IDD_PROGRESS, parent) { m_pSndFile = sndfile; m_lpszFileName = fname; m_pWaveFormat = pwfx; - m_bAbort = FALSE; + m_bAbort = false; m_bNormalize = bNorm; m_dwFileLimit = m_dwSongLimit = 0; m_nMaxPatterns = 0; } BOOL OnInitDialog(); - void OnCancel() { m_bAbort = TRUE; } + void OnCancel() { m_bAbort = true; } afx_msg void OnButton1(); DECLARE_MESSAGE_MAP() }; Modified: trunk/OpenMPT/soundlib/IT_DEFS.H =================================================================== --- trunk/OpenMPT/soundlib/IT_DEFS.H 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/soundlib/IT_DEFS.H 2009-10-12 00:44:56 UTC (rev 396) @@ -21,11 +21,11 @@ BYTE mv; BYTE speed; BYTE tempo; - BYTE sep; - BYTE zero; + BYTE sep; // panning separation (0...128) + BYTE pwd; // pitch wheel depth WORD msglength; DWORD msgoffset; - DWORD reserved2; + DWORD reserved; BYTE chnpan[64]; BYTE chnvol[64]; } ITFILEHEADER; Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-10-12 00:44:56 UTC (rev 396) @@ -1805,17 +1805,7 @@ header.highlight_minor = (BYTE)(m_nRowsPerBeat & 0xFF); header.highlight_major = (BYTE)(m_nRowsPerMeasure & 0xFF); - header.ordnum = 0; - //while ((header.ordnum < MAX_ORDERS) /*&& (Order[header.ordnum] < 0xFF)*/) header.ordnum++; //rewbs.AllowSaveHiddenPatterns - //if (header.ordnum < MAX_ORDERS) Order[header.ordnum++] = 0xFF; - //Ericus' implementation is better. -// -> CODE#0013 -// -> DESC="load/save the whole pattern order list" -// while ((header.ordnum < MAX_ORDERS) && (Order[header.ordnum] < 0xFF)) header.ordnum++; -// if (header.ordnum < MAX_ORDERS) Order[header.ordnum++] = 0xFF; - header.ordnum = MAX_ORDERS; - if(Order.size() < MAX_ORDERS) Order.resize(MAX_ORDERS, Order.GetInvalidPatIndex()); - + if(GetType() == MOD_TYPE_MPT) { if(!Order.NeedsExtraDatafield()) header.ordnum = Order.size(); @@ -1823,13 +1813,14 @@ //Crop unused orders from the end. while(header.ordnum > 1 && Order[header.ordnum - 1] == Order.GetInvalidPatIndex()) header.ordnum--; + } else + { + // An additional "---" pattern is appended so Impulse Tracker won't ignore the last order item. + // Interestingly, this can exceed IT's 256 order limit. + header.ordnum = min(Order.GetLengthTailTrimmed(), ModSpecs::itEx.ordersMax) + 1; } - - - if(GetType() != MOD_TYPE_MPT) - Order[MAX_ORDERS-1] = 0xFF; -// -! CODE#0013 + header.insnum = m_nInstruments; header.smpnum = m_nSamples; header.patnum = (GetType() == MOD_TYPE_MPT) ? Patterns.Size() : MAX_PATTERNS; @@ -2486,14 +2477,10 @@ header.highlight_minor = (BYTE)(m_nRowsPerBeat & 0xFF); header.highlight_major = (BYTE)(m_nRowsPerMeasure & 0xFF); - header.ordnum = 0; - header.ordnum=MAX_ORDERS; - while (header.ordnum>0 && Order[header.ordnum-1]==0xFF) { - header.ordnum--; - } - if(header.ordnum + 1 < MAX_ORDERS) - header.ordnum++; + // An additional "---" pattern is appended so Impulse Tracker won't ignore the last order item. + // Interestingly, this can exceed IT's 256 order limit. + header.ordnum = min(Order.GetLengthTailTrimmed(), ModSpecs::it.ordersMax) + 1; header.patnum = MAX_PATTERNS; while ((header.patnum > 0) && (!Patterns[header.patnum-1])) { Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-10-12 00:44:56 UTC (rev 396) @@ -717,7 +717,7 @@ insex[i-1].vol = pSmp->nVolume / 4; insex[i-1].flags = (pSmp->uFlags & CHN_LOOP) ? 1 : 0; if (pSmp->nC5Speed) - insex[i-1].finetune = pSmp->nC5Speed; + insex[i-1].finetune = min(pSmp->nC5Speed, 0xFFFF); else insex[i-1].finetune = TransposeToFrequency(pSmp->RelativeTone, pSmp->nFineTune); UINT flags = RS_PCM8U; Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-10-12 00:44:56 UTC (rev 396) @@ -276,7 +276,7 @@ m_nMinPeriod = 27; m_nMaxPeriod = 54784; - if ((!xmheader.orders) || (xmheader.orders > MAX_ORDERS)) return false; + if (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; Modified: trunk/OpenMPT/soundlib/Snd_defs.h =================================================================== --- trunk/OpenMPT/soundlib/Snd_defs.h 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/soundlib/Snd_defs.h 2009-10-12 00:44:56 UTC (rev 396) @@ -47,7 +47,7 @@ #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_SAMPLE_RATE 192000 #define MAX_ORDERS 256 #define MAX_PATTERNS 240 #define MAX_SAMPLES 4000 Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-10-12 00:44:56 UTC (rev 396) @@ -2522,7 +2522,7 @@ case 0xC0: NoteCut(nChn, param); break; // EDx: Note Delay // EEx: Pattern Delay - // EFx: MOD: Invert Loop, XM: Set Active Midi Macro + // EFx: MOD: Invert Loop / Funk Repeat, XM: Set Active Midi Macro case 0xF0: pChn->nActiveMacro = param; break; } } @@ -3150,11 +3150,11 @@ UINT nNote = pChn->nNewNote; LONG nOldPeriod = pChn->nPeriod; if ((nNote) && (nNote <= NOTE_MAX) && (pChn->nLength)) CheckNNA(nChn, 0, nNote, TRUE); - BOOL bResetEnv = FALSE; + bool bResetEnv = false; if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) { - if ((pChn->nRowInstr) && (param < 0x100)) { InstrumentChange(pChn, pChn->nRowInstr, FALSE, FALSE); bResetEnv = TRUE; } - if (param < 0x100) bResetEnv = TRUE; + if ((pChn->nRowInstr) && (param < 0x100)) { InstrumentChange(pChn, pChn->nRowInstr, FALSE, FALSE); bResetEnv = true; } + if (param < 0x100) bResetEnv = true; } NoteChange(nChn, nNote, IsCompatibleMode(TRK_IMPULSETRACKER) ? true : false, bResetEnv); if (m_nInstruments) { Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-12 00:44:56 UTC (rev 396) @@ -707,12 +707,13 @@ // Load plugins only when m_pModDoc != 0. (can be == 0 for example when examining module samples in treeview. string sNotFound; - bool bSearchIDs[MAX_MIXPLUGINS] = {false}; + bool bSearchIDs[MAX_MIXPLUGINS]; + memset(bSearchIDs, false, MAX_MIXPLUGINS * sizeof(bool)); UINT iShowNotFound = 0; if (gpMixPluginCreateProc && GetpModDoc()) { - for (UINT iPlug = 0; iPlug < MAX_MIXPLUGINS; iPlug++) + for (PLUGINDEX iPlug = 0; iPlug < MAX_MIXPLUGINS; iPlug++) { if ((m_MixPlugins[iPlug].Info.dwPluginId1) || (m_MixPlugins[iPlug].Info.dwPluginId2)) @@ -726,8 +727,8 @@ else { // plugin not found - add to list - BOOL bFound = false; - for(UINT iPlugFind = 0; iPlugFind < iPlug; iPlugFind++) + bool bFound = false; + for(PLUGINDEX iPlugFind = 0; iPlugFind < iPlug; iPlugFind++) if(m_MixPlugins[iPlugFind].Info.dwPluginId2 == m_MixPlugins[iPlug].Info.dwPluginId2) { bFound = true; @@ -746,6 +747,7 @@ } // Display a nice message so the user sees what plugins are missing + // TODO: Use IDD_MODLOADING_WARNINGS dialog (NON-MODAL!) to display all warnings that are encountered when loading a module. if(iShowNotFound) { if(iShowNotFound == 1) @@ -758,7 +760,7 @@ "\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.c_str(), "OpenMPT - Plugins missing", MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION) == IDYES) - for (UINT iPlug = 0; iPlug < MAX_MIXPLUGINS; iPlug++) + for (PLUGINDEX iPlug = 0; iPlug < MAX_MIXPLUGINS; iPlug++) if (bSearchIDs[iPlug] == true) { CString sUrl; @@ -771,7 +773,7 @@ m_pConfig->SetMixLevels(m_nMixLevels); RecalculateGainForAllPlugs(); - if (m_nType && m_nType != MOD_TYPE_MPT) + if (m_nType && (m_nType != MOD_TYPE_MPT)) { SetModSpecsPointer(m_pModSpecs, m_nType); Order.resize(GetModSpecifications().ordersMax); Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-10-12 00:44:56 UTC (rev 396) @@ -200,6 +200,7 @@ LONG nCutSwing, nResSwing; LONG nRestorePanOnNewNote; //If > 0, nPan should be set to nRestorePanOnNewNote - 1 on new note. Used to recover from panswing. UINT nOldGlobalVolSlide; + DWORD nEFxOffset; // offset memory for either Funk Repeat or Invert Loop (EFx, .MOD only) // 8-bit members BYTE nRestoreResonanceOnNewNote; //Like above BYTE nRestoreCutoffOnNewNote; //Like above @@ -223,6 +224,7 @@ BYTE nRowCommand, nRowParam; BYTE nLeftVU, nRightVU; BYTE nActiveMacro, nFilterMode; + BYTE nEFxDelay; // memory for either Funk Repeat or Invert Loop (EFx, .MOD only) uint16 m_RowPlugParam; //NOTE_PCs memory. float m_nPlugParamValueStep; //rewbs.smoothVST Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-10-12 00:44:56 UTC (rev 396) @@ -78,6 +78,7 @@ extern signed char ft2VibratoTable[256]; // -64 .. +64 extern int MixSoundBuffer[MIXBUFFERSIZE*4]; extern int MixRearBuffer[MIXBUFFERSIZE*2]; +extern BYTE ModEFxTable[16]; #ifndef NO_REVERB extern UINT gnReverbSend; @@ -1690,6 +1691,25 @@ } } } + + // .MOD EFx implementation + if((m_nType & MOD_TYPE_MOD) && pChn->nRowCommand == CMD_MODCMDEX && (pChn->nRowParam & 0xF0) == 0xF0) + { + pChn->nEFxDelay += ModEFxTable[pChn->nRowParam & 0x0F]; + if((pChn->dwFlags & CHN_LOOP) && (pChn->nEFxDelay & 0x80)) + { + // invert loop code (PT 1.1A and up) + pChn->nEFxDelay = 0; + + if (++pChn->nEFxOffset >= pChn->nLoopEnd - pChn->nLoopStart) + pChn->nEFxOffset = 0; + + // TRASH IT!!! (Yes, the sample!) + pChn->pSample[pChn->nLoopStart + pChn->nEFxOffset] = ~pChn->pSample[pChn->nLoopStart + pChn->nEFxOffset]; + } + } + + #ifdef MODPLUG_PLAYER // Limit CPU -> > 80% -> don't ramp if ((gnCPUUsage >= 80) && (!pChn->nRealVolume)) Modified: trunk/OpenMPT/soundlib/Tables.cpp =================================================================== --- trunk/OpenMPT/soundlib/Tables.cpp 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/soundlib/Tables.cpp 2009-10-12 00:44:56 UTC (rev 396) @@ -101,6 +101,12 @@ 1724,1628,1536,1450,1368,1292,1220,1150,1086,1026,968,914 }; +// Table for Invert Loop and Funk Repeat effects (EFx, .MOD only) +BYTE ModEFxTable[16] = +{ + 0, 5, 6, 7, 8, 10, 11, 13, + 16, 19, 22, 26, 32, 43, 64, 128 +}; // S3M C-4 periods WORD FreqS3MTable[16] = Modified: trunk/OpenMPT/soundlib/mod_specifications.h =================================================================== --- trunk/OpenMPT/soundlib/mod_specifications.h 2009-10-11 17:35:03 UTC (rev 395) +++ trunk/OpenMPT/soundlib/mod_specifications.h 2009-10-12 00:44:56 UTC (rev 396) @@ -257,8 +257,8 @@ true, //Has notecut. true, //Has noteoff. true, //Has notefade. - 240, //Pattern max. - 200, //Order max. + 200, //Pattern max. + 256, //Order max. 1, //Channel min 64, //Channel max 32, //Min tempo @@ -286,7 +286,7 @@ true, //Has noteoff. true, //Has notefade. 240, //Pattern max. - 255, //Order max. + 256, //Order max. 1, //Channel min 127, //Channel max 32, //Min tempo This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |