From: <re...@us...> - 2006-04-11 23:46:56
|
Revision: 156 Author: rewbs Date: 2006-04-11 16:44:36 -0700 (Tue, 11 Apr 2006) ViewCVS: http://svn.sourceforge.net/modplug/?rev=156&view=rev Log Message: ----------- . v1.17.02.42 + <rewbs> "Compatibility export" in file menu: save as 'plain' IT, without all of OpenMPT's crap. IT only for now (not XM). . <rewbs> Set instrument in pattern editor should work when no note is specified (tx Torvus - http://lpchip.com/modplug/viewtopic.php?t=470) . <rewbs> Restart position saved in IT (tx LPChip - http://lpchip.com/modplug/viewtopic.php?t=473) . <rewbs> Loop song now works even if restart pos falls on +++ (tx LPChip - http://lpchip.com/modplug/viewtopic.php?t=463) . <rewbs> Last used tempo is applied even when playback is triggered from instrument panel. (tx LPChip - http://lpchip.com/modplug/viewtopic.php?t=480) / <rewbs> User now gets a warning when loading MDA Degrade (tx fisk0 - http://lpchip.com/modplug/viewtopic.php?t=467) Modified Paths: -------------- trunk/OpenMPT/mptrack/CommandSet.cpp trunk/OpenMPT/mptrack/CommandSet.h trunk/OpenMPT/mptrack/InputHandler.cpp trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/bin/mptrack_Generic.exe trunk/OpenMPT/mptrack/bin/mptrack_P3.exe trunk/OpenMPT/mptrack/bin/mptrack_P4-Athlon64.exe trunk/OpenMPT/mptrack/bin/mptrack_athlon32.exe trunk/OpenMPT/mptrack/bin/version trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/packageTemplate/History.txt trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp Removed Paths: ------------- trunk/OpenMPT/mptrack/bin/testSvnCommitList trunk/OpenMPT/mptrack/bin/testSvnCommitList2 Modified: trunk/OpenMPT/mptrack/CommandSet.cpp =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.cpp 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/mptrack/CommandSet.cpp 2006-04-11 23:44:36 UTC (rev 156) @@ -2253,13 +2253,11 @@ commands[kcChangeLoopStatus].isDummy = false; commands[kcChangeLoopStatus].Message = "Toggle loop pattern"; + commands[kcFileExportCompat].UID = 1777; + commands[kcFileExportCompat].Message = "File/Export to standard IT/XM"; + commands[kcFileExportCompat].isHidden = false; + commands[kcFileExportCompat].isDummy = false; -/* commands[kcToggleLoopSong].UID = 1777; - commands[kcToggleLoopSong].isHidden = false; - commands[kcToggleLoopSong].isDummy = false; - commands[kcToggleLoopSong].Message = "Toggle loop song"; -*/ - #ifdef _DEBUG for (int i=0; i<kcNumCommands; i++) { if (commands[i].UID != 0) { // ignore unset UIDs Modified: trunk/OpenMPT/mptrack/CommandSet.h =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.h 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/mptrack/CommandSet.h 2006-04-11 23:44:36 UTC (rev 156) @@ -57,6 +57,7 @@ kcFileSaveAsWave, kcFileSaveAsMP3, kcFileSaveMidi, + kcFileExportCompat, kcPrevDocument, kcNextDocument, kcFileImportMidiLib, Modified: trunk/OpenMPT/mptrack/InputHandler.cpp =================================================================== --- trunk/OpenMPT/mptrack/InputHandler.cpp 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/mptrack/InputHandler.cpp 2006-04-11 23:44:36 UTC (rev 156) @@ -330,6 +330,7 @@ case ID_FILE_SAVEASWAVE: s="Save as Wave...\t"; c=kcFileSaveAsWave; break; case ID_FILE_SAVEASMP3: s="Save as MP3...\t"; c=kcFileSaveAsMP3; break; case ID_FILE_SAVEMIDI: s="Export as Midi...\t"; c=kcFileSaveMidi; break; + case ID_FILE_SAVECOMPAT: s="Compatibility Export...\t"; c=kcFileExportCompat; break; case ID_IMPORT_MIDILIB: s="Import Midi Library...\t"; c=kcFileImportMidiLib; break; case ID_ADD_SOUNDBANK: s="Add Sound Bank...\t"; c=kcFileAddSoundBank; break; @@ -390,6 +391,7 @@ pMenu->ModifyMenu(ID_FILE_SAVEASWAVE, MF_BYCOMMAND | MF_STRING, ID_FILE_SAVEASWAVE, GetMenuText(ID_FILE_SAVEASWAVE)); pMenu->ModifyMenu(ID_FILE_SAVEASMP3, MF_BYCOMMAND | MF_STRING, ID_FILE_SAVEASMP3, GetMenuText(ID_FILE_SAVEASMP3)); pMenu->ModifyMenu(ID_FILE_SAVEMIDI, MF_BYCOMMAND | MF_STRING, ID_FILE_SAVEMIDI, GetMenuText(ID_FILE_SAVEMIDI)); + pMenu->ModifyMenu(ID_FILE_SAVECOMPAT, MF_BYCOMMAND | MF_STRING, ID_FILE_SAVECOMPAT, GetMenuText(ID_FILE_SAVECOMPAT)); pMenu->ModifyMenu(ID_IMPORT_MIDILIB, MF_BYCOMMAND | MF_STRING, ID_IMPORT_MIDILIB, GetMenuText(ID_IMPORT_MIDILIB)); pMenu->ModifyMenu(ID_ADD_SOUNDBANK, MF_BYCOMMAND | MF_STRING, ID_ADD_SOUNDBANK, GetMenuText(ID_ADD_SOUNDBANK)); Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2006-04-11 23:44:36 UTC (rev 156) @@ -2707,6 +2707,7 @@ case kcFileSaveAs: case kcFileSaveAsWave: case kcFileSaveMidi: + case kcFileExportCompat: case kcFileClose: case kcFileSave: case kcViewGeneral: Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2006-04-11 23:44:36 UTC (rev 156) @@ -30,6 +30,7 @@ ON_COMMAND(ID_FILE_SAVEASWAVE, OnFileWaveConvert) ON_COMMAND(ID_FILE_SAVEASMP3, OnFileMP3Convert) ON_COMMAND(ID_FILE_SAVEMIDI, OnFileMidiConvert) + ON_COMMAND(ID_FILE_SAVECOMPAT, OnFileCompatibilitySave) ON_COMMAND(ID_PLAYER_PLAY, OnPlayerPlay) ON_COMMAND(ID_PLAYER_PAUSE, OnPlayerPause) ON_COMMAND(ID_PLAYER_STOP, OnPlayerStop) @@ -386,11 +387,7 @@ case MOD_TYPE_MOD: bOk = m_SndFile.SaveMod(lpszPathName, dwPacking); break; case MOD_TYPE_S3M: bOk = m_SndFile.SaveS3M(lpszPathName, dwPacking); break; case MOD_TYPE_XM: bOk = m_SndFile.SaveXM(lpszPathName, dwPacking); break; -// -> CODE#0023 -// -> DESC="IT project files (.itp)" -// case MOD_TYPE_IT: bOk = m_SndFile.SaveIT(lpszPathName, dwPacking); break; case MOD_TYPE_IT: bOk = (m_SndFile.m_dwSongFlags & SONG_ITPROJECT || !lstrcmpi(fext, ".itp")) ? m_SndFile.SaveITProject(lpszPathName) : m_SndFile.SaveIT(lpszPathName, dwPacking); break; -// -! NEW_FEATURE#0023 } EndWaitCursor(); if (bOk) @@ -398,12 +395,8 @@ if (nType == m_SndFile.m_nType) SetPathName(lpszPathName); } else { -// -> CODE#0023 -// -> DESC="IT project files (.itp)" -// ErrorBox(IDS_ERR_SAVESONG, CMainFrame::GetMainFrame()); if(nType == MOD_TYPE_IT && m_SndFile.m_dwSongFlags & SONG_ITPROJECT) ::MessageBox(NULL,"ITP projects need to have a path set for each instrument...",NULL,MB_ICONERROR | MB_OK); else ErrorBox(IDS_ERR_SAVESONG, CMainFrame::GetMainFrame()); -// -! NEW_FEATURE#0023 } return bOk; } @@ -1499,7 +1492,7 @@ void CModDoc::OnFileMidiConvert() -//------------------------------- +//------------------------------------- { CHAR path[_MAX_PATH]="", drive[_MAX_DRIVE]=""; CHAR s[_MAX_PATH], fname[_MAX_FNAME]=""; @@ -1527,7 +1520,60 @@ } } +//HACK: This is a quick fix. Needs to be better integrated into player and GUI. +void CModDoc::OnFileCompatibilitySave() +//------------------------------- +{ + CHAR path[_MAX_PATH]="", drive[_MAX_DRIVE]=""; + CHAR s[_MAX_PATH], fname[_MAX_FNAME]=""; + CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); + CString ext, pattern; + + UINT type = m_SndFile.GetType(); + if ((!pMainFrm) || (!m_SndFile.GetType())) return; + switch (type) { + /*case MOD_TYPE_XM: + ext = "xm"; + pattern = "Fast Tracker Files (*.xm)|*.xm||"; + break;*/ + case MOD_TYPE_IT: + ext = "it"; + pattern = "Impulse Tracker Files (*.it)|*.it||"; + break; + default: + ::MessageBox(NULL,"Compatibility export is currently only available the IT format.", "Can't do compatibility export.",MB_ICONINFORMATION | MB_OK); + return; + } + + ::MessageBox(NULL,"Warning: the exported file will not contain any of MPT's file-format hacks.", "Compatibility export warning.",MB_ICONINFORMATION | MB_OK); + _splitpath(GetPathName(), drive, path, fname, NULL); + strcpy(s, drive); + strcat(s, path); + strcat(s, fname); + if (!strstr(fname, "compat")) { + strcat(s, ".compat."); + } else { + strcat(s, "."); + } + strcat(s, ext); + CFileDialog dlg(FALSE, ext, s, + OFN_HIDEREADONLY | OFN_ENABLESIZING | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_NOREADONLYRETURN, + pattern, pMainFrm); + if (dlg.DoModal() != IDOK){ + return; + } + switch (type) { + case MOD_TYPE_XM: + m_SndFile.SaveCompatXM(dlg.GetPathName()); + break; + case MOD_TYPE_IT: + m_SndFile.SaveCompatIT(dlg.GetPathName()); + break; + } +} + + void CModDoc::OnPlayerPlay() //-------------------------- { @@ -2871,6 +2917,7 @@ case kcFileSaveAsWave: OnFileWaveConvert(); break; case kcFileSaveAsMP3: OnFileMP3Convert(); break; case kcFileSaveMidi: OnFileMidiConvert(); break; + case kcFileExportCompat: OnFileCompatibilitySave(); break; case kcEstimateSongLength: OnEstimateSongLength(); break; case kcApproxRealBPM: OnApproximateBPM(); break; case kcFileSave: DoSave(m_strPathName, 0); break; Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/mptrack/Moddoc.h 2006-04-11 23:44:36 UTC (rev 156) @@ -258,6 +258,7 @@ afx_msg void OnFileWaveConvert(); afx_msg void OnFileMP3Convert(); afx_msg void OnFileMidiConvert(); + afx_msg void OnFileCompatibilitySave(); afx_msg void OnPlayerPlay(); afx_msg void OnPlayerStop(); afx_msg void OnPlayerPause(); Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2006-04-11 23:44:36 UTC (rev 156) @@ -2315,7 +2315,7 @@ { CModDoc *pModDoc; CSoundFile *pSndFile; - UINT nIns = GetCurrentInstrument(); + BYTE nIns = static_cast<BYTE>(GetCurrentInstrument()); MODCOMMAND *p; BOOL bModified; @@ -2334,14 +2334,15 @@ UINT startChan = GetSelectionStartChan(); UINT endChan = GetSelectionEndChan(); - for (UINT r=startRow; r<endRow+1; r++) - { - for (UINT c=startChan; c<endChan+1; c++) - { + for (UINT r=startRow; r<endRow+1; r++) { + for (UINT c=startChan; c<endChan+1; c++) { + p = pSndFile->Patterns[m_nPattern] + r * pSndFile->m_nChannels + c; - if (p->note && p->instr != (BYTE)nIns) - { - p->instr = (BYTE)nIns; + + // If a note or an instr is present on the row, do the change, if required. + // Do not set instr if note and instr are both blank. + if ( (p->note||p->instr) && (p->instr!=nIns) ) { + p->instr = nIns; bModified = TRUE; } } Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2006-04-11 23:44:36 UTC (rev 156) @@ -1040,7 +1040,8 @@ #define NUM_PROBLEMPLUGS 3 static _PROBLEMATIC_PLUG gProblemPlugs[NUM_PROBLEMPLUGS] = { - {'VstP', 'Ni4S', 1, "Native Instruments B4", "*v1.1.1 hangs on playback. Do not proceed unless you have v1.1.5.*"}, + {'VstP', 'Ni4S', 1, "Native Instruments B4", "* v1.1.1 hangs on playback. Do not proceed unless you have v1.1.5. *"}, + {'VstP', 'mdaC', 1, "MDA Degrade", "* This plugin can cause OpenMPT to behave erratically.\r\nYou should try SoundHack's Decimate, ConcreteFX's Lowbit or Subtek's LoFi Plus instead. *"}, }; bool CSelectPluginDlg::VerifyPlug(PVSTPLUGINLIB plug) @@ -1048,10 +1049,10 @@ CString s; for (int p=0; p<NUM_PROBLEMPLUGS; p++) { - if ( (gProblemPlugs[p].id2 == plug->dwPluginId2) && gProblemPlugs[p].id2 + if ( (gProblemPlugs[p].id2 == plug->dwPluginId2) /*&& (gProblemPlugs[p].id1 == plug->dwPluginId1)*/) { - s.Format("WARNING: This plugin has been identified as %s,\r\n which is known to have the following problem with MPT:\r\n\r\n%s\r\n\r\n(see here for more information: http://www.modplug.com/forum/viewtopic.php?p=36930#36930)\r\n\r\nDo you want to continue to load?", gProblemPlugs[p].name, gProblemPlugs[p].problem); + s.Format("WARNING: This plugin has been identified as %s,\r\nwhich is known to have the following problem with OpenMPT:\r\n\r\n%s\r\n\r\nWould you like to continue to load this plugin?", gProblemPlugs[p].name, gProblemPlugs[p].problem); return (AfxMessageBox(s, MB_YESNO) == IDYES); } } @@ -2564,6 +2565,7 @@ pCh->uNoteOnMap[i][trackChannel]=0; MidiSend(dwMidiCode|(i<<8)); } + } // All "active" notes off on this midi and tracker channel Modified: trunk/OpenMPT/mptrack/bin/mptrack_Generic.exe =================================================================== (Binary files differ) Modified: trunk/OpenMPT/mptrack/bin/mptrack_P3.exe =================================================================== (Binary files differ) Modified: trunk/OpenMPT/mptrack/bin/mptrack_P4-Athlon64.exe =================================================================== (Binary files differ) Modified: trunk/OpenMPT/mptrack/bin/mptrack_athlon32.exe =================================================================== (Binary files differ) Deleted: trunk/OpenMPT/mptrack/bin/testSvnCommitList =================================================================== Deleted: trunk/OpenMPT/mptrack/bin/testSvnCommitList2 =================================================================== Modified: trunk/OpenMPT/mptrack/bin/version =================================================================== --- trunk/OpenMPT/mptrack/bin/version 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/mptrack/bin/version 2006-04-11 23:44:36 UTC (rev 156) @@ -1 +1 @@ -1.17.02.41 \ No newline at end of file +1.17.02.42 \ No newline at end of file Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/mptrack/mptrack.rc 2006-04-11 23:44:36 UTC (rev 156) @@ -106,6 +106,7 @@ MENUITEM "Save as &Wave...", ID_FILE_SAVEASWAVE MENUITEM "Save as M&P3...", ID_FILE_SAVEASMP3 MENUITEM "Export as M&idi...", ID_FILE_SAVEMIDI + MENUITEM "Export &unraped...", ID_FILE_SAVECOMPAT MENUITEM SEPARATOR MENUITEM "Import &midi Library...", ID_IMPORT_MIDILIB MENUITEM "Add Sound &Bank...", ID_ADD_SOUNDBANK @@ -1892,7 +1893,7 @@ // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,17,2,41 + FILEVERSION 1,17,2,42 PRODUCTVERSION 0,0,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG @@ -1910,7 +1911,7 @@ BEGIN VALUE "CompanyName", "Olivier Lapicque / OpenMPT team" VALUE "FileDescription", "OpenMPT / ModPlug Tracker" - VALUE "FileVersion", "1, 17, 2, 41" + VALUE "FileVersion", "1, 17, 2, 42" VALUE "InternalName", "Modplug Tracker" VALUE "LegalCopyright", "Copyright \xA91997-2003 Olivier Lapicque; \xA92004-2005 GPL." VALUE "LegalTrademarks", "M.O.D.P.L.U.G" @@ -2184,6 +2185,7 @@ ID_PATTERN_CHANNELMANAGER "Display channel manager window\nChannel manager" ID_INDICATOR_CPU "-" + ID_FILE_EXPORTCOMPAT "Export file to standard IT/XM." END STRINGTABLE @@ -2456,7 +2458,7 @@ STRINGTABLE BEGIN ID_SAMPLE_TRIM "Delete everything except the current selection\nTrim Sample" - ID_FILE_SAVEMIDI "Convert the current song to a standard midi file" + ID_FILE_SAVEMIDI "Export the current song to a standard midi file" ID_NETLINK_FORUMS "Go to the Modplug Central Music Forums" ID_INSTRUMENT_SAMPLEMAP "Edit the sample map" ID_NETLINK_PLUGINS "Go to KVR Audio to download plugins" Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/mptrack/resource.h 2006-04-11 23:44:36 UTC (rev 156) @@ -40,6 +40,7 @@ #define ID_PATTERN_CHANNELMANAGER 202 #define IDR_ENVELOPES 203 #define ID_INDICATOR_CPU 203 +#define ID_FILE_EXPORTCOMPAT 204 #define IDB_MAINBAR 300 #define IDB_IMAGELIST 301 #define IDB_PATTERNS 302 @@ -546,7 +547,6 @@ #define IDC_PATTERN_PLAYFROMSTART 2026 #define IDC_PATTERN_STOP 2027 #define IDC_PATTERN_RECORD 2028 -#define IDC_PATTERN_FOLLOWSONG 3029 #define IDC_PATTERN_NEW 2030 #define IDC_PATTERN_OCTAVELINK 2031 #define IDC_SPIN_SPACING 2032 @@ -738,6 +738,7 @@ #define IDC_TEXT_RPB 2301 #define IDC_SPIN_RPB 2302 #define IDC_EDIT_RPB 2303 +#define IDC_PATTERN_FOLLOWSONG 3029 #define ID_FILE_NEWMOD 32771 #define ID_FILE_NEWXM 32772 #define ID_FILE_NEWS3M 32773 @@ -939,6 +940,8 @@ #define ID_PATTERN_ADDCHANNEL_AFTER 59149 #define ID_PATTERN_REMOVECHANNEL 59150 #define ID_PATTERN_REMOVECHANNELDIALOG 59151 +#define ID_Menu 59200 +#define ID_FILE_SAVECOMPAT 59202 // Next default values for new objects // @@ -946,7 +949,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 510 -#define _APS_NEXT_COMMAND_VALUE 59200 +#define _APS_NEXT_COMMAND_VALUE 59203 #define _APS_NEXT_CONTROL_VALUE 2255 #define _APS_NEXT_SYMED_VALUE 901 #endif Modified: trunk/OpenMPT/packageTemplate/History.txt =================================================================== --- trunk/OpenMPT/packageTemplate/History.txt 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/packageTemplate/History.txt 2006-04-11 23:44:36 UTC (rev 156) @@ -8,7 +8,15 @@ ?: other (tx XYZ): thanks to XYZ for telling me about the bug +. v1.17.02.42 + + <rewbs> "Compatibility export" in file menu: save as 'plain' IT, without all of OpenMPT's crap. IT only for now (not XM). + . <rewbs> Set instrument in pattern editor should work when no note is specified (tx Torvus - http://lpchip.com/modplug/viewtopic.php?t=470) + . <rewbs> Restart position saved in IT (tx LPChip - http://lpchip.com/modplug/viewtopic.php?t=473) + . <rewbs> Loop song now works even if restart pos falls on +++ (tx LPChip - http://lpchip.com/modplug/viewtopic.php?t=463) + . <rewbs> Last used tempo is applied even when playback is triggered from instrument panel. (tx LPChip - http://lpchip.com/modplug/viewtopic.php?t=480) + / <rewbs> User now gets a warning when loading MDA Degrade (tx fisk0 - http://lpchip.com/modplug/viewtopic.php?t=467) + . v 1.17.02.41 + <rewbs> Pattern record state is now saved to ini . <rewbs> Fixed the following settings that were not saving correctly: mod document window status, row spacing, channel VU meters, channel effect visibility, Most recent files list, Toolbar settings. Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2006-04-11 23:44:36 UTC (rev 156) @@ -601,6 +601,7 @@ case 'SPA.': fadr = reinterpret_cast<BYTE*>(&m_nSongPreAmp); break; case 'VSTV': fadr = reinterpret_cast<BYTE*>(&m_nVSTiVolume); break; case 'DGV.': fadr = reinterpret_cast<BYTE*>(&m_nDefaultGlobalVolume); break; + case 'RP..': fadr = reinterpret_cast<BYTE*>(&m_nRestartPos); break; } if (fadr != NULL) { // if field code recognized @@ -1007,6 +1008,7 @@ case 'SPA.': fadr = reinterpret_cast<BYTE*>(&m_nSongPreAmp); break; case 'VSTV': fadr = reinterpret_cast<BYTE*>(&m_nVSTiVolume); break; case 'DGV.': fadr = reinterpret_cast<BYTE*>(&m_nDefaultGlobalVolume); break; + case 'RP..': fadr = reinterpret_cast<BYTE*>(&m_nRestartPos); break; } if (fadr != NULL) { // if field code recognized @@ -1996,6 +1998,579 @@ #pragma warning(default:4100) #endif // MODPLUG_NO_FILESAVE +//HACK: This is a quick fix. Needs to be better integrated into player and GUI. +//And need to split into subroutines and eliminate code duplication with SaveIT. +BOOL CSoundFile::SaveCompatIT(LPCSTR lpszFileName) +//------------------------------------------------ +{ + const int IT_MAX_CHANNELS=64; + DWORD dwPatNamLen, dwChnNamLen; + ITFILEHEADER header; + ITINSTRUMENT iti; + ITSAMPLESTRUCT itss; + BYTE smpcount[(MAX_SAMPLES+7)/8]; + DWORD inspos[MAX_INSTRUMENTS]; + DWORD patpos[MAX_PATTERNS]; + DWORD smppos[MAX_SAMPLES]; + DWORD dwPos = 0, dwHdrPos = 0, dwExtra = 2; + WORD patinfo[4]; +// -> CODE#0006 +// -> DESC="misc quantity changes" + BYTE chnmask[IT_MAX_CHANNELS]; + MODCOMMAND lastvalue[IT_MAX_CHANNELS]; + UINT nChannels = min(m_nChannels, IT_MAX_CHANNELS); +// -! BEHAVIOUR_CHANGE#0006 + BYTE buf[512]; + FILE *f; + + + if ((!lpszFileName) || ((f = fopen(lpszFileName, "wb")) == NULL)) return FALSE; + memset(inspos, 0, sizeof(inspos)); + memset(patpos, 0, sizeof(patpos)); + memset(smppos, 0, sizeof(smppos)); + // Writing Header + memset(&header, 0, sizeof(header)); + dwPatNamLen = 0; + dwChnNamLen = 0; + header.id = 0x4D504D49; + lstrcpyn(header.songname, m_szNames[0], 27); + header.reserved1 = 0x1004; + header.ordnum = 0; + header.ordnum=MAX_ORDERS; + while (header.ordnum>0 && Order[header.ordnum-1]==0xFF) { + header.ordnum--; + } + header.patnum = MAX_PATTERNS; + while ((header.patnum > 0) && (!Patterns[header.patnum-1])) { + header.patnum--; + } + + header.insnum = m_nInstruments; + header.smpnum = m_nSamples; + header.cwtv = 0x888; // We don't use these version info fields any more. + header.cmwt = 0x888; // Might come up as "Impulse Tracker 8" file in XMPlay. :) + header.flags = 0x0001; + header.special = 0x0006; + if (m_nInstruments) header.flags |= 0x04; + if (m_dwSongFlags & SONG_LINEARSLIDES) header.flags |= 0x08; + if (m_dwSongFlags & SONG_ITOLDEFFECTS) header.flags |= 0x10; + if (m_dwSongFlags & SONG_ITCOMPATMODE) header.flags |= 0x20; + if (m_dwSongFlags & SONG_EXFILTERRANGE) header.flags |= 0x1000; + header.globalvol = m_nDefaultGlobalVolume >> 1; + header.mv = m_nSongPreAmp; + if (header.mv < 0x20) header.mv = 0x20; + if (header.mv > 0x7F) header.mv = 0x7F; + header.speed = m_nDefaultSpeed; + header.tempo = min(m_nDefaultTempo,255); //Limit this one to 255, we save the real one as an extension below. + header.sep = 128; + dwHdrPos = sizeof(header) + header.ordnum; + // Channel Pan and Volume + memset(header.chnpan, 0xFF, 64); + memset(header.chnvol, 64, 64); + for (UINT ich=0; ich<nChannels; ich++) + { + header.chnpan[ich] = ChnSettings[ich].nPan >> 2; + if (ChnSettings[ich].dwFlags & CHN_SURROUND) header.chnpan[ich] = 100; + header.chnvol[ich] = ChnSettings[ich].nVolume; + if (ChnSettings[ich].dwFlags & CHN_MUTE) header.chnpan[ich] |= 0x80; +/* if (ChnSettings[ich].szName[0]) + { + dwChnNamLen = (ich+1) * MAX_CHANNELNAME; + } +*/ + } +// if (dwChnNamLen) dwExtra += dwChnNamLen + 8; +/*#ifdef SAVEITTIMESTAMP + dwExtra += 8; // Time Stamp +#endif +*/ + if (m_dwSongFlags & SONG_EMBEDMIDICFG) + { + header.flags |= 0x80; + header.special |= 0x08; + dwExtra += sizeof(MODMIDICFG); + } + // Pattern Names +/* if ((m_nPatternNames) && (m_lpszPatternNames)) + { + dwPatNamLen = m_nPatternNames * MAX_PATTERNNAME; + while ((dwPatNamLen >= MAX_PATTERNNAME) && (!m_lpszPatternNames[dwPatNamLen-MAX_PATTERNNAME])) dwPatNamLen -= MAX_PATTERNNAME; + if (dwPatNamLen < MAX_PATTERNNAME) dwPatNamLen = 0; + if (dwPatNamLen) dwExtra += dwPatNamLen + 8; + } +*/ // Mix Plugins + //dwExtra += SaveMixPlugins(NULL, TRUE); + // Comments + if (m_lpszSongComments) + { + header.special |= 1; + header.msglength = strlen(m_lpszSongComments)+1; + header.msgoffset = dwHdrPos + dwExtra + header.insnum*4 + header.patnum*4 + header.smpnum*4; + } + // Write file header + fwrite(&header, 1, sizeof(header), f); + fwrite(Order, 1, header.ordnum, f); + if (header.insnum) fwrite(inspos, 4, header.insnum, f); + if (header.smpnum) fwrite(smppos, 4, header.smpnum, f); + if (header.patnum) fwrite(patpos, 4, header.patnum, f); + // Writing editor history information + { +/*#ifdef SAVEITTIMESTAMP + SYSTEMTIME systime; + FILETIME filetime; + WORD timestamp[4]; + WORD nInfoEx = 1; + memset(timestamp, 0, sizeof(timestamp)); + fwrite(&nInfoEx, 1, 2, f); + GetSystemTime(&systime); + SystemTimeToFileTime(&systime, &filetime); + FileTimeToDosDateTime(&filetime, ×tamp[0], ×tamp[1]); + fwrite(timestamp, 1, 8, f); +#else +*/ WORD nInfoEx = 0; + fwrite(&nInfoEx, 1, 2, f); +//#endif + } + // Writing midi cfg + if (header.flags & 0x80) + { + fwrite(&m_MidiCfg, 1, sizeof(MODMIDICFG), f); + } + // Writing pattern names +/* if (dwPatNamLen) + { + DWORD d = 0x4d414e50; + fwrite(&d, 1, 4, f); + fwrite(&dwPatNamLen, 1, 4, f); + fwrite(m_lpszPatternNames, 1, dwPatNamLen, f); + } +*/ // Writing channel Names +/* if (dwChnNamLen) + { + DWORD d = 0x4d414e43; + fwrite(&d, 1, 4, f); + fwrite(&dwChnNamLen, 1, 4, f); + UINT nChnNames = dwChnNamLen / MAX_CHANNELNAME; + for (UINT inam=0; inam<nChnNames; inam++) + { + fwrite(ChnSettings[inam].szName, 1, MAX_CHANNELNAME, f); + } + } +*/ // Writing mix plugins info +/* SaveMixPlugins(f, FALSE); +*/ // Writing song message + dwPos = dwHdrPos + dwExtra + (header.insnum + header.smpnum + header.patnum) * 4; + if (header.special & 1) + { + dwPos += strlen(m_lpszSongComments) + 1; + fwrite(m_lpszSongComments, 1, strlen(m_lpszSongComments)+1, f); + } + // Writing instruments + for (UINT nins=1; nins<=header.insnum; nins++) + { + BOOL bKbdEx = FALSE; + BYTE keyboardex[120]; + + memset(&iti, 0, sizeof(iti)); + iti.id = 0x49504D49; // "IMPI" + //iti.trkvers = 0x211; + iti.trkvers = 0x220; //rewbs.itVersion + if (Headers[nins]) + { + INSTRUMENTHEADER *penv = Headers[nins]; + memset(smpcount, 0, sizeof(smpcount)); + memcpy(iti.filename, penv->filename, 12); + memcpy(iti.name, penv->name, 26); + iti.mbank = penv->wMidiBank; + iti.mpr = penv->nMidiProgram; + iti.mch = penv->nMidiChannel; + iti.nna = penv->nNNA; + if (penv->nDCT<DCT_PLUGIN) iti.dct = penv->nDCT; else iti.dct =0; + iti.dca = penv->nDNA; + iti.fadeout = penv->nFadeOut >> 5; + iti.pps = penv->nPPS; + iti.ppc = penv->nPPC; + iti.gbv = (BYTE)(penv->nGlobalVol << 1); + iti.dfp = (BYTE)penv->nPan >> 2; + if (!(penv->dwFlags & ENV_SETPANNING)) iti.dfp |= 0x80; + iti.rv = penv->nVolSwing; + iti.rp = penv->nPanSwing; + iti.ifc = penv->nIFC; + iti.ifr = penv->nIFR; + iti.nos = 0; + for (UINT i=0; i<120; i++) if (penv->Keyboard[i] < MAX_SAMPLES) + { + UINT smp = penv->Keyboard[i]; + if ((smp) && (!(smpcount[smp>>3] & (1<<(smp&7))))) + { + smpcount[smp>>3] |= 1 << (smp&7); + iti.nos++; + } + iti.keyboard[i*2] = penv->NoteMap[i] - 1; + iti.keyboard[i*2+1] = smp; + if (smp > 0xff) bKbdEx = TRUE; + keyboardex[i] = (smp>>8); + } else keyboardex[i] = 0; + // Writing Volume envelope + if (penv->dwFlags & ENV_VOLUME) iti.volenv.flags |= 0x01; + if (penv->dwFlags & ENV_VOLLOOP) iti.volenv.flags |= 0x02; + if (penv->dwFlags & ENV_VOLSUSTAIN) iti.volenv.flags |= 0x04; + if (penv->dwFlags & ENV_VOLCARRY) iti.volenv.flags |= 0x08; + iti.volenv.num = (BYTE)penv->nVolEnv; + iti.volenv.lpb = (BYTE)penv->nVolLoopStart; + iti.volenv.lpe = (BYTE)penv->nVolLoopEnd; + iti.volenv.slb = penv->nVolSustainBegin; + iti.volenv.sle = penv->nVolSustainEnd; + // Writing Panning envelope + if (penv->dwFlags & ENV_PANNING) iti.panenv.flags |= 0x01; + if (penv->dwFlags & ENV_PANLOOP) iti.panenv.flags |= 0x02; + if (penv->dwFlags & ENV_PANSUSTAIN) iti.panenv.flags |= 0x04; + if (penv->dwFlags & ENV_PANCARRY) iti.panenv.flags |= 0x08; + iti.panenv.num = (BYTE)penv->nPanEnv; + iti.panenv.lpb = (BYTE)penv->nPanLoopStart; + iti.panenv.lpe = (BYTE)penv->nPanLoopEnd; + iti.panenv.slb = penv->nPanSustainBegin; + iti.panenv.sle = penv->nPanSustainEnd; + // Writing Pitch Envelope + if (penv->dwFlags & ENV_PITCH) iti.pitchenv.flags |= 0x01; + if (penv->dwFlags & ENV_PITCHLOOP) iti.pitchenv.flags |= 0x02; + if (penv->dwFlags & ENV_PITCHSUSTAIN) iti.pitchenv.flags |= 0x04; + if (penv->dwFlags & ENV_PITCHCARRY) iti.pitchenv.flags |= 0x08; + if (penv->dwFlags & ENV_FILTER) iti.pitchenv.flags |= 0x80; + iti.pitchenv.num = (BYTE)penv->nPitchEnv; + iti.pitchenv.lpb = (BYTE)penv->nPitchLoopStart; + iti.pitchenv.lpe = (BYTE)penv->nPitchLoopEnd; + iti.pitchenv.slb = (BYTE)penv->nPitchSustainBegin; + iti.pitchenv.sle = (BYTE)penv->nPitchSustainEnd; + // Writing Envelopes data + for (UINT ev=0; ev<25; ev++) + { + iti.volenv.data[ev*3] = penv->VolEnv[ev]; + iti.volenv.data[ev*3+1] = penv->VolPoints[ev] & 0xFF; + iti.volenv.data[ev*3+2] = penv->VolPoints[ev] >> 8; + iti.panenv.data[ev*3] = penv->PanEnv[ev] - 32; + iti.panenv.data[ev*3+1] = penv->PanPoints[ev] & 0xFF; + iti.panenv.data[ev*3+2] = penv->PanPoints[ev] >> 8; + iti.pitchenv.data[ev*3] = penv->PitchEnv[ev] - 32; + iti.pitchenv.data[ev*3+1] = penv->PitchPoints[ev] & 0xFF; + iti.pitchenv.data[ev*3+2] = penv->PitchPoints[ev] >> 8; + } + } else + // Save Empty Instrument + { + for (UINT i=0; i<120; i++) iti.keyboard[i*2] = i; + iti.ppc = 5*12; + iti.gbv = 128; + iti.dfp = 0x20; + iti.ifc = 0xFF; + } + if (!iti.nos) iti.trkvers = 0; + // Writing instrument + if (bKbdEx) *((int *)iti.dummy) = 'MPTX'; + inspos[nins-1] = dwPos; + dwPos += sizeof(ITINSTRUMENT); + fwrite(&iti, 1, sizeof(ITINSTRUMENT), f); + if (bKbdEx) + { + dwPos += 120; + fwrite(keyboardex, 1, 120, f); + } + + //------------ rewbs.modularInstData +/* if (Headers[nins]) + { + long modularInstSize = 0; + UINT ModInstID = 'INSM'; + fwrite(&ModInstID, 1, sizeof(ModInstID), f); // mark this as an instrument with modular extensions + long sizePos = ftell(f); // we will want to write the modular data's total size here + fwrite(&modularInstSize, 1, sizeof(modularInstSize), f); // write a DUMMY size, just to move file pointer by a long + + //Write chunks + UINT ID; + { //VST Slot chunk: + ID='PLUG'; + fwrite(&ID, 1, sizeof(int), f); + INSTRUMENTHEADER *penv = Headers[nins]; + fwrite(&(penv->nMixPlug), 1, sizeof(BYTE), f); + modularInstSize += sizeof(int)+sizeof(BYTE); + } +*/ //How to save your own modular instrument chunk: + /* { + ID='MYID'; + fwrite(&ID, 1, sizeof(int), f); + instModularDataSize+=sizeof(int); + + //You can save your chunk size somwhere here if you need variable chunk size. + fwrite(myData, 1, myDataSize, f); + instModularDataSize+=myDataSize; + } + */ +/* //write modular data's total size + long curPos = ftell(f); // remember current pos + fseek(f, sizePos, SEEK_SET); // go back to sizePos + fwrite(&modularInstSize, 1, sizeof(modularInstSize), f); // write data + fseek(f, curPos, SEEK_SET); // go back to where we were. + + //move forward + dwPos+=sizeof(ModInstID)+sizeof(modularInstSize)+modularInstSize; + } +*/ //------------ end rewbs.modularInstData + } + // Writing sample headers + memset(&itss, 0, sizeof(itss)); + for (UINT hsmp=0; hsmp<header.smpnum; hsmp++) + { + smppos[hsmp] = dwPos; + dwPos += sizeof(ITSAMPLESTRUCT); + fwrite(&itss, 1, sizeof(ITSAMPLESTRUCT), f); + } + // Writing Patterns + for (UINT npat=0; npat<header.patnum; npat++) + { + DWORD dwPatPos = dwPos; + UINT len; + if (!Patterns[npat]) continue; + patpos[npat] = dwPos; + patinfo[0] = 0; + patinfo[1] = PatternSize[npat]; + patinfo[2] = 0; + patinfo[3] = 0; + // Check for empty pattern + if (PatternSize[npat] == 64) + { + MODCOMMAND *pzc = Patterns[npat]; + UINT nz = PatternSize[npat] * nChannels; + for (UINT iz=0; iz<nz; iz++) + { + if ((pzc[iz].note) || (pzc[iz].instr) + || (pzc[iz].volcmd) || (pzc[iz].command)) break; + } + if (iz == nz) + { + patpos[npat] = 0; + continue; + } + } + fwrite(patinfo, 8, 1, f); + dwPos += 8; + memset(chnmask, 0xFF, sizeof(chnmask)); + memset(lastvalue, 0, sizeof(lastvalue)); + MODCOMMAND *m = Patterns[npat]; + for (UINT row=0; row<PatternSize[npat]; row++) + { + len = 0; + for (UINT ch=0; ch<nChannels; ch++, m++) + { + BYTE b = 0; + UINT command = m->command; + UINT param = m->param; + UINT vol = 0xFF; + UINT note = m->note; + if (note) b |= 1; + if ((note) && (note < 0xFE)) note--; + if (m->instr) b |= 2; + if (m->volcmd) + { + UINT volcmd = m->volcmd; + switch(volcmd) + { + case VOLCMD_VOLUME: vol = m->vol; if (vol > 64) vol = 64; break; + case VOLCMD_PANNING: vol = m->vol + 128; if (vol > 192) vol = 192; break; + case VOLCMD_VOLSLIDEUP: vol = 85 + ConvertVolParam(m->vol); break; + case VOLCMD_VOLSLIDEDOWN: vol = 95 + ConvertVolParam(m->vol); break; + case VOLCMD_FINEVOLUP: vol = 65 + ConvertVolParam(m->vol); break; + case VOLCMD_FINEVOLDOWN: vol = 75 + ConvertVolParam(m->vol); break; + case VOLCMD_VIBRATO: vol = 203; break; + case VOLCMD_VIBRATOSPEED: vol = 203 + ConvertVolParam(m->vol); break; + case VOLCMD_TONEPORTAMENTO: vol = 193 + ConvertVolParam(m->vol); break; + case VOLCMD_PORTADOWN: vol = 105 + ConvertVolParam(m->vol); break; + case VOLCMD_PORTAUP: vol = 115 + ConvertVolParam(m->vol); break; + case VOLCMD_VELOCITY: vol = 213 + ConvertVolParam(m->vol); break; //rewbs.velocity + case VOLCMD_OFFSET: vol = 223 + ConvertVolParam(m->vol); break; //rewbs.volOff + default: vol = 0xFF; + } + } + if (vol != 0xFF) b |= 4; + if (command) + { + S3MSaveConvert(&command, ¶m, TRUE); + if (command) b |= 8; + } + // Packing information + if (b) + { + // Same note ? + if (b & 1) + { + if ((note == lastvalue[ch].note) && (lastvalue[ch].volcmd & 1)) + { + b &= ~1; + b |= 0x10; + } else + { + lastvalue[ch].note = note; + lastvalue[ch].volcmd |= 1; + } + } + // Same instrument ? + if (b & 2) + { + if ((m->instr == lastvalue[ch].instr) && (lastvalue[ch].volcmd & 2)) + { + b &= ~2; + b |= 0x20; + } else + { + lastvalue[ch].instr = m->instr; + lastvalue[ch].volcmd |= 2; + } + } + // Same volume column byte ? + if (b & 4) + { + if ((vol == lastvalue[ch].vol) && (lastvalue[ch].volcmd & 4)) + { + b &= ~4; + b |= 0x40; + } else + { + lastvalue[ch].vol = vol; + lastvalue[ch].volcmd |= 4; + } + } + // Same command / param ? + if (b & 8) + { + if ((command == lastvalue[ch].command) && (param == lastvalue[ch].param) && (lastvalue[ch].volcmd & 8)) + { + b &= ~8; + b |= 0x80; + } else + { + lastvalue[ch].command = command; + lastvalue[ch].param = param; + lastvalue[ch].volcmd |= 8; + } + } + if (b != chnmask[ch]) + { + chnmask[ch] = b; + buf[len++] = (ch+1) | 0x80; + buf[len++] = b; + } else + { + buf[len++] = ch+1; + } + if (b & 1) buf[len++] = note; + if (b & 2) buf[len++] = m->instr; + if (b & 4) buf[len++] = vol; + if (b & 8) + { + buf[len++] = command; + buf[len++] = param; + } + } + } + buf[len++] = 0; + dwPos += len; + patinfo[0] += len; + fwrite(buf, 1, len, f); + } + fseek(f, dwPatPos, SEEK_SET); + fwrite(patinfo, 8, 1, f); + fseek(f, dwPos, SEEK_SET); + } + // Writing Sample Data + for (UINT nsmp=1; nsmp<=header.smpnum; nsmp++) + { + MODINSTRUMENT *psmp = &Ins[nsmp]; + memset(&itss, 0, sizeof(itss)); + memcpy(itss.filename, psmp->name, 12); + memcpy(itss.name, m_szNames[nsmp], 26); + itss.id = 0x53504D49; + itss.gvl = (BYTE)psmp->nGlobalVol; + if (m_nInstruments) + { + for (UINT iu=1; iu<=m_nInstruments; iu++) if (Headers[iu]) + { + INSTRUMENTHEADER *penv = Headers[iu]; + for (UINT ju=0; ju<128; ju++) if (penv->Keyboard[ju] == nsmp) + { + itss.flags = 0x01; + break; + } + } + } else + { + itss.flags = 0x01; + } + if (psmp->uFlags & CHN_LOOP) itss.flags |= 0x10; + if (psmp->uFlags & CHN_SUSTAINLOOP) itss.flags |= 0x20; + if (psmp->uFlags & CHN_PINGPONGLOOP) itss.flags |= 0x40; + if (psmp->uFlags & CHN_PINGPONGSUSTAIN) itss.flags |= 0x80; + itss.C5Speed = psmp->nC4Speed; + if (!itss.C5Speed) itss.C5Speed = 8363; + itss.length = psmp->nLength; + itss.loopbegin = psmp->nLoopStart; + itss.loopend = psmp->nLoopEnd; + itss.susloopbegin = psmp->nSustainStart; + itss.susloopend = psmp->nSustainEnd; + 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; + 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|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.samplepointer = dwPos; + fseek(f, smppos[nsmp-1], SEEK_SET); + fwrite(&itss, 1, sizeof(ITSAMPLESTRUCT), f); + fseek(f, dwPos, SEEK_SET); + if ((psmp->pSample) && (psmp->nLength)) + { + dwPos += WriteSample(f, psmp, flags); + } + } + + //Save hacked-on extra info +// SaveExtendedInstrumentProperties(Headers, header.insnum, f); +// SaveExtendedSongProperties(f); + + // Updating offsets + fseek(f, dwHdrPos, SEEK_SET); + if (header.insnum) fwrite(inspos, 4, header.insnum, f); + if (header.smpnum) fwrite(smppos, 4, header.smpnum, f); + if (header.patnum) fwrite(patpos, 4, header.patnum, f); + fclose(f); + return TRUE; + +} + ////////////////////////////////////////////////////////////////////////////// // IT 2.14 compression @@ -2549,5 +3124,12 @@ fwrite(&size, 1, sizeof(__int16), f); fwrite(&m_nDefaultGlobalVolume, 1, size, f); + code = 'RP..'; //write m_nRestartPos + fwrite(&code, 1, sizeof(__int32), f); + size = sizeof(m_nRestartPos); + fwrite(&size, 1, sizeof(__int16), f); + fwrite(&m_nRestartPos, 1, size, f); + + return; } \ No newline at end of file Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2006-04-11 23:44:36 UTC (rev 156) @@ -988,4 +988,12 @@ return TRUE; } +//HACK: This is a quick fix. Needs to be better integrated into player and GUI. +BOOL CSoundFile::SaveCompatXM(LPCSTR lpszFileName) +//------------------------------------------------ +{ + + return TRUE; +} + #endif // MODPLUG_NO_FILESAVE Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2006-04-11 23:44:36 UTC (rev 156) @@ -172,6 +172,7 @@ PSB. nPanSustainBegin; PSE. nPanSustainEnd; R... nResampling; +RP.. [EXT] nRestartPos; RPB. [EXT] nRowsPerBeat; RPM. [EXT] nRowsPerMeasure; RS.. nResSwing; Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/soundlib/Sndfile.h 2006-04-11 23:44:36 UTC (rev 156) @@ -934,6 +934,8 @@ BOOL SaveS3M(LPCSTR lpszFileName, UINT nPacking=0); BOOL SaveMod(LPCSTR lpszFileName, UINT nPacking=0); BOOL SaveIT(LPCSTR lpszFileName, UINT nPacking=0); + BOOL SaveCompatIT(LPCSTR lpszFileName); + BOOL SaveCompatXM(LPCSTR lpszFileName); // -> CODE#0023 // -> DESC="IT project files (.itp)" BOOL SaveITProject(LPCSTR lpszFileName); Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2006-03-23 01:46:21 UTC (rev 155) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2006-04-11 23:44:36 UTC (rev 156) @@ -611,7 +611,8 @@ m_nTickCount = 0; m_nRow = m_nNextRow; // Reset Pattern Loop Effect - if (m_nCurrentPattern != m_nNextPattern) m_nCurrentPattern = m_nNextPattern; + if (m_nCurrentPattern != m_nNextPattern) + m_nCurrentPattern = m_nNextPattern; // Check if pattern is valid if (!(m_dwSongFlags & SONG_PATTERNLOOP)) { @@ -629,16 +630,14 @@ //rewbs.instroVSTi: stop all VSTi at end of song, if looping. StopAllVsti(); - m_nMusicSpeed = m_nDefaultSpeed; m_nMusicTempo = m_nDefaultTempo; m_nGlobalVolume = m_nDefaultGlobalVolume; - for (UINT i=0; i<MAX_CHANNELS; i++) - { + for (UINT i=0; i<MAX_CHANNELS; i++) { Chn[i].dwFlags |= CHN_NOTEFADE | CHN_KEYOFF; Chn[i].nFadeOutVol = 0; - if (i < m_nChannels) - { + + if (i < m_nChannels) { Chn[i].nGlobalVol = ChnSettings[i].nVolume; Chn[i].nVolume = ChnSettings[i].nVolume; Chn[i].nPan = ChnSettings[i].nPan; @@ -648,8 +647,8 @@ Chn[i].nOldOffset = 0; Chn[i].nOldHiOffset = 0; Chn[i].nPortamentoDest = 0; - if (!Chn[i].nLength) - { + + if (!Chn[i].nLength) { Chn[i].dwFlags = ChnSettings[i].dwFlags; Chn[i].nLoopStart = 0; Chn[i].nLoopEnd = 0; @@ -662,31 +661,42 @@ } + + //Handle Repeat position if (m_nRepeatCount > 0) m_nRepeatCount--; m_nCurrentPattern = m_nRestartPos; - m_nRow = 0; - if ((Order[m_nCurrentPattern] >= MAX_PATTERNS) || (!Patterns[Order[m_nCurrentPattern]])) return FALSE; - } else - { + m_nRow = 0; + //If restart pos points to +++, move along + while (Order[m_nCurrentPattern] == 0xFE) { + m_nCurrentPattern++; + } + //Check for end of song or bad pattern + if ( (Order[m_nCurrentPattern] >= MAX_PATTERNS) + || (!Patterns[Order[m_nCurrentPattern]]) ) { + return FALSE; + } + + } else { m_nCurrentPattern++; } - m_nPattern = (m_nCurrentPattern < MAX_ORDERS) ? Order[m_nCurrentPattern] : 0xFF; - if ((m_nPattern < MAX_PATTERNS) && (!Patterns[m_nPattern])) m_nPattern = 0xFE; + + if (m_nCurrentPattern < MAX_ORDERS) { + m_nPattern = Order[m_nCurrentPattern]; + } else { + m_nPattern = 0xFF; + } + + if ((m_nPattern < MAX_PATTERNS) && (!Patterns[m_nPattern])) { + m_nPattern = 0xFE; + } } m_nNextPattern = m_nCurrentPattern; #ifdef MODPLUG_TRACKER -// if (m_nInstruments) ProcessMidiOut(); //rewbs.VSTnoteDelay if ((m_nMaxOrderPosition) && (m_nCurrentPattern >= m_nMaxOrderPosition)) return FALSE; #endif // MODPLUG_TRACKER } -//#ifdef MODPLUG_TRACKER -// if (m_dwSongFlags & SONG_STEP) -// { -// m_dwSongFlags &= ~SONG_STEP; -// m_dwSongFlags |= SONG_PAUSED; -// } -//#endif // MODPLUG_TRACKER + // Weird stuff? if ((m_nPattern >= MAX_PATTERNS) || (!Patterns[m_nPattern])) return FALSE; // Should never happen @@ -766,10 +776,7 @@ //////////////////////////////////////////////////////////////////////////////////// m_nTotalCount++; if (!m_nMusicTempo) return FALSE; -// -> CODE#0022 -// -> DESC="alternative BPM/Speed interpretation method" - switch(m_nTempoMode) { case tempo_mode_alternative: @@ -796,47 +803,22 @@ default: m_nBufferCount = (gdwMixingFreq * 5 * m_nTempoFactor) / (m_nMusicTempo << 8); } - /* - if (CMainFrame::m_dwPatternSetup & PATTERN_ALTERNTIVEBPMSPEED) { - m_nBufferCount = gdwMixingFreq / m_nMusicTempo; - } - else { - m_nBufferCount = (gdwMixingFreq * 5 * m_nTempoFactor) / (m_nMusicTempo << 8); - } - */ -// -! NEW_FEATURE#0022 m_nSamplesPerTick = m_nBufferCount; //rewbs.flu -#ifdef MODPLUG_TRACKER - if (m_dwSongFlags & SONG_PAUSED) - { - m_nBufferCount = gdwMixingFreq / 64; // 1/64 seconds - } -#endif + +// robinf: this block causes envelopes to behave incorrectly when +// playback is triggered from instrument panel. +// I can't see why it would be useful. Dissabling for now. +// +// if (m_dwSongFlags & SONG_PAUSED) { +// m_nBufferCount = gdwMixingFreq / 64; // 1/64 seconds +// } + + // Master Volume + Pre-Amplification / Attenuation setup DWORD nMasterVol; { -////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ericus 10/02/2005 -/* - int nchn32 = (m_nChannels < 32) ? m_nChannels : 31; - if ((m_nType & MOD_TYPE_IT) && (m_nInstruments) && (nchn32 < 6)) nchn32 = 6; - int realmastervol = m_nMasterVolume; - if (realmastervol > 0x80) - { - realmastervol = 0x80 + ((realmastervol - 0x80) * (nchn32+4)) / 16; - } - UINT attenuation = (gdwSoundSetup & SNDMIX_AGC) ? PreAmpAGCTable[nchn32>>1] : PreAmpTable[nchn32>>1]; - DWORD mastervol = (realmastervol * (m_nSongPreAmp + 0x10)) >> 6; - if (mastervol > 0x200) mastervol = 0x200; - if ((m_dwSongFlags & SONG_GLOBALFADE) && (m_nGlobalFadeMaxSamples)) - { - mastervol = _muldiv(mastervol, m_nGlobalFadeSamples, m_nGlobalFadeMaxSamples); - } - nMasterVol = (mastervol << 7) / attenuation; - if (nMasterVol > 0x180) nMasterVol = 0x180; -*/ int nchn32 = 0; MODCHANNEL *pChn = Chn; for (UINT nChn=0; nChn<m_nChannels; nChn++,pChn++) { @@ -862,8 +844,6 @@ if(attenuation < 1) attenuation = 1; nMasterVol = (mastervol << 7) / attenuation; - -////////////////////////////////////////////////////////////////////////////////////////////////////////////// } //////////////////////////////////////////////////////////////////////////////////// // Update channels data This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |