From: <sag...@us...> - 2009-10-13 20:21:02
|
Revision: 398 http://modplug.svn.sourceforge.net/modplug/?rev=398&view=rev Author: saga-games Date: 2009-10-13 20:20:48 +0000 (Tue, 13 Oct 2009) Log Message: ----------- [New] Added song flag "PT 1.x Mode" (for .MOD files) that enabled on-the-fly sample swapping as ProTracker did it. [Fix] Further fixes to "Invert Loop" command (thanks, bubsy) [Ref] Moved effect conversion (from format x to y) to CSoundFile as this might be useful for other parts of the program as well. [Ref] Commented song flags a bit more Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/dlg_misc.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/Snd_defs.h trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-10-12 22:04:33 UTC (rev 397) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-10-13 20:20:48 UTC (rev 398) @@ -186,7 +186,7 @@ void SongProperties(); // operations public: - BOOL ChangeModType(UINT nNewType); + BOOL ChangeModType(MODTYPE wType); BOOL ChangeNumChannels(UINT nNewChannels, const bool showCancelInRemoveDlg = true); BOOL ConvertInstrumentsToSamples(); Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-12 22:04:33 UTC (rev 397) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-13 20:20:48 UTC (rev 398) @@ -37,15 +37,15 @@ ////////////////////////////////////////////////////////////////////// // Module type conversion -BOOL CModDoc::ChangeModType(UINT nNewType) -//---------------------------------------- +BOOL CModDoc::ChangeModType(MODTYPE nNewType) +//------------------------------------------- { CHAR s[256]; UINT b64 = 0; - const MODTYPE oldtype = m_SndFile.GetType(); + const MODTYPE nOldType = m_SndFile.GetType(); - if (nNewType == oldtype && nNewType == MOD_TYPE_IT){ + if (nNewType == nOldType && nNewType == MOD_TYPE_IT){ // Even if m_nType doesn't change, we might need to change extension in itp<->it case. // This is because ITP is a HACK and doesn't genuinely change m_nType, // but uses flages instead. @@ -53,11 +53,11 @@ return TRUE; } - if(nNewType == oldtype) return TRUE; + if(nNewType == nOldType) return TRUE; - const bool oldTypeIsMOD = (oldtype == MOD_TYPE_MOD), oldTypeIsXM = (oldtype == MOD_TYPE_XM), - oldTypeIsS3M = (oldtype == MOD_TYPE_S3M), oldTypeIsIT = (oldtype == MOD_TYPE_IT), - oldTypeIsMPT = (oldtype == MOD_TYPE_MPT), oldTypeIsMOD_XM = (oldTypeIsMOD || oldTypeIsXM), + const bool oldTypeIsMOD = (nOldType == MOD_TYPE_MOD), oldTypeIsXM = (nOldType == MOD_TYPE_XM), + oldTypeIsS3M = (nOldType == MOD_TYPE_S3M), oldTypeIsIT = (nOldType == MOD_TYPE_IT), + oldTypeIsMPT = (nOldType == MOD_TYPE_MPT), oldTypeIsMOD_XM = (oldTypeIsMOD || oldTypeIsXM), oldTypeIsS3M_IT_MPT = (oldTypeIsS3M || oldTypeIsIT || oldTypeIsMPT), oldTypeIsIT_MPT = (oldTypeIsIT || oldTypeIsMPT); @@ -172,114 +172,13 @@ { nChannel = (nChannel + 1) % m_SndFile.m_nChannels; // 0...Channels - 1 - ////////////////////////// - // Convert 8-bit Panning - if(m->command == CMD_PANNING8) - { - if(newTypeIsS3M) - { - m->param = (m->param + 1) >> 1; - } - else if(oldTypeIsS3M) - { - if(m->param == 0xA4) - { - // surround remap - m->command = (newTypeIsIT_MPT) ? CMD_S3MCMDEX : CMD_XFINEPORTAUPDOWN; - m->param = 0x91; - } - else - { - m->param = min(m->param << 1, 0xFF); - } - } - } // End if(m->command == CMD_PANNING8) + m_SndFile.ConvertCommand(m, nOldType, nNewType); - ////////////////////////// - // Convert param control - if(oldTypeIsMPT) + // Deal with effect memory for MOD/XM arpeggio + if (oldTypeIsS3M_IT_MPT && newTypeIsMOD_XM) { - if(m->note == NOTE_PC || m->note == NOTE_PCS) - { - m->param = min(MODCOMMAND::maxColumnValue, m->GetValueEffectCol()) * 0x7F / MODCOMMAND::maxColumnValue; - m->command = (m->note == NOTE_PC) ? CMD_MIDI : CMD_SMOOTHMIDI; - m->volcmd = VOLCMD_NONE; - m->note = NOTE_NONE; - } - } // End if(oldTypeIsMPT) - - ///////////////////////////////////////// - // Convert MOD / XM to S3M / IT / MPTM - if(oldTypeIsMOD_XM && newTypeIsS3M_IT_MPT) - { switch(m->command) { - case CMD_MODCMDEX: - CSoundFile::MODExx2S3MSxx(m); - break; - case CMD_VOLUME: - if (!m->volcmd) - { - m->volcmd = VOLCMD_VOLUME; - m->vol = m->param; - if (m->vol > 0x40) m->vol = 0x40; - m->command = m->param = 0; - } - break; - case CMD_PORTAMENTOUP: - if (m->param > 0xDF) m->param = 0xDF; - break; - case CMD_PORTAMENTODOWN: - if (m->param > 0xDF) m->param = 0xDF; - break; - case CMD_XFINEPORTAUPDOWN: - switch(m->param & 0xF0) - { - case 0x10: m->command = CMD_PORTAMENTOUP; m->param = (m->param & 0x0F) | 0xE0; break; - case 0x20: m->command = CMD_PORTAMENTODOWN; m->param = (m->param & 0x0F) | 0xE0; break; - case 0x50: - case 0x60: - case 0x70: - case 0x90: - case 0xA0: - m->command = CMD_S3MCMDEX; - // surround remap (this is the "official" command) - if(newTypeIsS3M && m->param == 0x91) - { - m->command = CMD_PANNING8; - m->param = 0xA4; - } - break; - } - break; - case CMD_KEYOFF: - if(m->note == 0) - { - m->note = (newTypeIsS3M) ? NOTE_NOTECUT : NOTE_KEYOFF; - m->command = CMD_S3MCMDEX; - if(m->param == 0) - m->instr = 0; - m->param = 0xD0 | (m->param & 0x0F); - } - break; - case CMD_PANNINGSLIDE: - // swap L/R - m->param = ((m->param & 0x0F) << 4) | (m->param >> 4); - default: - break; - } - } // End if(oldTypeIsMOD_XM && newTypeIsS3M_IT_MPT) - - - ///////////////////////////////////////// - // Convert S3M / IT / MPTM to MOD / XM - else if (oldTypeIsS3M_IT_MPT && newTypeIsMOD_XM) - { - if(m->note == NOTE_NOTECUT || m->note == NOTE_FADE) - m->note = NOTE_KEYOFF; - - switch(m->command) - { case CMD_ARPEGGIO: // No effect memory in XM / MOD if(m->param == 0) @@ -287,115 +186,14 @@ else cEffectMemory[nChannel][CMD_ARPEGGIO] = m->param; break; - case CMD_S3MCMDEX: - CSoundFile::S3MSxx2MODExx(m); - break; - case CMD_VOLUMESLIDE: - if ((m->param & 0xF0) && ((m->param & 0x0F) == 0x0F)) - { - m->command = CMD_MODCMDEX; - m->param = (m->param >> 4) | 0xA0; - } else - if ((m->param & 0x0F) && ((m->param & 0xF0) == 0xF0)) - { - m->command = CMD_MODCMDEX; - m->param = (m->param & 0x0F) | 0xB0; - } - break; - case CMD_PORTAMENTOUP: - if (m->param >= 0xF0) - { - m->command = CMD_MODCMDEX; - m->param = (m->param & 0x0F) | 0x10; - } else - if (m->param >= 0xE0) - { - m->command = CMD_MODCMDEX; - m->param = (((m->param & 0x0F)+3) >> 2) | 0x10; - } else m->command = CMD_PORTAMENTOUP; - break; - case CMD_PORTAMENTODOWN: - if (m->param >= 0xF0) - { - m->command = CMD_MODCMDEX; - m->param = (m->param & 0x0F) | 0x20; - } else - if (m->param >= 0xE0) - { - m->command = CMD_MODCMDEX; - m->param = (((m->param & 0x0F)+3) >> 2) | 0x20; - } else m->command = CMD_PORTAMENTODOWN; - break; - case CMD_SPEED: - { - UINT spdmax = (nNewType == MOD_TYPE_XM) ? 0x1F : 0x20; - if (m->param > spdmax) m->param = spdmax; - } - break; - case CMD_PANNINGSLIDE: - // swap L/R - m->param = ((m->param & 0x0F) << 4) | (m->param >> 4); - // remove fine slides - if((m->param > 0xF0) || ((m->param & 0x0F) == 0x0F && m->param != 0x0F)) - m->command = CMD_NONE; - default: - break; } - } // End if (oldTypeIsS3M_IT_MPT && newTypeIsMOD_XM) + } - - /////////////////////// - // Convert IT to S3M - else if (oldTypeIsIT_MPT && newTypeIsS3M) + // Adjust effect memory for MOD files + if(newTypeIsMOD) { - if(m->note == NOTE_KEYOFF || m->note == NOTE_FADE) - m->note = NOTE_NOTECUT; - switch(m->command) { - case CMD_S3MCMDEX: - if(m->param == 0x91) - { - // surround remap (this is the "official" command) - m->command = CMD_PANNING8; - m->param = 0xA4; - } - break; - case CMD_SMOOTHMIDI: - m->command = CMD_MIDI; - break; - default: - break; - } - } // End if (oldTypeIsIT_MPT && newTypeIsS3M) - - - - /////////////////////////////////////////////////// - // Convert MOD to anything - adjust effect memory - if (oldTypeIsMOD) - { - 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) - { - if(m->command) switch(m->command) - { - case CMD_RETRIG: - m->command = CMD_MODCMDEX; - m->param = 0x90 | (m->param & 0x0F); - break; case CMD_PORTAMENTOUP: case CMD_PORTAMENTODOWN: case CMD_TONEPORTAVOL: @@ -407,217 +205,9 @@ else cEffectMemory[nChannel][m->command] = m->param; break; - } - else switch(m->volcmd) - { - case VOLCMD_VOLUME: - m->command = CMD_VOLUME; - m->param = m->vol; - break; - case VOLCMD_PANNING: - m->command = CMD_PANNING8; - m->param = CLAMP(m->vol << 2, 0, 0xFF); - break; - case VOLCMD_VOLSLIDEDOWN: - m->command = CMD_VOLUMESLIDE; - m->param = m->vol; - break; - case VOLCMD_VOLSLIDEUP: - m->command = CMD_VOLUMESLIDE; - m->param = m->vol << 4; - break; - case VOLCMD_FINEVOLDOWN: - m->command = CMD_MODCMDEX; - m->param = 0xB0 | m->vol; - break; - case VOLCMD_FINEVOLUP: - m->command = CMD_MODCMDEX; - m->param = 0xA0 | m->vol; - break; - case VOLCMD_PORTADOWN: - m->command = CMD_PORTAMENTODOWN; - m->param = m->vol << 2; - break; - case VOLCMD_PORTAUP: - m->command = CMD_PORTAMENTOUP; - m->param = m->vol << 2; - break; - case VOLCMD_TONEPORTAMENTO: - m->command = CMD_TONEPORTAMENTO; - m->param = m->vol << 2; - break; - case VOLCMD_VIBRATODEPTH: - m->command = CMD_VIBRATO; - m->param = m->vol; - break; - case VOLCMD_VIBRATOSPEED: - m->command = CMD_VIBRATO; - m->param = m->vol << 4; - break; - // OpenMPT-specific commands - case VOLCMD_OFFSET: - m->command = CMD_OFFSET; - m->param = m->vol << 3; - break; - case VOLCMD_VELOCITY: - m->command = CMD_VOLUME; - m->param = m->vol * 7; - break; - default: - break; } - m->volcmd = CMD_NONE; - } // End if (newTypeIsMOD) - - /////////////////////////////////////////////////// - // Convert anything to S3M - adjust volume column - if (newTypeIsS3M) - { - if(!m->command) switch(m->volcmd) - { - case VOLCMD_VOLSLIDEDOWN: - m->command = CMD_VOLUMESLIDE; - m->param = m->vol; - m->volcmd = CMD_NONE; - break; - case VOLCMD_VOLSLIDEUP: - m->command = CMD_VOLUMESLIDE; - m->param = m->vol << 4; - m->volcmd = CMD_NONE; - break; - case VOLCMD_FINEVOLDOWN: - m->command = CMD_VOLUMESLIDE; - m->param = 0xF0 | m->vol; - m->volcmd = CMD_NONE; - break; - case VOLCMD_FINEVOLUP: - m->command = CMD_VOLUMESLIDE; - m->param = (m->vol << 4) | 0x0F; - m->volcmd = CMD_NONE; - break; - case VOLCMD_PORTADOWN: - m->command = CMD_PORTAMENTODOWN; - m->param = m->vol << 2; - m->volcmd = CMD_NONE; - break; - case VOLCMD_PORTAUP: - m->command = CMD_PORTAMENTOUP; - m->param = m->vol << 2; - m->volcmd = CMD_NONE; - break; - case VOLCMD_TONEPORTAMENTO: - m->command = CMD_TONEPORTAMENTO; - m->param = m->vol << 2; - m->volcmd = CMD_NONE; - break; - case VOLCMD_VIBRATODEPTH: - m->command = CMD_VIBRATO; - m->param = m->vol; - m->volcmd = CMD_NONE; - break; - case VOLCMD_VIBRATOSPEED: - m->command = CMD_VIBRATO; - m->param = m->vol << 4; - m->volcmd = CMD_NONE; - break; - case VOLCMD_PANSLIDELEFT: - m->command = CMD_PANNINGSLIDE; - m->param = m->vol << 4; - m->volcmd = CMD_NONE; - break; - case VOLCMD_PANSLIDERIGHT: - m->command = CMD_PANNINGSLIDE; - m->param = m->vol; - m->volcmd = CMD_NONE; - break; - // OpenMPT-specific commands - case VOLCMD_OFFSET: - m->command = CMD_OFFSET; - m->param = m->vol << 3; - m->volcmd = CMD_NONE; - break; - case VOLCMD_VELOCITY: - m->volcmd = CMD_VOLUME; - m->vol *= 7; - break; - default: - break; - } - } // End if (newTypeIsS3M) - - ////////////////////////////////////////////////// - // Convert anything to XM - adjust volume column - if (newTypeIsXM) - { - if(!m->command) switch(m->volcmd) - { - case VOLCMD_PORTADOWN: - m->command = CMD_PORTAMENTODOWN; - m->param = m->vol << 2; - m->volcmd = CMD_NONE; - break; - case VOLCMD_PORTAUP: - m->command = CMD_PORTAMENTOUP; - m->param = m->vol << 2; - m->volcmd = CMD_NONE; - break; - // OpenMPT-specific commands - case VOLCMD_OFFSET: - m->command = CMD_OFFSET; - m->param = m->vol << 3; - m->volcmd = CMD_NONE; - break; - case VOLCMD_VELOCITY: - m->volcmd = CMD_VOLUME; - m->vol *= 7; - break; - default: - break; - } - } // End if (newTypeIsXM) - - /////////////////////////////////////////////////// - // Convert anything to IT - adjust volume column - if (newTypeIsIT_MPT) - { - if(!m->command) switch(m->volcmd) - { - case VOLCMD_VOLSLIDEDOWN: - case VOLCMD_VOLSLIDEUP: - case VOLCMD_FINEVOLDOWN: - case VOLCMD_FINEVOLUP: - case VOLCMD_PORTADOWN: - case VOLCMD_PORTAUP: - case VOLCMD_TONEPORTAMENTO: - case VOLCMD_VIBRATODEPTH: - // OpenMPT-specific commands - case VOLCMD_OFFSET: - case VOLCMD_VELOCITY: - m->vol = min(m->vol, 9); - break; - case VOLCMD_PANSLIDELEFT: - m->command = CMD_PANNINGSLIDE; - m->param = m->vol << 4; - m->volcmd = CMD_NONE; - break; - case VOLCMD_PANSLIDERIGHT: - m->command = CMD_PANNINGSLIDE; - m->param = m->vol; - m->volcmd = CMD_NONE; - break; - case VOLCMD_VIBRATOSPEED: - m->command = CMD_VIBRATO; - m->param = m->vol << 4; - m->volcmd = CMD_NONE; - break; - default: - break; - } - } // End if (newTypeIsIT) - - if(!m_SndFile.GetModSpecifications().HasNote(m->note)) - m->note = NOTE_NONE; + } } } @@ -704,6 +294,7 @@ } if (!newTypeIsIT_MPT) m_SndFile.m_dwSongFlags &= ~(SONG_ITOLDEFFECTS|SONG_ITCOMPATMODE); if (!newTypeIsS3M) m_SndFile.m_dwSongFlags &= ~SONG_FASTVOLSLIDES; + if (!newTypeIsMOD) m_SndFile.m_dwSongFlags &= ~SONG_PT1XMODE; END_CRITICAL(); ChangeFileExtension(nNewType); Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-10-12 22:04:33 UTC (rev 397) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-10-13 20:20:48 UTC (rev 398) @@ -102,6 +102,7 @@ // -> CODE#0023 // -> DESC="IT project files (.itp)" ON_COMMAND(IDC_CHECK6, OnCheck6) + ON_COMMAND(IDC_CHECK_PT1X, OnCheckPT1x) ON_CBN_SELCHANGE(IDC_COMBO1,UpdateDialog) // -! NEW_FEATURE#0023 //}}AFX_MSG_MAP @@ -125,6 +126,7 @@ // -> CODE#0023 // -> DESC="IT project files (.itp)" DDX_Control(pDX, IDC_CHECK6, m_CheckBox6); + DDX_Control(pDX, IDC_CHECK_PT1X, m_CheckBoxPT1x); DDX_Control(pDX, IDC_EDIT_FLAGS, m_EditFlag); // -! NEW_FEATURE#0023 //}}AFX_DATA_MAP @@ -249,6 +251,7 @@ m_CheckBox3.SetCheck((m_pSndFile->m_dwSongFlags & SONG_ITOLDEFFECTS) ? MF_CHECKED : 0); m_CheckBox4.SetCheck((m_pSndFile->m_dwSongFlags & SONG_ITCOMPATMODE) ? MF_CHECKED : 0); m_CheckBox5.SetCheck((m_pSndFile->m_dwSongFlags & SONG_EXFILTERRANGE) ? MF_CHECKED : 0); + m_CheckBoxPT1x.SetCheck((m_pSndFile->m_dwSongFlags & SONG_PT1XMODE) ? MF_CHECKED : 0); // -> CODE#0023 // -> DESC="IT project files (.itp)" @@ -260,6 +263,7 @@ m_CheckBox3.EnableWindow((m_pSndFile->m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) ? TRUE : FALSE); m_CheckBox4.EnableWindow((m_pSndFile->m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) ? TRUE : FALSE); m_CheckBox5.EnableWindow((m_pSndFile->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)) ? TRUE : FALSE); + m_CheckBoxPT1x.EnableWindow((m_pSndFile->m_nType & (MOD_TYPE_MOD)) ? TRUE : FALSE); // -> CODE#0023 // -> DESC="IT project files (.itp)" @@ -394,7 +398,16 @@ m_pSndFile->m_dwSongFlags &= ~SONG_ITPEMBEDIH; } +void CModTypeDlg::OnCheckPT1x() +//----------------------------- +{ + if (m_CheckBoxPT1x.GetCheck()) + m_pSndFile->m_dwSongFlags |= SONG_PT1XMODE; + else + m_pSndFile->m_dwSongFlags &= ~SONG_PT1XMODE; +} + BOOL CModTypeDlg::VerifyData() //--------------------------------- { Modified: trunk/OpenMPT/mptrack/dlg_misc.h =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.h 2009-10-12 22:04:33 UTC (rev 397) +++ trunk/OpenMPT/mptrack/dlg_misc.h 2009-10-13 20:20:48 UTC (rev 398) @@ -11,7 +11,7 @@ { public: CComboBox m_TypeBox, m_ChannelsBox, m_TempoModeBox, m_PlugMixBox; - CButton m_CheckBox1, m_CheckBox2, m_CheckBox3, m_CheckBox4, m_CheckBox5; + CButton m_CheckBox1, m_CheckBox2, m_CheckBox3, m_CheckBox4, m_CheckBox5, m_CheckBoxPT1x; CEdit m_EditFlag; CSoundFile *m_pSndFile; UINT m_nChannels, m_nType; @@ -50,6 +50,7 @@ // -> DESC="IT project files (.itp)" afx_msg void OnCheck6(); // -! NEW_FEATURE#0023 + afx_msg void OnCheckPT1x(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2009-10-12 22:04:33 UTC (rev 397) +++ trunk/OpenMPT/mptrack/mptrack.rc 2009-10-13 20:20:48 UTC (rev 398) @@ -628,6 +628,7 @@ LTEXT "Rows/beat",IDC_TEXT_ROWSPERBEAT,186,224,36,8 EDITTEXT IDC_ROWSPERMEASURE,156,240,24,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Rows/measure",IDC_TEXT_ROWSPERMEASURE,186,242,49,8 + CONTROL "ProTracker 1.x Mode (MOD)",IDC_CHECK_PT1X,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,96,108,10 END IDD_SHOWLOG DIALOG 0, 0, 300, 106 Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2009-10-12 22:04:33 UTC (rev 397) +++ trunk/OpenMPT/mptrack/resource.h 2009-10-13 20:20:48 UTC (rev 398) @@ -908,6 +908,7 @@ #define IDC_CHK_REMOVE_PLUGINS 2405 #define IDC_CHK_OPTIMIZE_SAMPLES 2406 #define IDC_CHK_MERGE_SEQUENCES 2408 +#define IDC_CHECK_PT1X 2409 #define ID_FILE_NEWMOD 32771 #define ID_FILE_NEWXM 32772 #define ID_FILE_NEWS3M 32773 @@ -1152,7 +1153,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 522 #define _APS_NEXT_COMMAND_VALUE 59231 -#define _APS_NEXT_CONTROL_VALUE 2409 +#define _APS_NEXT_CONTROL_VALUE 2410 #define _APS_NEXT_SYMED_VALUE 901 #endif #endif Modified: trunk/OpenMPT/soundlib/Snd_defs.h =================================================================== --- trunk/OpenMPT/soundlib/Snd_defs.h 2009-10-12 22:04:33 UTC (rev 397) +++ trunk/OpenMPT/soundlib/Snd_defs.h 2009-10-13 20:20:48 UTC (rev 398) @@ -177,7 +177,7 @@ #define FLTMODE_UNCHANGED 0xFF #define FLTMODE_LOWPASS 0 #define FLTMODE_HIGHPASS 1 -#define FLTMODE_BANDPASS 2 +#define FLTMODE_BANDPASS 2 // unused #define RSF_16BIT 0x04 @@ -255,30 +255,31 @@ #define SYSMIX_SSE 0x20 // Module flags -#define SONG_EMBEDMIDICFG 0x0001 -#define SONG_FASTVOLSLIDES 0x0002 // Old Scream Tracker 3.0 volume slides -#define SONG_ITOLDEFFECTS 0x0004 // Old Impulse Tracker effect implementations -#define SONG_ITCOMPATMODE 0x0008 // IT "Compatible Gxx" -#define SONG_LINEARSLIDES 0x0010 // Linear slides vs. Amiga slides -#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 +#define SONG_EMBEDMIDICFG 0x0001 // Embed macros in file +#define SONG_FASTVOLSLIDES 0x0002 // Old Scream Tracker 3.0 volume slides +#define SONG_ITOLDEFFECTS 0x0004 // Old Impulse Tracker effect implementations +#define SONG_ITCOMPATMODE 0x0008 // IT "Compatible Gxx" +#define SONG_LINEARSLIDES 0x0010 // Linear slides vs. Amiga slides +#define SONG_PATTERNLOOP 0x0020 // Loop current pattern (pattern editor) +#define SONG_STEP 0x0040 // Song is in "step" mode (pattern editor) +#define SONG_PAUSED 0x0080 // Song is paused +#define SONG_FADINGSONG 0x0100 // Song is fading out +#define SONG_ENDREACHED 0x0200 // Song is finished +#define SONG_GLOBALFADE 0x0400 // Song is fading out +#define SONG_CPUVERYHIGH 0x0800 // High CPU usage +#define SONG_FIRSTTICK 0x1000 // Is set when the current tick is the first tick of the row +#define SONG_MPTFILTERMODE 0x2000 // Local filter mode (reset filter on each note) +#define SONG_SURROUNDPAN 0x4000 // Pan in the rear channels +#define SONG_EXFILTERRANGE 0x8000 // Cutoff Filter has double frequency range (up to ~10Khz) +#define SONG_AMIGALIMITS 0x10000 // Enforce amiga frequency limits // -> CODE#0023 // -> DESC="IT project files (.itp)" -#define SONG_ITPROJECT 0x20000 -#define SONG_ITPEMBEDIH 0x40000 +#define SONG_ITPROJECT 0x20000 // Is a project file +#define SONG_ITPEMBEDIH 0x40000 // Embed instrument headers in project file // -! NEW_FEATURE#0023 -#define SONG_BREAKTOROW 0x80000 -#define SONG_POSJUMP 0x100000 +#define SONG_BREAKTOROW 0x80000 // Break to row command encountered (internal flag, do not touch) +#define SONG_POSJUMP 0x100000 // Position jump encountered (internal flag, do not touch) +#define SONG_PT1XMODE 0x200000 // ProTracker 1.x playback mode // Global Options (Renderer) #define SNDMIX_REVERSESTEREO 0x0001 @@ -307,7 +308,7 @@ #define SNDMIX_DIRECTTODISK 0x10000 #define SNDMIX_ENABLEMMX 0x20000 #define SNDMIX_NOBACKWARDJUMPS 0x40000 -#define SNDMIX_MAXDEFAULTPAN 0x80000 // Used by the MOD loader +#define SNDMIX_MAXDEFAULTPAN 0x80000 // Used by the MOD loader (currently unused) #define SNDMIX_MUTECHNMODE 0x100000 // Notes are not played on muted channels #define SNDMIX_EMULATE_MIX_BUGS 0x200000 // rewbs.emulateMixBugs Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-10-12 22:04:33 UTC (rev 397) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-10-13 20:20:48 UTC (rev 398) @@ -1249,7 +1249,7 @@ if ((!note) && (instr)) //Case: instrument with no note data. { //IT compatibility: Instrument with no note. - if(IsCompatibleMode(TRK_IMPULSETRACKER)) + if(IsCompatibleMode(TRK_IMPULSETRACKER) || (m_dwSongFlags & SONG_PT1XMODE)) { if(m_nInstruments) { @@ -2526,9 +2526,15 @@ // EEx: Pattern Delay case 0xF0: if((m_nType & MOD_TYPE_MOD) != 0) // MOD: Invert Loop + { pChn->nEFxSpeed = param; + pChn->pEFxSample = pChn->pModSample; + if(m_dwSongFlags & SONG_FIRSTTICK) InvertLoop(pChn); + } else // XM: Set Active Midi Macro + { pChn->nActiveMacro = param; + } break; } } @@ -2633,7 +2639,7 @@ //------------------------------------------------------------------ { // S9x and X9x commands (S3M/XM/IT only) - if (m_nTickCount) return; + if(!(m_dwSongFlags & SONG_FIRSTTICK)) return; switch(param & 0x0F) { // S90: Surround Off @@ -2689,18 +2695,23 @@ //-------------------------------------------------- { // EFx implementation for MOD files (PT 1.1A and up: Invert Loop) - // This effect trashes samples. + // This effect trashes samples. Thanks to bubsy for making this work. :) if((m_nType & MOD_TYPE_MOD) == 0 || pChn->nEFxSpeed == 0) return; - pChn->nEFxDelay += ModEFxTable[pChn->nEFxSpeed]; - if(pChn->nEFxDelay < 0x80) return; + pChn->nEFxDelay += ModEFxTable[pChn->nEFxSpeed & 0x0F]; + + if(pChn->nEFxDelay < 0x80) return; // only applied if the "delay" reaches 128 pChn->nEFxDelay = 0; - if (++pChn->nEFxOffset >= pChn->nLoopEnd - pChn->nLoopStart) + + // we obviously also need a sample for this + MODSAMPLE *pModSample = pChn->pEFxSample; + if(pModSample == nullptr || pModSample->pSample == nullptr || !(pModSample->uFlags & CHN_LOOP)) return; + + if (++pChn->nEFxOffset >= pModSample->nLoopEnd - pModSample->nLoopStart) pChn->nEFxOffset = 0; // TRASH IT!!! (Yes, the sample!) - if(pChn->pSample != nullptr && (pChn->dwFlags & CHN_LOOP)) - pChn->pSample[pChn->nLoopStart + pChn->nEFxOffset] = ~pChn->pSample[pChn->nLoopStart + pChn->nEFxOffset]; + pModSample->pSample[pModSample->nLoopStart + pChn->nEFxOffset] = ~pModSample->pSample[pModSample->nLoopStart + pChn->nEFxOffset]; } Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-12 22:04:33 UTC (rev 397) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-13 20:20:48 UTC (rev 398) @@ -3258,4 +3258,460 @@ case 0xB0: m->param = (m->param & 0x0F) | 0x60; break; // rest are the same } +} + +// Convert a mod command from one format to another. +void CSoundFile::ConvertCommand(MODCOMMAND *m, MODTYPE nOldType, MODTYPE nNewType) +//-------------------------------------------------------------------------------- +{ + // helper variables + const bool oldTypeIsMOD = (nOldType == MOD_TYPE_MOD), oldTypeIsXM = (nOldType == MOD_TYPE_XM), + oldTypeIsS3M = (nOldType == MOD_TYPE_S3M), oldTypeIsIT = (nOldType == MOD_TYPE_IT), + oldTypeIsMPT = (nOldType == MOD_TYPE_MPT), oldTypeIsMOD_XM = (oldTypeIsMOD || oldTypeIsXM), + oldTypeIsS3M_IT_MPT = (oldTypeIsS3M || oldTypeIsIT || oldTypeIsMPT), + oldTypeIsIT_MPT = (oldTypeIsIT || oldTypeIsMPT); + + const bool newTypeIsMOD = (nNewType == MOD_TYPE_MOD), newTypeIsXM = (nNewType == MOD_TYPE_XM), + newTypeIsS3M = (nNewType == MOD_TYPE_S3M), newTypeIsIT = (nNewType == MOD_TYPE_IT), + newTypeIsMPT = (nNewType == MOD_TYPE_MPT), newTypeIsMOD_XM = (newTypeIsMOD || newTypeIsXM), + newTypeIsS3M_IT_MPT = (newTypeIsS3M || newTypeIsIT || newTypeIsMPT), + newTypeIsIT_MPT = (newTypeIsIT || newTypeIsMPT); + + ////////////////////////// + // Convert 8-bit Panning + if(m->command == CMD_PANNING8) + { + if(newTypeIsS3M) + { + m->param = (m->param + 1) >> 1; + } + else if(oldTypeIsS3M) + { + if(m->param == 0xA4) + { + // surround remap + m->command = (nNewType & (MOD_TYPE_IT|MOD_TYPE_MPT)) ? CMD_S3MCMDEX : CMD_XFINEPORTAUPDOWN; + m->param = 0x91; + } + else + { + m->param = min(m->param << 1, 0xFF); + } + } + } // End if(m->command == CMD_PANNING8) + + ////////////////////////// + // Convert param control + if(oldTypeIsMPT) + { + if(m->note == NOTE_PC || m->note == NOTE_PCS) + { + m->param = (BYTE)(min(MODCOMMAND::maxColumnValue, m->GetValueEffectCol()) * 0x7F / MODCOMMAND::maxColumnValue); + m->command = (m->note == NOTE_PC) ? CMD_MIDI : CMD_SMOOTHMIDI; // might be removed later + m->volcmd = VOLCMD_NONE; + m->note = NOTE_NONE; + } + } // End if(oldTypeIsMPT) + + ///////////////////////////////////////// + // Convert MOD / XM to S3M / IT / MPTM + if(oldTypeIsMOD_XM && newTypeIsS3M_IT_MPT) + { + switch(m->command) + { + case CMD_MODCMDEX: + MODExx2S3MSxx(m); + break; + case CMD_VOLUME: + if (!m->volcmd) + { + m->volcmd = VOLCMD_VOLUME; + m->vol = m->param; + if (m->vol > 0x40) m->vol = 0x40; + m->command = m->param = 0; + } + break; + case CMD_PORTAMENTOUP: + if (m->param > 0xDF) m->param = 0xDF; + break; + case CMD_PORTAMENTODOWN: + if (m->param > 0xDF) m->param = 0xDF; + break; + case CMD_XFINEPORTAUPDOWN: + switch(m->param & 0xF0) + { + case 0x10: m->command = CMD_PORTAMENTOUP; m->param = (m->param & 0x0F) | 0xE0; break; + case 0x20: m->command = CMD_PORTAMENTODOWN; m->param = (m->param & 0x0F) | 0xE0; break; + case 0x50: + case 0x60: + case 0x70: + case 0x90: + case 0xA0: + m->command = CMD_S3MCMDEX; + // surround remap (this is the "official" command) + if(nNewType & MOD_TYPE_S3M && m->param == 0x91) + { + m->command = CMD_PANNING8; + m->param = 0xA4; + } + break; + } + break; + case CMD_KEYOFF: + if(m->note == 0) + { + m->note = (newTypeIsS3M) ? NOTE_NOTECUT : NOTE_KEYOFF; + m->command = CMD_S3MCMDEX; + if(m->param == 0) + m->instr = 0; + m->param = 0xD0 | (m->param & 0x0F); + } + break; + case CMD_PANNINGSLIDE: + // swap L/R + m->param = ((m->param & 0x0F) << 4) | (m->param >> 4); + default: + break; + } + } // End if(oldTypeIsMOD_XM && newTypeIsS3M_IT_MPT) + + + ///////////////////////////////////////// + // Convert S3M / IT / MPTM to MOD / XM + else if(oldTypeIsS3M_IT_MPT && newTypeIsMOD_XM) + { + if(m->note == NOTE_NOTECUT || m->note == NOTE_FADE) + m->note = NOTE_KEYOFF; + + switch(m->command) + { + case CMD_S3MCMDEX: + S3MSxx2MODExx(m); + break; + case CMD_VOLUMESLIDE: + if ((m->param & 0xF0) && ((m->param & 0x0F) == 0x0F)) + { + m->command = CMD_MODCMDEX; + m->param = (m->param >> 4) | 0xA0; + } else + if ((m->param & 0x0F) && ((m->param & 0xF0) == 0xF0)) + { + m->command = CMD_MODCMDEX; + m->param = (m->param & 0x0F) | 0xB0; + } + break; + case CMD_PORTAMENTOUP: + if (m->param >= 0xF0) + { + m->command = CMD_MODCMDEX; + m->param = (m->param & 0x0F) | 0x10; + } else + if (m->param >= 0xE0) + { + m->command = CMD_MODCMDEX; + m->param = (((m->param & 0x0F)+3) >> 2) | 0x10; + } else m->command = CMD_PORTAMENTOUP; + break; + case CMD_PORTAMENTODOWN: + if (m->param >= 0xF0) + { + m->command = CMD_MODCMDEX; + m->param = (m->param & 0x0F) | 0x20; + } else + if (m->param >= 0xE0) + { + m->command = CMD_MODCMDEX; + m->param = (((m->param & 0x0F)+3) >> 2) | 0x20; + } else m->command = CMD_PORTAMENTODOWN; + break; + case CMD_SPEED: + { + m->param = min(m->param, (nNewType == MOD_TYPE_XM) ? 0x1F : 0x20); + } + break; + case CMD_TEMPO: + if(m->param < 0x20) m->command = CMD_NONE; // no tempo slides + break; + case CMD_PANNINGSLIDE: + // swap L/R + m->param = ((m->param & 0x0F) << 4) | (m->param >> 4); + // remove fine slides + if((m->param > 0xF0) || ((m->param & 0x0F) == 0x0F && m->param != 0x0F)) + m->command = CMD_NONE; + default: + break; + } + } // End if(oldTypeIsS3M_IT_MPT && newTypeIsMOD_XM) + + + /////////////////////// + // Convert IT to S3M + else if (oldTypeIsIT_MPT && newTypeIsS3M) + { + if(m->note == NOTE_KEYOFF || m->note == NOTE_FADE) + m->note = NOTE_NOTECUT; + + switch(m->command) + { + case CMD_S3MCMDEX: + if(m->param == 0x91) + { + // surround remap (this is the "official" command) + m->command = CMD_PANNING8; + m->param = 0xA4; + } + break; + case CMD_SMOOTHMIDI: + m->command = CMD_MIDI; + break; + default: + break; + } + } // End if (oldTypeIsIT_MPT && newTypeIsS3M) + + + + /////////////////////////////////////////////////////////////////////// + // Convert MOD to anything - adjust effect memory, remove Invert Loop + if (oldTypeIsMOD) + { + 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; + + case CMD_MODCMDEX: // This would turn into "Set Active Macro", so let's better remove it + if((m->param & 0xF0) == 0xF0) m->command = CMD_NONE; + break; + } + } // End if (oldTypeIsMOD && newTypeIsXM) + + ///////////////////////////////////////////////////////////////////// + // Convert anything to MOD - remove volume column, remove Set Macro + if (newTypeIsMOD) + { + if(m->command) switch(m->command) + { + case CMD_RETRIG: // MOD only has E9x + m->command = CMD_MODCMDEX; + m->param = 0x90 | (m->param & 0x0F); + break; + case CMD_MODCMDEX: // This would turn into "Invert Loop", so let's better remove it + if((m->param & 0xF0) == 0xF0) m->command = CMD_NONE; + break; + } + + else switch(m->volcmd) + { + case VOLCMD_VOLUME: + m->command = CMD_VOLUME; + m->param = m->vol; + break; + case VOLCMD_PANNING: + m->command = CMD_PANNING8; + m->param = CLAMP(m->vol << 2, 0, 0xFF); + break; + case VOLCMD_VOLSLIDEDOWN: + m->command = CMD_VOLUMESLIDE; + m->param = m->vol; + break; + case VOLCMD_VOLSLIDEUP: + m->command = CMD_VOLUMESLIDE; + m->param = m->vol << 4; + break; + case VOLCMD_FINEVOLDOWN: + m->command = CMD_MODCMDEX; + m->param = 0xB0 | m->vol; + break; + case VOLCMD_FINEVOLUP: + m->command = CMD_MODCMDEX; + m->param = 0xA0 | m->vol; + break; + case VOLCMD_PORTADOWN: + m->command = CMD_PORTAMENTODOWN; + m->param = m->vol << 2; + break; + case VOLCMD_PORTAUP: + m->command = CMD_PORTAMENTOUP; + m->param = m->vol << 2; + break; + case VOLCMD_TONEPORTAMENTO: + m->command = CMD_TONEPORTAMENTO; + m->param = m->vol << 2; + break; + case VOLCMD_VIBRATODEPTH: + m->command = CMD_VIBRATO; + m->param = m->vol; + break; + case VOLCMD_VIBRATOSPEED: + m->command = CMD_VIBRATO; + m->param = m->vol << 4; + break; + // OpenMPT-specific commands + case VOLCMD_OFFSET: + m->command = CMD_OFFSET; + m->param = m->vol << 3; + break; + case VOLCMD_VELOCITY: + m->command = CMD_VOLUME; + m->param = m->vol * 7; + break; + default: + break; + } + m->volcmd = CMD_NONE; + } // End if (newTypeIsMOD) + + /////////////////////////////////////////////////// + // Convert anything to S3M - adjust volume column + if (newTypeIsS3M) + { + if(!m->command) switch(m->volcmd) + { + case VOLCMD_VOLSLIDEDOWN: + m->command = CMD_VOLUMESLIDE; + m->param = m->vol; + m->volcmd = CMD_NONE; + break; + case VOLCMD_VOLSLIDEUP: + m->command = CMD_VOLUMESLIDE; + m->param = m->vol << 4; + m->volcmd = CMD_NONE; + break; + case VOLCMD_FINEVOLDOWN: + m->command = CMD_VOLUMESLIDE; + m->param = 0xF0 | m->vol; + m->volcmd = CMD_NONE; + break; + case VOLCMD_FINEVOLUP: + m->command = CMD_VOLUMESLIDE; + m->param = (m->vol << 4) | 0x0F; + m->volcmd = CMD_NONE; + break; + case VOLCMD_PORTADOWN: + m->command = CMD_PORTAMENTODOWN; + m->param = m->vol << 2; + m->volcmd = CMD_NONE; + break; + case VOLCMD_PORTAUP: + m->command = CMD_PORTAMENTOUP; + m->param = m->vol << 2; + m->volcmd = CMD_NONE; + break; + case VOLCMD_TONEPORTAMENTO: + m->command = CMD_TONEPORTAMENTO; + m->param = m->vol << 2; + m->volcmd = CMD_NONE; + break; + case VOLCMD_VIBRATODEPTH: + m->command = CMD_VIBRATO; + m->param = m->vol; + m->volcmd = CMD_NONE; + break; + case VOLCMD_VIBRATOSPEED: + m->command = CMD_VIBRATO; + m->param = m->vol << 4; + m->volcmd = CMD_NONE; + break; + case VOLCMD_PANSLIDELEFT: + m->command = CMD_PANNINGSLIDE; + m->param = m->vol << 4; + m->volcmd = CMD_NONE; + break; + case VOLCMD_PANSLIDERIGHT: + m->command = CMD_PANNINGSLIDE; + m->param = m->vol; + m->volcmd = CMD_NONE; + break; + // OpenMPT-specific commands + case VOLCMD_OFFSET: + m->command = CMD_OFFSET; + m->param = m->vol << 3; + m->volcmd = CMD_NONE; + break; + case VOLCMD_VELOCITY: + m->volcmd = CMD_VOLUME; + m->vol *= 7; + break; + default: + break; + } + } // End if (newTypeIsS3M) + + ////////////////////////////////////////////////// + // Convert anything to XM - adjust volume column + if (newTypeIsXM) + { + if(!m->command) switch(m->volcmd) + { + case VOLCMD_PORTADOWN: + m->command = CMD_PORTAMENTODOWN; + m->param = m->vol << 2; + m->volcmd = CMD_NONE; + break; + case VOLCMD_PORTAUP: + m->command = CMD_PORTAMENTOUP; + m->param = m->vol << 2; + m->volcmd = CMD_NONE; + break; + // OpenMPT-specific commands + case VOLCMD_OFFSET: + m->command = CMD_OFFSET; + m->param = m->vol << 3; + m->volcmd = CMD_NONE; + break; + case VOLCMD_VELOCITY: + m->volcmd = CMD_VOLUME; + m->vol *= 7; + break; + default: + break; + } + } // End if (newTypeIsXM) + + /////////////////////////////////////////////////// + // Convert anything to IT - adjust volume column + if (newTypeIsIT_MPT) + { + if(!m->command) switch(m->volcmd) + { + case VOLCMD_VOLSLIDEDOWN: + case VOLCMD_VOLSLIDEUP: + case VOLCMD_FINEVOLDOWN: + case VOLCMD_FINEVOLUP: + case VOLCMD_PORTADOWN: + case VOLCMD_PORTAUP: + case VOLCMD_TONEPORTAMENTO: + case VOLCMD_VIBRATODEPTH: + // OpenMPT-specific commands + case VOLCMD_OFFSET: + case VOLCMD_VELOCITY: + m->vol = min(m->vol, 9); + break; + case VOLCMD_PANSLIDELEFT: + m->command = CMD_PANNINGSLIDE; + m->param = m->vol << 4; + m->volcmd = CMD_NONE; + break; + case VOLCMD_PANSLIDERIGHT: + m->command = CMD_PANNINGSLIDE; + m->param = m->vol; + m->volcmd = CMD_NONE; + break; + case VOLCMD_VIBRATOSPEED: + m->command = CMD_VIBRATO; + m->param = m->vol << 4; + m->volcmd = CMD_NONE; + break; + default: + break; + } + } // End if (newTypeIsIT) + + if(!CSoundFile::GetModSpecifications(nNewType).HasNote(m->note)) + m->note = NOTE_NONE; } \ No newline at end of file Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-10-12 22:04:33 UTC (rev 397) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-10-13 20:20:48 UTC (rev 398) @@ -201,6 +201,7 @@ 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 Invert Loop (EFx, .MOD only) + MODSAMPLE *pEFxSample; // sample memory for Invert Loop (EFx, .MOD only) // 8-bit members BYTE nRestoreResonanceOnNewNote; //Like above BYTE nRestoreCutoffOnNewNote; //Like above @@ -741,8 +742,9 @@ void S3MSaveConvert(UINT *pcmd, UINT *pprm, BOOL bIT, BOOL bCompatibilityExport = false) const; WORD ModSaveCommand(const MODCOMMAND *m, const bool bXM, const bool bCompatibilityExport = false) const; - static void MODExx2S3MSxx(MODCOMMAND *m); - static void S3MSxx2MODExx(MODCOMMAND *m); + static void ConvertCommand(MODCOMMAND *m, MODTYPE nOldType, MODTYPE nNewType); // Convert a complete MODCHANNEL item from one format to another + static void MODExx2S3MSxx(MODCOMMAND *m); // Convert Exx to Sxx + static void S3MSxx2MODExx(MODCOMMAND *m); // Convert Sxx to Exx public: // Real-time sound functions This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |