From: <sag...@us...> - 2009-09-21 13:05:20
|
Revision: 373 http://modplug.svn.sourceforge.net/modplug/?rev=373&view=rev Author: saga-games Date: 2009-09-21 13:05:09 +0000 (Mon, 21 Sep 2009) Log Message: ----------- [Imp] Tuning dialog: Using the default tuning path as default path for Import/Export dialog [Imp] IT Loader: Removed unnecessary / wrong pre-amp limits Modified Paths: -------------- trunk/OpenMPT/mptrack/Mptrack.h trunk/OpenMPT/mptrack/TuningDialog.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Sndfile.cpp Modified: trunk/OpenMPT/mptrack/Mptrack.h =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.h 2009-09-20 13:44:24 UTC (rev 372) +++ trunk/OpenMPT/mptrack/Mptrack.h 2009-09-21 13:05:09 UTC (rev 373) @@ -187,6 +187,7 @@ BOOL IsDebug() const { return m_bDebugMode; } LPCSTR GetConfigFileName() const { return m_szConfigFileName; } LPCSTR GetPluginCacheFileName() const { return m_szPluginCacheFileName; } + LPCSTR GetTuningsPath() const { return m_szTuningsDirectory; } LPCSTR GetConfigPath() const { return m_szConfigDirectory; } void SetupPaths(); Modified: trunk/OpenMPT/mptrack/TuningDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/TuningDialog.cpp 2009-09-20 13:44:24 UTC (rev 372) +++ trunk/OpenMPT/mptrack/TuningDialog.cpp 2009-09-21 13:05:09 UTC (rev 373) @@ -629,6 +629,7 @@ NULL, OFN_HIDEREADONLY| OFN_ENABLESIZING | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_NOREADONLYRETURN, filter.c_str(), this); + dlg.m_ofn.lpstrInitialDir = theApp.GetTuningsPath(); bool failure = true; @@ -668,6 +669,7 @@ OFN_HIDEREADONLY | OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST, filter.c_str(), this); + dlg.m_ofn.lpstrInitialDir = theApp.GetTuningsPath(); if (dlg.DoModal() != IDOK) return; Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-20 13:44:24 UTC (rev 372) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-21 13:05:09 UTC (rev 373) @@ -1871,12 +1871,10 @@ if (m_dwSongFlags & SONG_ITCOMPATMODE) header.flags |= 0x20; if (m_dwSongFlags & SONG_EXFILTERRANGE) header.flags |= 0x1000; header.globalvol = m_nDefaultGlobalVolume >> 1; - header.mv = m_nSamplePreAmp; - if (header.mv < 0x20) header.mv = 0x20; - if (header.mv > 0x7F) header.mv = 0x7F; + header.mv = CLAMP(m_nSamplePreAmp, 0, 128); 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; + header.tempo = min(m_nDefaultTempo, 255); //Limit this one to 255, we save the real one as an extension below. + header.sep = 128; // pan separation dwHdrPos = sizeof(header) + header.ordnum; // Channel Pan and Volume memset(header.chnpan, 0xFF, 64); @@ -2521,11 +2519,9 @@ if (m_dwSongFlags & SONG_EXFILTERRANGE) header.flags |= 0x1000; header.globalvol = m_nDefaultGlobalVolume >> 1; header.mv = CLAMP(m_nSamplePreAmp, 0, 128); - 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; + header.tempo = min(m_nDefaultTempo, 255); //Limit this one to 255, we save the real one as an extension below. + header.sep = 128; // pan separation dwHdrPos = sizeof(header) + header.ordnum; // Channel Pan and Volume memset(header.chnpan, 0xFF, 64); Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-09-20 13:44:24 UTC (rev 372) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-09-21 13:05:09 UTC (rev 373) @@ -2896,7 +2896,7 @@ } // Load local tunings. - s_pTuningsSharedLocal->SetSavefilePath(std::string(std::string(theApp.GetConfigPath()) + "tunings\\local_tunings" + CTuningCollection::s_FileExtension.c_str())); + s_pTuningsSharedLocal->SetSavefilePath(std::string(std::string(theApp.GetTuningsPath()) + "local_tunings" + CTuningCollection::s_FileExtension.c_str())); s_pTuningsSharedLocal->Deserialize(); // Enabling adding/removing of tunings for standard collection This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-09-22 17:07:29
|
Revision: 375 http://modplug.svn.sourceforge.net/modplug/?rev=375&view=rev Author: saga-games Date: 2009-09-22 17:07:04 +0000 (Tue, 22 Sep 2009) Log Message: ----------- [Mod] Compatibility Export: Use module working directory in "save as" dialog [Fix] Color Setup: When no INI file was present, channel separators were completely black [Fix] MED Loader: Possible error when loading orderlist Modified Paths: -------------- trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/misc_util.h trunk/OpenMPT/soundlib/Load_med.cpp Removed Paths: ------------- trunk/OpenMPT/mptrack/bin/default.mkb Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2009-09-21 20:03:46 UTC (rev 374) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2009-09-22 17:07:04 UTC (rev 375) @@ -255,6 +255,8 @@ 0x800000, 0x808000, 0x008000, 0x808000, 0x008080, 0x000080, 0xFF0000, // VU-Meters 0x00FF00, 0x00FFFF, 0x0000FF, + // Channel separators + GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNFACE), GetSysColor(COLOR_BTNHIGHLIGHT), }; // Directory Arrays (Default + Last) Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-21 20:03:46 UTC (rev 374) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-22 17:07:04 UTC (rev 375) @@ -1635,6 +1635,8 @@ CFileDialog dlg(FALSE, ext, s, OFN_HIDEREADONLY | OFN_ENABLESIZING | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_NOREADONLYRETURN, pattern, pMainFrm); + dlg.m_ofn.lpstrInitialDir = CMainFrame::GetWorkingDirectory(DIR_MODS); + if (dlg.DoModal() != IDOK){ return; } Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2009-09-21 20:03:46 UTC (rev 374) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2009-09-22 17:07:04 UTC (rev 375) @@ -742,6 +742,8 @@ MoveConfigFile("plugin.cache"); MoveConfigFile("mpt_intl.ini"); MoveConfigFile("default.mkb", "", "Keybindings.mkb"); + MoveConfigFile("Keybindings.mkb"); + // TODO - Check the old ini settings here } // Create tunings dir Deleted: trunk/OpenMPT/mptrack/bin/default.mkb =================================================================== --- trunk/OpenMPT/mptrack/bin/default.mkb 2009-09-21 20:03:46 UTC (rev 374) +++ trunk/OpenMPT/mptrack/bin/default.mkb 2009-09-22 17:07:04 UTC (rev 375) @@ -1,282 +0,0 @@ -//-------- OpenMPT key binding definition file ------- -//-Format is: - -//- Context:Command ID:Modifiers:Key:KeypressEventType //Comments - -//---------------------------------------------------------------------- - -//----( Global Context (0) )------------ -0:1347:2:78:1 //File/New: Ctrl+N (KeyDown) -0:1346:2:79:1 //File/Open: Ctrl+O (KeyDown) -0:1349:2:83:1 //File/Save: Ctrl+S (KeyDown) -0:1030:2:119:1 //Play song/Pause song: Ctrl+F8 (KeyDown) -0:1031:0:119:1 //Pause song: F8 (KeyDown) -0:1375:0:27:1 //Stop Song: ESC (KeyDown) -0:1029:0:116:5 //Play song from start: F5 (KeyDown|KeyHold) -0:1028:0:118:5 //Play song from cursor: F7 (KeyDown|KeyHold) -0:1027:0:117:5 //Play pattern from start: F6 (KeyDown|KeyHold) -0:1026:2:117:5 //Play pattern from cursor: Ctrl+F6 (KeyDown|KeyHold) -0:1687:6:66:1 //Show approx. real BPM: Ctrl+Alt+B (KeyDown) -0:1376:2:120:1 //Toggle Midi Record: Ctrl+F9 (KeyDown) -0:1359:2:90:1 //Undo: Ctrl+Z (KeyDown) -0:1360:2:88:1 //Cut: Ctrl+X (KeyDown) -0:1361:2:67:1 //Copy: Ctrl+C (KeyDown) -0:1361:4:67:1 //Copy: Alt+C (KeyDown) -0:1362:2:86:1 //Paste: Ctrl+V (KeyDown) -0:1362:4:86:1 //Paste: Alt+V (KeyDown) -0:1363:2:77:1 //Mix Paste: Ctrl+M (KeyDown) -0:1364:2:65:1 //SelectAll: Ctrl+A (KeyDown) -0:1365:2:70:1 //Find: Ctrl+F (KeyDown) -0:1366:2:114:1 //Find Next: Ctrl+F3 (KeyDown) -0:1021:0:122:1 //View General: F11 (KeyDown) -0:1022:0:113:1 //View Pattern: F2 (KeyDown) -0:1023:0:114:1 //View Samples: F3 (KeyDown) -0:1024:0:115:1 //View Instruments: F4 (KeyDown) -0:1025:1:120:1 //View Comments: Shift+F9 (KeyDown) -0:1368:2:113:1 //Toggle Tree View: Ctrl+F2 (KeyDown) -0:1369:2:112:1 //View Options: Ctrl+F1 (KeyDown) -0:1670:6:77:1 //View Channel Manager: Ctrl+Alt+M (KeyDown) -0:1669:3:77:1 //View 'Add Plugin' Window: Shift+Ctrl+M (KeyDown) -0:1032:0:219:5 //Previous instrument: [ (KeyDown|KeyHold) -0:1032:2:38:5 //Previous instrument: Ctrl+UP (KeyDown|KeyHold) -0:1033:0:221:5 //Next instrument: ] (KeyDown|KeyHold) -0:1033:2:40:5 //Next instrument: Ctrl+DOWN (KeyDown|KeyHold) -0:1036:0:111:5 //Previous octave: NUM DIVIDE (KeyDown|KeyHold) -0:1037:0:106:5 //Next octave: NUMMULT (KeyDown|KeyHold) -0:1034:2:37:5 //Previous order: Ctrl+LEFT (KeyDown|KeyHold) -0:1035:2:39:5 //Next order: Ctrl+RIGHT (KeyDown|KeyHold) -0:1201:0:223:1 //Note off: ` (KeyDown) - -//----( General Context [bottom] (1) )------------ - -//----( Pattern Context [bottom] (2) )------------ -2:1017:0:34:5 //Jump down by measure: PGDOWN (KeyDown|KeyHold) -2:1018:0:33:5 //Jump up by measure: PGUP (KeyDown|KeyHold) -2:1338:4:34:5 //Jump down by beat: Alt+PGDOWN (KeyDown|KeyHold) -2:1339:4:33:5 //Jump up by beat: Alt+PGUP (KeyDown|KeyHold) -2:1019:2:34:5 //Snap down to measure: Ctrl+PGDOWN (KeyDown|KeyHold) -2:1020:2:33:5 //Snap up to measure: Ctrl+PGUP (KeyDown|KeyHold) -2:1340:6:34:5 //Snap down to beat: Ctrl+Alt+PGDOWN (KeyDown|KeyHold) -2:1341:6:33:5 //Snap up to beat: Ctrl+Alt+PGUP (KeyDown|KeyHold) -2:1038:0:40:5 //Navigate down by 1 row: DOWN (KeyDown|KeyHold) -2:1039:0:38:5 //Navigate up by 1 row: UP (KeyDown|KeyHold) -2:1040:0:37:5 //Navigate left: LEFT (KeyDown|KeyHold) -2:1041:0:39:5 //Navigate right: RIGHT (KeyDown|KeyHold) -2:1042:0:9:5 //Navigate to next channel: TAB (KeyDown|KeyHold) -2:1043:2:9:5 //Navigate to previous channel: Ctrl+TAB (KeyDown|KeyHold) -2:1044:0:36:1 //Go to first channel: HOME (KeyDown) -2:1045:2:36:1 //Go to first row: Ctrl+HOME (KeyDown) -2:1046:6:36:1 //Go to first row of first channel: Ctrl+Alt+HOME (KeyDown) -2:1047:0:35:1 //Go to last channel: END (KeyDown) -2:1048:2:35:1 //Go to last row: Ctrl+END (KeyDown) -2:1049:6:35:1 //Go to last row of last channel: Ctrl+Alt+END (KeyDown) -2:1050:1:16:1 //Selection key: Shift (KeyDown) -2:1011:4:76:1 //Select channel / Select all: Alt+L (KeyDown) -2:1663:2:118:1 //Toggle follow song: Ctrl+F7 (KeyDown) -2:1003:0:13:1 //Quick copy: ENTER (KeyDown) -2:1004:0:32:5 //Quick paste: SPACE (KeyDown|KeyHold) -2:1001:1:120:1 //Enable recording: Shift+F9 (KeyDown) -2:1002:2:13:1 //Play row: Ctrl+ENTER (KeyDown) -2:1002:0:104:1 //Play row: NUM 8 (KeyDown) -2:1002:0:56:1 //Play row: 8 (KeyDown) -2:1317:4:18:1 //Set row jump on note entry: Alt (KeyDown) -2:1685:6:9:1 //Switch to order list: Ctrl+Alt+TAB (KeyDown) -2:1672:3:13:1 //Insert new pattern: Shift+Ctrl+ENTER (KeyDown) -2:1662:6:80:1 //Toggle channel's plugin editor: Ctrl+Alt+P (KeyDown) -2:1062:0:93:1 //Show note properties: Application (KeyDown) -2:1063:2:93:1 //Show context (right-click) menu: Ctrl+Application (KeyDown) -2:1005:0:120:1 //Mute current channel: F9 (KeyDown) -2:1006:0:121:1 //Solo current channel: F10 (KeyDown) -2:1007:4:81:5 //Transpose +1: Alt+Q (KeyDown|KeyHold) -2:1008:4:65:5 //Transpose -1: Alt+A (KeyDown|KeyHold) -2:1009:6:81:5 //Transpose +12: Ctrl+Alt+Q (KeyDown|KeyHold) -2:1010:6:65:5 //Transpose -12: Ctrl+Alt+A (KeyDown|KeyHold) -2:1012:4:74:1 //Amplify selection: Alt+J (KeyDown) -2:1014:4:73:1 //Interpolate volume: Alt+I (KeyDown) -2:1015:4:88:1 //Interpolate effect: Alt+X (KeyDown) -2:1016:4:66:1 //Open effect visualizer: Alt+B (KeyDown) -2:1013:4:83:1 //Apply current instrument: Alt+S (KeyDown) -2:1660:4:69:1 //Grow selection: Alt+E (KeyDown) -2:1661:4:68:1 //Shrink selection: Alt+D (KeyDown) -2:1057:0:46:1 //Clear row: DELETE (KeyDown) -2:1058:0:110:1 //Clear field: NUM DECIMAL (KeyDown) -2:1664:1:190:1 //Clear field (IT Style): Shift+. (KeyDown) -2:1059:2:46:1 //Clear row and step: Ctrl+DELETE (KeyDown) -2:1060:2:110:1 //Clear field and step: Ctrl+NUM DECIMAL (KeyDown) -2:1665:3:190:1 //Clear field and step (IT Style): Shift+Ctrl+. (KeyDown) -2:1061:0:8:5 //Delete rows: BACKSPACE (KeyDown|KeyHold) -2:1377:2:8:5 //Delete all rows: Ctrl+BACKSPACE (KeyDown|KeyHold) -2:1378:0:45:5 //Insert Row: INSERT (KeyDown|KeyHold) -2:1379:2:45:1 //Insert All Rows: Ctrl+INSERT (KeyDown) -2:1055:0:109:5 //Previous pattern: NUM SUB (KeyDown|KeyHold) -2:1054:0:107:5 //Next pattern: NUM PLUS (KeyDown|KeyHold) - -//----( Pattern Context [bottom] - Note Col (3) )------------ -3:1064:0:90:1 //Base octave C: Z (KeyDown) -3:1065:0:83:1 //Base octave C#: S (KeyDown) -3:1066:0:88:1 //Base octave D: X (KeyDown) -3:1067:0:68:1 //Base octave D#: D (KeyDown) -3:1068:0:67:1 //Base octave E: C (KeyDown) -3:1069:0:86:1 //Base octave F: V (KeyDown) -3:1070:0:71:1 //Base octave F#: G (KeyDown) -3:1071:0:66:1 //Base octave G: B (KeyDown) -3:1072:0:72:1 //Base octave G#: H (KeyDown) -3:1073:0:78:1 //Base octave +1 A: N (KeyDown) -3:1074:0:74:1 //Base octave +1 A#: J (KeyDown) -3:1075:0:77:1 //Base octave +1 B: M (KeyDown) -3:1076:0:81:1 //Base octave +1 C: Q (KeyDown) -3:1077:0:50:1 //Base octave +1 C#: 2 (KeyDown) -3:1078:0:87:1 //Base octave +1 D: W (KeyDown) -3:1079:0:51:1 //Base octave +1 D#: 3 (KeyDown) -3:1080:0:69:1 //Base octave +1 E: E (KeyDown) -3:1081:0:82:1 //Base octave +1 F: R (KeyDown) -3:1082:0:53:1 //Base octave +1 F#: 5 (KeyDown) -3:1083:0:84:1 //Base octave +1 G: T (KeyDown) -3:1084:0:54:1 //Base octave +1 G#: 6 (KeyDown) -3:1085:0:89:1 //Base octave +2 A: Y (KeyDown) -3:1086:0:55:1 //Base octave +2 A#: 7 (KeyDown) -3:1087:0:85:1 //Base octave +2 B: U (KeyDown) -3:1088:0:73:1 //Base octave +2 C: I (KeyDown) -3:1089:0:57:1 //Base octave +2 C#: 9 (KeyDown) -3:1090:0:79:1 //Base octave +2 D: O (KeyDown) -3:1091:0:48:1 //Base octave +2 D#: 0 (KeyDown) -3:1092:0:80:1 //Base octave +2 E: P (KeyDown) -3:1212:0:96:1 //Set octave 0: NUM 0 (KeyDown) -3:1213:0:97:1 //Set octave 1: NUM 1 (KeyDown) -3:1214:0:98:1 //Set octave 2: NUM 2 (KeyDown) -3:1215:0:99:1 //Set octave 3: NUM 3 (KeyDown) -3:1216:0:52:1 //Set octave 4: 4 (KeyDown) -3:1216:0:100:1 //Set octave 4: NUM 4 (KeyDown) -3:1217:0:101:1 //Set octave 5: NUM 5 (KeyDown) -3:1218:0:102:1 //Set octave 6: NUM 6 (KeyDown) -3:1219:0:103:1 //Set octave 7: NUM 7 (KeyDown) -3:1220:0:104:1 //Set octave 8: NUM 8 (KeyDown) -3:1221:0:105:1 //Set octave 9: NUM 9 (KeyDown) -3:1316:1:16:1 //Chord Modifier: Shift (KeyDown) -3:1200:0:49:1 //Note cut: 1 (KeyDown) -3:1201:0:187:1 //Note off: = (KeyDown) -3:1667:1:49:1 //Note cut (don't remember instrument): Shift+1 (KeyDown) -3:1668:1:223:1 //Note off (don't remember instrument): Shift+` (KeyDown) - -//----( Pattern Context [bottom] - Ins Col (4) )------------ -4:1202:0:96:1 //Set instrument digit 0: NUM 0 (KeyDown) -4:1202:0:48:1 //Set instrument digit 0: 0 (KeyDown) -4:1203:0:97:1 //Set instrument digit 1: NUM 1 (KeyDown) -4:1203:0:49:1 //Set instrument digit 1: 1 (KeyDown) -4:1204:0:98:1 //Set instrument digit 2: NUM 2 (KeyDown) -4:1204:0:50:1 //Set instrument digit 2: 2 (KeyDown) -4:1205:0:99:1 //Set instrument digit 3: NUM 3 (KeyDown) -4:1205:0:51:1 //Set instrument digit 3: 3 (KeyDown) -4:1206:0:100:1 //Set instrument digit 4: NUM 4 (KeyDown) -4:1206:0:52:1 //Set instrument digit 4: 4 (KeyDown) -4:1207:0:101:1 //Set instrument digit 5: NUM 5 (KeyDown) -4:1207:0:53:1 //Set instrument digit 5: 5 (KeyDown) -4:1208:0:102:1 //Set instrument digit 6: NUM 6 (KeyDown) -4:1208:0:54:1 //Set instrument digit 6: 6 (KeyDown) -4:1209:0:103:1 //Set instrument digit 7: NUM 7 (KeyDown) -4:1209:0:55:1 //Set instrument digit 7: 7 (KeyDown) -4:1210:0:56:1 //Set instrument digit 8: 8 (KeyDown) -4:1210:0:104:1 //Set instrument digit 8: NUM 8 (KeyDown) -4:1211:0:105:1 //Set instrument digit 9: NUM 9 (KeyDown) -4:1211:0:57:1 //Set instrument digit 9: 9 (KeyDown) - -//----( Pattern Context [bottom] - Vol Col (5) )------------ -5:1222:0:48:1 //Set volume digit 0: 0 (KeyDown) -5:1222:0:96:1 //Set volume digit 0: NUM 0 (KeyDown) -5:1223:0:49:1 //Set volume digit 1: 1 (KeyDown) -5:1223:0:97:1 //Set volume digit 1: NUM 1 (KeyDown) -5:1224:0:50:1 //Set volume digit 2: 2 (KeyDown) -5:1224:0:98:1 //Set volume digit 2: NUM 2 (KeyDown) -5:1225:0:51:1 //Set volume digit 3: 3 (KeyDown) -5:1225:0:99:1 //Set volume digit 3: NUM 3 (KeyDown) -5:1226:0:52:1 //Set volume digit 4: 4 (KeyDown) -5:1226:0:100:1 //Set volume digit 4: NUM 4 (KeyDown) -5:1227:0:53:1 //Set volume digit 5: 5 (KeyDown) -5:1227:0:101:1 //Set volume digit 5: NUM 5 (KeyDown) -5:1228:0:54:1 //Set volume digit 6: 6 (KeyDown) -5:1228:0:102:1 //Set volume digit 6: NUM 6 (KeyDown) -5:1229:0:55:1 //Set volume digit 7: 7 (KeyDown) -5:1229:0:103:1 //Set volume digit 7: NUM 7 (KeyDown) -5:1230:0:56:1 //Set volume digit 8: 8 (KeyDown) -5:1230:0:104:1 //Set volume digit 8: NUM 8 (KeyDown) -5:1231:0:57:1 //Set volume digit 9: 9 (KeyDown) -5:1231:0:105:1 //Set volume digit 9: NUM 9 (KeyDown) -5:1232:0:86:1 //Vol command - volume: V (KeyDown) -5:1233:0:80:1 //Vol command - pan: P (KeyDown) -5:1234:0:67:1 //Vol command - vol slide up: C (KeyDown) -5:1235:0:68:1 //Vol command - vol slide down: D (KeyDown) -5:1236:0:65:1 //Vol command - vol fine slide up: A (KeyDown) -5:1237:0:66:1 //Vol command - vol fine slide down: B (KeyDown) -5:1238:0:85:1 //Vol command - vibrato speed: U (KeyDown) -5:1239:0:72:1 //Vol command - vibrato: H (KeyDown) -5:1240:0:76:1 //Vol command - XM pan left: L (KeyDown) -5:1241:0:82:1 //Vol command - XM pan right: R (KeyDown) -5:1242:0:71:1 //Vol command - Portamento: G (KeyDown) -5:1243:0:70:1 //Vol command - Portamento Up: F (KeyDown) -5:1244:0:69:1 //Vol command - Portamento Down: E (KeyDown) -5:1245:1:186:1 //Vol command - Velocity: Shift+; (KeyDown) -5:1246:0:79:1 //Vol command - Offset: O (KeyDown) - -//----( Pattern Context [bottom] - FX Col (6) )------------ -6:1294:0:220:1 //FX midi macro slide: \ (KeyDown) -6:1295:1:186:1 //FX pseudo-velocity (experimental): Shift+; (KeyDown) -6:1666:0:222:1 //FX parameter extension command: # (KeyDown) - -//----( Pattern Context [bottom] - Param Col (7) )------------ -7:1247:0:48:1 //FX Param digit 0: 0 (KeyDown) -7:1247:0:96:1 //FX Param digit 0: NUM 0 (KeyDown) -7:1248:0:49:1 //FX Param digit 1: 1 (KeyDown) -7:1248:0:97:1 //FX Param digit 1: NUM 1 (KeyDown) -7:1249:0:50:1 //FX Param digit 2: 2 (KeyDown) -7:1249:0:98:1 //FX Param digit 2: NUM 2 (KeyDown) -7:1250:0:51:1 //FX Param digit 3: 3 (KeyDown) -7:1250:0:99:1 //FX Param digit 3: NUM 3 (KeyDown) -7:1251:0:52:1 //FX Param digit 4: 4 (KeyDown) -7:1251:0:100:1 //FX Param digit 4: NUM 4 (KeyDown) -7:1252:0:53:1 //FX Param digit 5: 5 (KeyDown) -7:1252:0:101:1 //FX Param digit 5: NUM 5 (KeyDown) -7:1253:0:54:1 //FX Param digit 6: 6 (KeyDown) -7:1253:0:102:1 //FX Param digit 6: NUM 6 (KeyDown) -7:1254:0:55:1 //FX Param digit 7: 7 (KeyDown) -7:1254:0:103:1 //FX Param digit 7: NUM 7 (KeyDown) -7:1255:0:56:1 //FX Param digit 8: 8 (KeyDown) -7:1255:0:104:1 //FX Param digit 8: NUM 8 (KeyDown) -7:1256:0:57:1 //FX Param digit 9: 9 (KeyDown) -7:1256:0:105:1 //FX Param digit 9: NUM 9 (KeyDown) -7:1257:0:65:1 //FX Param digit A: A (KeyDown) -7:1258:0:66:1 //FX Param digit B: B (KeyDown) -7:1259:0:67:1 //FX Param digit C: C (KeyDown) -7:1260:0:68:1 //FX Param digit D: D (KeyDown) -7:1261:0:69:1 //FX Param digit E: E (KeyDown) -7:1262:0:70:1 //FX Param digit F: F (KeyDown) - -//----( Sample Context [bottom] (8) )------------ -8:1673:4:76:1 //Load a Sample: Alt+L (KeyDown) -8:1674:4:83:1 //Save Sample: Alt+S (KeyDown) -8:1675:4:78:1 //New Sample: Alt+N (KeyDown) -8:1380:2:84:1 //Trim sample around loop points: Ctrl+T (KeyDown) -8:1383:0:8:1 //Silence sample selection: BACKSPACE (KeyDown) -8:1384:3:78:1 //Normalise Sample: Shift+Ctrl+N (KeyDown) -8:1385:3:65:1 //Amplify Sample: Shift+Ctrl+A (KeyDown) -8:1381:3:82:1 //Reverse sample: Shift+Ctrl+R (KeyDown) -8:1382:0:46:1 //Delete sample selection: DELETE (KeyDown) -8:1386:0:107:1 //Zoom Out: NUM PLUS (KeyDown) -8:1387:0:109:1 //Zoom In: NUM SUB (KeyDown) - -//----( Instrument Context [bottom] (9) )------------ - -//----( Comments Context [bottom] (10) )------------ - -//----( Unknown Context (11) )------------ - -//----( Unknown Context (12) )------------ - -//----( Plugin GUI Context (13) )------------ - -//----( General Context [top] (14) )------------ - -//----( Pattern Context [top] (15) )------------ - -//----( Sample Context [top] (16) )------------ - -//----( Instrument Context [top] (17) )------------ - -//----( Comments Context [top] (18) )------------ Modified: trunk/OpenMPT/mptrack/misc_util.h =================================================================== --- trunk/OpenMPT/mptrack/misc_util.h 2009-09-21 20:03:46 UTC (rev 374) +++ trunk/OpenMPT/mptrack/misc_util.h 2009-09-22 17:07:04 UTC (rev 375) @@ -135,4 +135,30 @@ } } +// Convert a 0-terminated string to a space-padded string +template <size_t size> +void NullToSpaceString(char (&buffer)[size]) +{ + size_t pos = size; + while (pos-- > 0) + if (buffer[pos] == 0) + buffer[pos] = 32; + buffer[size - 1] = 0; +} +// Convert a space-padded string to a 0-terminated string +template <size_t size> +void SpaceToNullString(char (&buffer)[size]) +{ + // First, remove any Nulls + NullToSpaceString(buffer); + size_t pos = size; + while (pos-- > 0) + { + if (buffer[pos] == 32) + buffer[pos] = 0; + else if(buffer[pos] != 0) + break; + } + buffer[size - 1] = 0; +} #endif Modified: trunk/OpenMPT/soundlib/Load_med.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_med.cpp 2009-09-21 20:03:46 UTC (rev 374) +++ trunk/OpenMPT/soundlib/Load_med.cpp 2009-09-22 17:07:04 UTC (rev 375) @@ -673,7 +673,7 @@ Order.resize(nOrders++); for (UINT i=0; i<n; i++) { - WORD seqval = BigEndian(pmps->seq[i]); + WORD seqval = BigEndianW(pmps->seq[i]); if ((seqval < wNumBlocks) && (nOrders < MAX_ORDERS-1)) { Order[nOrders++] = (ORDERINDEX)seqval; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-09-24 15:24:42
|
Revision: 379 http://modplug.svn.sourceforge.net/modplug/?rev=379&view=rev Author: saga-games Date: 2009-09-24 15:24:32 +0000 (Thu, 24 Sep 2009) Log Message: ----------- [New] Can now import PSM16 files. [Fix] Pattern editor: If the current pattern is the last possible pattern in the sequence, no "next pattern" is displayed [Fix] Color Setup: When loading colour presets that have less colours are defined than required, the missing colours will be replaced by those from the "MPT" preset. [Fix] IT Specs: As the last order in an IT file has to be "---", any other order item got overwritten when saving IT files with 256 orders. As a consequence, the maximum order count has been reduced by one. Modified Paths: -------------- trunk/OpenMPT/mptrack/Draw_pat.cpp trunk/OpenMPT/mptrack/Moptions.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/mod_specifications.h Modified: trunk/OpenMPT/mptrack/Draw_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Draw_pat.cpp 2009-09-23 15:04:06 UTC (rev 378) +++ trunk/OpenMPT/mptrack/Draw_pat.cpp 2009-09-24 15:24:32 UTC (rev 379) @@ -616,6 +616,7 @@ const ORDERINDEX startOrder= static_cast<ORDERINDEX>(SendCtrlMessage(CTRLMSG_GETCURRENTORDER)); ORDERINDEX nNextOrder; nNextOrder = pSndFile->Order.GetNextOrderIgnoringSkips(startOrder); + if(nNextOrder == startOrder) nNextOrder = ORDERINDEX_INVALID; //Ignore skip items(+++) from sequence. const ORDERINDEX ordCount = pSndFile->Order.GetLength(); Modified: trunk/OpenMPT/mptrack/Moptions.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moptions.cpp 2009-09-23 15:04:06 UTC (rev 378) +++ trunk/OpenMPT/mptrack/Moptions.cpp 2009-09-24 15:24:32 UTC (rev 379) @@ -590,6 +590,8 @@ TCHAR sFilename[MAX_PATH]; strcpy(sFilename, dlg.GetPathName()); + // Ensure that all colours are reset (for outdated colour schemes) + OnPresetMPT(); for(int i = 0; i < MAX_MODCOLORS; i++) { TCHAR sKeyName[16]; Modified: trunk/OpenMPT/soundlib/Load_psm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-09-23 15:04:06 UTC (rev 378) +++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-09-24 15:24:32 UTC (rev 379) @@ -1,5 +1,5 @@ /* - * Purpose: Load new PSM (ProTracker Studio) modules + * Purpose: Load PSM16 and new PSM (ProTracker Studio) modules * Authors: Johannes Schultz * * This is partly based on http://www.shikadi.net/moddingwiki/ProTracker_Studio_Module @@ -7,11 +7,11 @@ * gave me a few clues. :) * * What's playing? - * - Epic Pinball - Perfect! (the old tunes in PSM16 format are not supported) + * - Epic Pinball - Perfect! (I don't have an old version with the PSM16 tunes to compare, though - some of them differ from the new PSM tunes) * - Extreme Pinball - Perfect! (subtunes included!) * - Jazz Jackrabbit - Perfect! * - One Must Fall! - Perfect! (it helped a lot to have the original MTM files...) - * - Silverball - Currently not supported (old PSM16 format) + * - Silverball - Seems to work (I don't have all tables so I can't compare) * - Sinaria - Seems to work (never played the game, so I can't really tell...) * * Effect conversion should be about right... @@ -23,7 +23,14 @@ #pragma pack(1) -struct PSMHEADER +//////////////////////////////////////////////////////////// +// +// New PSM support starts here. PSM16 structs are below. +// + + + +struct PSMNEWHEADER { DWORD formatID; // "PSM " (new format) DWORD fileSize; // Filesize - 12 @@ -98,6 +105,7 @@ // Portamento effect conversion (depending on format version) inline BYTE convert_psm_porta(BYTE param, bool bNewFormat) +//-------------------------------------------------------- { return ((bNewFormat) ? (param) : ((param < 4) ? (param | 0xF0) : (param >> 2))); } @@ -111,12 +119,16 @@ DWORD dwMemPos = 0; bool bNewFormat = false; // The game "Sinaria" uses a slightly modified PSM structure - ASSERT_CAN_READ(12); - PSMHEADER shdr; - memcpy(&shdr, lpStream, sizeof(PSMHEADER)); - if(LittleEndian(shdr.formatID) != 0x204d5350 // "PSM " - || LittleEndian(shdr.fileSize) != dwMemLength - 12 - || LittleEndian(shdr.fileInfoID) != 0x454C4946 // "FILE" + ASSERT_CAN_READ(sizeof(PSMNEWHEADER)); + PSMNEWHEADER *shdr = (PSMNEWHEADER *)lpStream; + + if(LittleEndian(shdr->formatID) == 0xFE4D5350) // "PSM\xFE" - PSM16 format + return ReadPSM16(lpStream, dwMemLength); + + // Check header + if(LittleEndian(shdr->formatID) != 0x204D5350 // "PSM " + || LittleEndian(shdr->fileSize) != dwMemLength - 12 + || LittleEndian(shdr->fileInfoID) != 0x454C4946 // "FILE" ) return false; // Yep, this seems to be a valid file. @@ -727,7 +739,6 @@ dwRowOffset += 2; } - } row_data += m_nChannels; @@ -791,3 +802,399 @@ #undef ASSERT_CAN_READ } + +//////////////////////////////// +// +// PSM16 support starts here. +// + +#pragma pack(1) + +struct PSM16HEADER +{ + DWORD formatID; // "PSM\xFE" (PSM16) + CHAR songName[59]; // Song title, padded with nulls + BYTE lineEnd; // $1A + BYTE songType; // Song Type bitfield + BYTE formatVersion; // $10 + BYTE patternVersion; // 0 or 1 + BYTE songSpeed; // + BYTE songTempo; // 32 ... 255 + BYTE masterVolume; // 0 ... 255 + WORD songLength; // 0 ... 255 (number of patterns to play in the song) + WORD songOrders; // 0 ... 255 (same as previous value as no subsongs are present) + WORD numPatterns; // 1 ... 255 + WORD numSamples; // 1 ... 255 + WORD numChannelsPlay; // 0 ... 32 (max. number of channels to play) + WORD numChannelsReal; // 0 ... 32 (max. number of channels to process) + DWORD orderOffset; + DWORD panOffset; + DWORD patOffset; + DWORD smpOffset; + DWORD commentsOffset; + DWORD patSize; // Size of all patterns + CHAR filler[40]; +}; + +struct PSM16SMPHEADER +{ + CHAR filename[13]; // null-terminated + CHAR name[24]; // dito + DWORD offset; // in file + DWORD memoffset; // not used + WORD sampleNumber; // 1 ... 255 + BYTE flags; // sample flag bitfield + DWORD length; // in bytes + DWORD loopStart; // in samples? + DWORD loopEnd; // in samples? + CHAR finetune; // 0 ... 15 (useless?) + BYTE volume; // default volume + WORD c2freq; +}; + +struct PSM16PATHEADER +{ + WORD size; // includes header bytes + BYTE numRows; // 1 ... 64 + BYTE numChans; // 1 ... 31 +}; + +#pragma pack() + + +bool CSoundFile::ReadPSM16(const LPCBYTE lpStream, const DWORD dwMemLength) +//----------------------------------------------------------------------- +{ + #define ASSERT_CAN_READ(x) \ + if( dwMemPos > dwMemLength || x > dwMemLength - dwMemPos ) return false; + + DWORD dwMemPos = 0; + + ASSERT_CAN_READ(sizeof(PSM16HEADER)); + PSM16HEADER *shdr = (PSM16HEADER *)lpStream; + + // Check header + if((LittleEndian(shdr->formatID) != 0xFE4D5350) // "PSM\xFE" + || (shdr->lineEnd != 0x1A) + || (shdr->formatVersion != 0x10 && shdr->formatVersion != 0x01) // why is this sometimes 0x01? + || (shdr->patternVersion != 0) // 255ch pattern version not supported (did anyone use this?) + || ((shdr->songType & 3) != 0) + || (min(shdr->numChannelsPlay, shdr->numChannelsReal) == 0) + ) return false; + + // Seems to be valid! + + m_nType = MOD_TYPE_S3M; + m_nChannels = max(shdr->numChannelsPlay, shdr->numChannelsReal); + m_nMasterVolume = shdr->masterVolume; + m_nDefaultGlobalVolume = 256; + m_nDefaultSpeed = shdr->songSpeed; + m_nDefaultTempo = shdr->songTempo; + + memset(m_szNames, 0, sizeof(m_szNames)); + memcpy(m_szNames[0], shdr->songName, 31); + m_szNames[0][31] = 0; + + // Read orders + dwMemPos = LittleEndian(shdr->orderOffset); + ASSERT_CAN_READ((DWORD)LittleEndianW(shdr->songOrders) + 2); + if(LittleEndian(shdr->orderOffset) > 4 && LittleEndian(*(DWORD *)(lpStream + dwMemPos - 4)) == 0x44524f50) // PORD + { + Order.ReadAsByte(lpStream + dwMemPos, LittleEndianW(shdr->songOrders), dwMemLength - dwMemPos); + } + + // Read pan positions + dwMemPos = LittleEndian(shdr->panOffset); + ASSERT_CAN_READ(32); + if(LittleEndian(shdr->panOffset) > 4 && LittleEndian(*(DWORD *)(lpStream + dwMemPos - 4)) == 0x4E415050) // PPAN + { + for(CHANNELINDEX i = 0; i < 32; i++) + { + ChnSettings[i].nPan = lpStream[dwMemPos + i] << 4; + ChnSettings[i].nVolume = 64; + ChnSettings[i].dwFlags = (i >= shdr->numChannelsPlay) ? CHN_MUTE : 0; + } + } + + // Read samples + dwMemPos = LittleEndian(shdr->smpOffset); + ASSERT_CAN_READ(0); + if(LittleEndian(shdr->smpOffset) > 4 && LittleEndian(*(DWORD *)(lpStream + dwMemPos - 4)) == 0x48415350) // PSAH + { + SAMPLEINDEX iSmpCount = 0; + m_nSamples = LittleEndianW(shdr->numSamples); + while(iSmpCount < LittleEndianW(shdr->numSamples)) + { + ASSERT_CAN_READ(sizeof(PSM16SMPHEADER)); + PSM16SMPHEADER *smphdr = (PSM16SMPHEADER *)(lpStream + dwMemPos); + dwMemPos += sizeof(PSM16SMPHEADER); + + SAMPLEINDEX iSmp = LittleEndianW(smphdr->sampleNumber); + m_nSamples = max(m_nSamples, iSmp); + + memcpy(m_szNames[iSmp], smphdr->name, 24); + m_szNames[iSmp][24] = 0; + memcpy(Samples[iSmp].filename, smphdr->filename, 13); + Samples[iSmp].filename[13] = 0; + + Samples[iSmp].nLength = LittleEndian(smphdr->length); + Samples[iSmp].nLoopStart = LittleEndian(smphdr->loopStart); + Samples[iSmp].nLoopEnd = LittleEndian(smphdr->loopEnd); + Samples[iSmp].nC5Speed = LittleEndianW(smphdr->c2freq); + Samples[iSmp].nVolume = smphdr->volume << 2; + Samples[iSmp].nGlobalVol = 256; + + UINT iSampleFormat = RS_PCM8S; + if(smphdr->flags & 0x04) // 16-Bit + { + Samples[iSmp].uFlags |= CHN_16BIT; + Samples[iSmp].nLength >>= 1; + iSampleFormat = RS_PCM16S; + } + if(smphdr->flags & 0x08) // Signed/Unsigned + { + if(Samples[iSmp].uFlags & CHN_16BIT) + iSampleFormat = RS_PCM16U; + else + iSampleFormat = RS_PCM8U; + } + if(smphdr->flags & 0x10) // Delta/Raw + { + if(Samples[iSmp].uFlags & CHN_16BIT) + iSampleFormat = RS_PCM16D; + else + iSampleFormat = RS_PCM8D; + } + if(smphdr->flags & 0x20) // Bidi Loop + { + Samples[iSmp].uFlags |= CHN_PINGPONGLOOP; + } + if(smphdr->flags & 0x80) // Loop + { + Samples[iSmp].uFlags |= CHN_LOOP; + } + if((smphdr->flags & 0x7F) == 0) + iSampleFormat = RS_PCM8D; + + ReadSample(&Samples[iSmp], iSampleFormat, reinterpret_cast<LPCSTR>(lpStream + LittleEndianW(smphdr->offset)), dwMemLength - LittleEndianW(smphdr->offset)); + + iSmpCount++; + } + } + + // Read patterns + dwMemPos = LittleEndian(shdr->patOffset); + ASSERT_CAN_READ(LittleEndian(shdr->patSize)); + if(LittleEndian(shdr->patOffset) > 4 && LittleEndian(*(DWORD *)(lpStream + dwMemPos - 4)) == 0x54415050) // PPAT + { + DWORD dwPatEndPos = LittleEndian(shdr->patOffset) + LittleEndian(shdr->patSize); + + for(PATTERNINDEX nPat = 0; nPat < LittleEndianW(shdr->numPatterns); nPat++) + { + ASSERT_CAN_READ(sizeof(PSM16PATHEADER)); + PSM16PATHEADER *phdr = (PSM16PATHEADER *)(lpStream + dwMemPos); + ASSERT_CAN_READ(LittleEndianW(phdr->size)); + + DWORD dwNextPattern = dwMemPos + ((LittleEndianW(phdr->size) + 15) & ~15); + dwMemPos += sizeof(PSM16PATHEADER); + + if(Patterns.Insert(nPat, phdr->numRows)) + { + CString s; + s.Format(TEXT("Allocating patterns failed starting from pattern %u"), nPat); + MessageBox(NULL, s, TEXT("OpenMPT PSM16 import"), MB_ICONERROR); + break; + } + + MODCOMMAND *row_data; + ROWINDEX iRow = 0; + + while(dwMemPos < dwNextPattern && iRow < phdr->numRows) + { + ASSERT_CAN_READ(1); + BYTE bChnFlag = lpStream[dwMemPos++]; + if(bChnFlag == 0) + { + iRow++; + continue; + } + + row_data = Patterns[nPat] + iRow * m_nChannels + min(bChnFlag & 0x1F, m_nChannels - 1); + + if(bChnFlag & 0x80) + { + // note + instr present + ASSERT_CAN_READ(2); + row_data->note = lpStream[dwMemPos++] + 37; + row_data->instr = lpStream[dwMemPos++]; + } + if(bChnFlag & 0x40) + { + // volume present + ASSERT_CAN_READ(1); + row_data->volcmd = VOLCMD_VOLUME; + row_data->vol = lpStream[dwMemPos++]; + } + if(bChnFlag & 0x20) + { + // effect present - convert + ASSERT_CAN_READ(2); + BYTE command = lpStream[dwMemPos++], param = lpStream[dwMemPos++]; + + switch(command) + { + // Volslides + case 0x01: // fine volslide up + command = CMD_VOLUMESLIDE; + param = (param << 4) | 0x0F; + break; + case 0x02: // volslide up + command = CMD_VOLUMESLIDE; + param = (param << 4) & 0xF0; + break; + case 0x03: // fine voslide down + command = CMD_VOLUMESLIDE; + param = 0xF0 | param; + break; + case 0x04: // volslide down + command = CMD_VOLUMESLIDE; + param = param & 0x0F; + break; + + // Portamento + case 0x0A: // fine portamento up + command = CMD_PORTAMENTOUP; + param |= 0xF0; + break; + case 0x0B: // portamento down + command = CMD_PORTAMENTOUP; + break; + case 0x0C: // fine portamento down + command = CMD_PORTAMENTODOWN; + param |= 0xF0; + break; + case 0x0D: // portamento down + command = CMD_PORTAMENTODOWN; + break; + case 0x0E: // tone portamento + command = CMD_TONEPORTAMENTO; + break; + case 0x0F: // glissando control + command = CMD_S3MCMDEX; + param |= 0x10; + break; + case 0x10: // tone portamento + volslide up + command = CMD_TONEPORTAVOL; + param <<= 4; + break; + case 0x11: // tone portamento + volslide down + command = CMD_TONEPORTAVOL; + param &= 0x0F; + break; + + // Vibrato + case 0x14: // vibrato + command = CMD_VIBRATO; + break; + case 0x15: // vibrato waveform + command = CMD_S3MCMDEX; + param |= 0x30; + break; + case 0x16: // vibrato + volslide up + command = CMD_VIBRATOVOL; + param <<= 4; + break; + case 0x17: // vibrato + volslide down + command = CMD_VIBRATOVOL; + param &= 0x0F; + break; + + // Tremolo + case 0x1E: // tremolo + command = CMD_TREMOLO; + break; + case 0x1F: // tremolo waveform + command = CMD_S3MCMDEX; + param |= 0x40; + break; + + // Sample commands + case 0x28: // 3-byte offset - we only support the middle byte. + ASSERT_CAN_READ(2); + command = CMD_OFFSET; + param = lpStream[dwMemPos++]; + dwMemPos++; + break; + case 0x29: // retrigger + command = CMD_RETRIG; + param &= 0x0F; + break; + case 0x2A: // note cut + command = CMD_S3MCMDEX; + param |= 0xC0; + break; + case 0x2B: // note delay + command = CMD_S3MCMDEX; + param |= 0xD0; + break; + + // Position change + case 0x32: // position jump + command = CMD_POSITIONJUMP; + break; + case 0x33: // pattern break + command = CMD_PATTERNBREAK; + break; + case 0x34: // loop pattern + command = CMD_S3MCMDEX; + param |= 0xB0; + break; + case 0x35: // pattern delay + command = CMD_S3MCMDEX; + param |= 0xE0; + break; + + // speed change + case 0x3C: // set speed + command = CMD_SPEED; + break; + case 0x3D: // set tempo + command = CMD_TEMPO; + break; + + // misc commands + case 0x46: // arpeggio + command = CMD_ARPEGGIO; + break; + case 0x47: // set finetune + command = CMD_S3MCMDEX; + param |= 0x20; + break; + case 0x48: // set balance (panning?) + command = CMD_PANNING8; + param = (param << 4) + 8; + break; + + default: + command = CMD_NONE; + break; + } + + row_data->command = command; + row_data->param = param; + } + } + // Pattern break for short patterns (so saving the modules as S3M won't break it) + if(phdr->numRows != 64) + TryWriteEffect(nPat, phdr->numRows - 1, CMD_PATTERNBREAK, 0, false, CHANNELINDEX_INVALID, false, false); + + dwMemPos = dwNextPattern; + if(dwMemPos > dwPatEndPos) break; + } + } + + return true; + + #undef ASSERT_CAN_READ + +} Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-09-23 15:04:06 UTC (rev 378) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-09-24 15:24:32 UTC (rev 379) @@ -698,6 +698,7 @@ bool ReadAMF(LPCBYTE lpStream, const DWORD dwMemLength); bool ReadMT2(LPCBYTE lpStream, DWORD dwMemLength); bool ReadPSM(LPCBYTE lpStream, DWORD dwMemLength); + bool ReadPSM16(LPCBYTE lpStream, DWORD dwMemLength); bool ReadJ2B(LPCBYTE lpStream, DWORD dwMemLength); bool ReadUMX(LPCBYTE lpStream, DWORD dwMemLength); bool ReadMO3(LPCBYTE lpStream, const DWORD dwMemLength); Modified: trunk/OpenMPT/soundlib/mod_specifications.h =================================================================== --- trunk/OpenMPT/soundlib/mod_specifications.h 2009-09-23 15:04:06 UTC (rev 378) +++ trunk/OpenMPT/soundlib/mod_specifications.h 2009-09-24 15:24:32 UTC (rev 379) @@ -286,7 +286,7 @@ true, //Has noteoff. true, //Has notefade. 240, //Pattern max. - 256, //Order max. + 255, //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. |
From: <sag...@us...> - 2009-09-29 22:30:25
|
Revision: 382 http://modplug.svn.sourceforge.net/modplug/?rev=382&view=rev Author: saga-games Date: 2009-09-29 22:30:10 +0000 (Tue, 29 Sep 2009) Log Message: ----------- [Imp] Mod Conversion: Detect and fix patterns with Bxx effect properly when merging sequences [Fix] Pattern Editor: Entering Note Fade notes didn't work the "old style" way. [Ref] Some minor code cleanup Modified Paths: -------------- trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/soundlib/Load_gdm.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/patternContainer.cpp trunk/OpenMPT/soundlib/patternContainer.h Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-29 12:43:52 UTC (rev 381) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-29 22:30:10 UTC (rev 382) @@ -104,11 +104,22 @@ // Merge multiple sequences m_SndFile.Order.SetSequence(0); m_SndFile.Order.resize(m_SndFile.Order.GetLengthTailTrimmed()); - SEQUENCEINDEX removedSequences = 0; + SEQUENCEINDEX removedSequences = 0; // sequence count + vector <SEQUENCEINDEX> patternsFixed; // pattern fixed by other sequence already? + patternsFixed.resize(m_SndFile.Patterns.Size(), SEQUENCEINDEX_INVALID); + // Set up vector + for(ORDERINDEX nOrd = 0; nOrd < m_SndFile.Order.GetLengthTailTrimmed(); nOrd++) + { + PATTERNINDEX nPat = m_SndFile.Order[nOrd]; + if(!m_SndFile.Patterns.IsValidPat(nPat)) continue; + patternsFixed[nPat] = 0; + } + while(m_SndFile.Order.GetNumSequences() > 1) { removedSequences++; - if(m_SndFile.Order.GetLengthTailTrimmed() + 1 + m_SndFile.Order.GetSequence(1).GetLengthTailTrimmed() > m_SndFile.GetModSpecifications(nNewType).ordersMax) + const ORDERINDEX nFirstOrder = m_SndFile.Order.GetLengthTailTrimmed() + 1; // +1 for separator item + if(nFirstOrder + m_SndFile.Order.GetSequence(1).GetLengthTailTrimmed() > m_SndFile.GetModSpecifications(nNewType).ordersMax) { wsprintf(s, "WARNING: Cannot merge Sequence %d (too long!)\n", removedSequences); AddToLog(s); @@ -118,7 +129,43 @@ m_SndFile.Order.Append(m_SndFile.Order.GetInvalidPatIndex()); // Separator item for(ORDERINDEX nOrd = 0; nOrd < m_SndFile.Order.GetSequence(1).GetLengthTailTrimmed(); nOrd++) { - m_SndFile.Order.Append(m_SndFile.Order.GetSequence(1)[nOrd]); + PATTERNINDEX nPat = m_SndFile.Order.GetSequence(1)[nOrd]; + m_SndFile.Order.Append(nPat); + + // Try to fix patterns (Bxx commands) + if(!m_SndFile.Patterns.IsValidPat(nPat)) continue; + + MODCOMMAND *m = m_SndFile.Patterns[nPat]; + for (UINT len = 0; len < m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; m++, len++) + { + if(m->command == CMD_POSITIONJUMP) + { + if(patternsFixed[nPat] != SEQUENCEINDEX_INVALID && patternsFixed[nPat] != removedSequences) + { + // Oops, some other sequence uses this pattern already. + const PATTERNINDEX nNewPat = m_SndFile.Patterns.Insert(m_SndFile.PatternSize[nPat]); + if(nNewPat != SEQUENCEINDEX_INVALID) + { + // could create new pattern - copy data over and continue from here. + m_SndFile.Order[nFirstOrder + nOrd] = nNewPat; + MODCOMMAND *pSrc = m_SndFile.Patterns[nPat]; + MODCOMMAND *pDest = m_SndFile.Patterns[nNewPat]; + memcpy(pDest, pSrc, m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels * sizeof(MODCOMMAND)); + m = pDest + len; + patternsFixed.resize(max(nNewPat + 1, patternsFixed.size()), SEQUENCEINDEX_INVALID); + nPat = nNewPat; + } else + { + // cannot create new pattern: notify the user + wsprintf(s, "CONFLICT: Pattern break commands in Pattern %d might be broken since it has been used in several sequences!", nPat); + AddToLog(s); + } + } + m->param += nFirstOrder; + patternsFixed[nPat] = removedSequences; + } + } + } m_SndFile.Order.RemoveSequence(1); } Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-29 12:43:52 UTC (rev 381) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-29 22:30:10 UTC (rev 382) @@ -4180,7 +4180,7 @@ } // -- old style note cut/off: erase instrument number - if (oldStyle && ((p->note==NOTE_NOTECUT) || (p->note==NOTE_KEYOFF))) { + if (oldStyle && ((p->note == NOTE_NOTECUT) || (p->note == NOTE_KEYOFF) || (p->note == NOTE_FADE))) { p->instr=0; } Modified: trunk/OpenMPT/soundlib/Load_gdm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_gdm.cpp 2009-09-29 12:43:52 UTC (rev 381) +++ trunk/OpenMPT/soundlib/Load_gdm.cpp 2009-09-29 22:30:10 UTC (rev 382) @@ -96,7 +96,7 @@ // read channel pan map... 0...15 = channel panning, 16 = surround channel, 255 = channel does not exist m_nChannels = 32; - for(int i = 0; i < 32; i++) + for(CHANNELINDEX i = 0; i < 32; i++) { if(pHeader->PanMap[i] < 16) { Modified: trunk/OpenMPT/soundlib/Load_psm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-09-29 12:43:52 UTC (rev 381) +++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-09-29 22:30:10 UTC (rev 382) @@ -847,7 +847,7 @@ DWORD length; // in bytes DWORD loopStart; // in samples? DWORD loopEnd; // in samples? - CHAR finetune; // 0 ... 15 (useless?) + CHAR finetune; // 0 ... 15 (useless? also, why is this almost always 70?) BYTE volume; // default volume WORD c2freq; }; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-09-29 12:43:52 UTC (rev 381) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-09-29 22:30:10 UTC (rev 382) @@ -1045,10 +1045,10 @@ } -UINT CSoundFile::GetNumPatterns() const +ORDERINDEX CSoundFile::GetNumPatterns() const //------------------------------------- { - UINT i = 0; + ORDERINDEX i = 0; while ((i < Order.size()) && (Order[i] < Order.GetInvalidPatIndex())) i++; return i; } Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-09-29 12:43:52 UTC (rev 381) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-09-29 22:30:10 UTC (rev 382) @@ -623,9 +623,9 @@ BOOL SetMasterVolume(UINT vol, BOOL bAdjustAGC=FALSE); UINT GetMasterVolume() const { return m_nMasterVolume; } - UINT GetNumPatterns() const; - UINT GetNumInstruments() const {return m_nInstruments;} - UINT GetNumSamples() const { return m_nSamples; } + ORDERINDEX GetNumPatterns() const; + INSTRUMENTINDEX GetNumInstruments() const {return m_nInstruments;} + SAMPLEINDEX GetNumSamples() const { return m_nSamples; } UINT GetCurrentPos() const; UINT GetCurrentPattern() const { return m_nPattern; } ORDERINDEX GetCurrentOrder() const { return static_cast<ORDERINDEX>(m_nCurrentPattern); } Modified: trunk/OpenMPT/soundlib/patternContainer.cpp =================================================================== --- trunk/OpenMPT/soundlib/patternContainer.cpp 2009-09-29 12:43:52 UTC (rev 381) +++ trunk/OpenMPT/soundlib/patternContainer.cpp 2009-09-29 22:30:10 UTC (rev 382) @@ -5,14 +5,14 @@ #include "../mptrack/serialization_utils.h" #include "../mptrack/version.h" -int CPatternContainer::Insert(const ROWINDEX rows) +PATTERNINDEX CPatternContainer::Insert(const ROWINDEX rows) //--------------------------------------------- { PATTERNINDEX i = 0; for(i = 0; i<m_Patterns.size(); i++) if(!m_Patterns[i]) break; if(Insert(i, rows)) - return -1; + return PATTERNINDEX_INVALID; else return i; } Modified: trunk/OpenMPT/soundlib/patternContainer.h =================================================================== --- trunk/OpenMPT/soundlib/patternContainer.h 2009-09-29 12:43:52 UTC (rev 381) +++ trunk/OpenMPT/soundlib/patternContainer.h 2009-09-29 22:30:10 UTC (rev 382) @@ -38,9 +38,9 @@ //ignoring request. bool Insert(const PATTERNINDEX index, const ROWINDEX rows); - //Insert pattern to position with the lowest index, and return that index, -1 + //Insert pattern to position with the lowest index, and return that index, PATTERNINDEX_INVALID //on failure. - int Insert(const ROWINDEX rows); + PATTERNINDEX Insert(const ROWINDEX rows); //Remove pattern from given position. Currently it actually makes the pattern //'invisible' - the pattern data is cleared but the actual pattern object won't get removed. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-10-04 12:50:26
|
Revision: 385 http://modplug.svn.sourceforge.net/modplug/?rev=385&view=rev Author: saga-games Date: 2009-10-04 12:50:16 +0000 (Sun, 04 Oct 2009) Log Message: ----------- [Imp] Treeview: Double-clicking order items and pattern items should work now, dragondrop is not fully functional yet. [Mod] Updated DE_jojo.mkb (Reset Channel shortcut, Note Cut / Off / Fade are now "old style". [Mod] Pattern editor: It is impossible to enter something into the voluem column in mod format now. [Ref] More refactoring (not much). Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_pat.cpp trunk/OpenMPT/mptrack/Ctrl_pat.h trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/mptrack/View_tre.h trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-10-02 15:49:41 UTC (rev 384) +++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-10-04 12:50:16 UTC (rev 385) @@ -337,7 +337,8 @@ } - } else { + } else + { UINT nmax = m_pSndFile->m_nSamples; while ((nmax > 1) && (m_pSndFile->Samples[nmax].pSample == NULL) && (!m_pSndFile->m_szNames[nmax][0])) nmax--; for (UINT i=1; i<=nmax; i++) if ((m_pSndFile->m_szNames[i][0]) || (m_pSndFile->Samples[i].pSample)) { @@ -413,7 +414,7 @@ break; case CTRLMSG_SETCURRENTPATTERN: - SetCurrentPattern(lParam); + SetCurrentPattern((PATTERNINDEX)lParam); break; case CTRLMSG_SETCURRENTORDER: @@ -535,10 +536,10 @@ } -void CCtrlPatterns::SetCurrentPattern(UINT nPat) -//---------------------------------------------- +void CCtrlPatterns::SetCurrentPattern(PATTERNINDEX nPat) +//------------------------------------------------------ { - SendViewMessage(VIEWMSG_SETCURRENTPATTERN, nPat); + SendViewMessage(VIEWMSG_SETCURRENTPATTERN, (LPARAM)nPat); } @@ -576,10 +577,7 @@ void CCtrlPatterns::OnActivatePage(LPARAM lParam) //----------------------------------------------- { - CModDoc *pModDoc = GetDocument(); - CSoundFile* pSndFile = pModDoc ? pModDoc->GetSoundFile() : NULL; - - if ((pModDoc) && (m_pParent)) + if ((m_pModDoc) && (m_pParent)) { int nIns = m_pParent->GetInstrumentChange(); if (nIns > 0) @@ -588,30 +586,37 @@ } m_pParent->InstrumentChanged(-1); } - if ((lParam >= 0) && (lParam < m_pSndFile->Patterns.Size())) + if (!(lParam & 0x8000) && m_pSndFile) { - if (pSndFile) + // Pattern item + PATTERNINDEX nPat = (PATTERNINDEX)(lParam & 0x7FFF); + if(m_pSndFile->Patterns.IsValidIndex(nPat)) { - for (ORDERINDEX i=0; i<pSndFile->Order.size(); i++) + for (SEQUENCEINDEX nSeq = 0; nSeq < m_pSndFile->Order.GetNumSequences(); nSeq++) { - if (pSndFile->Order[i] == (UINT)lParam) + for (ORDERINDEX nOrd = 0; nOrd < m_pSndFile->Order.GetSequence(nSeq).GetLengthTailTrimmed(); nOrd++) { - m_OrderList.SetCurSel(i, TRUE); - break; + if (m_pSndFile->Order.GetSequence(nSeq)[nOrd] == nPat) + { + m_OrderList.SelectSequence(nSeq); + m_OrderList.SetCurSel(nOrd, true); + break; + } } - if (pSndFile->Order[i] == pSndFile->Order.GetInvalidPatIndex()) break; } } - SetCurrentPattern(lParam); + SetCurrentPattern(nPat); } - else if ((lParam >= 0x8000) && (lParam < int(pSndFile->Order.size()) + 0x8000)) + else if ((lParam & 0x8000) && m_pSndFile) { - if (pSndFile) + // Order item + ORDERINDEX nOrd = (ORDERINDEX)(lParam & 0x7FFF); + SEQUENCEINDEX nSeq = (SEQUENCEINDEX)(lParam >> 16); + if((nSeq < m_pSndFile->Order.GetNumSequences()) && (nOrd < m_pSndFile->Order.GetSequence(nSeq).size())) { - lParam &= 0x7FFF; - m_OrderList.OnSelectSequence(pSndFile->Order.GetCurrentSequenceIndex()); // new sequence already set in view_tre.cpp, GetModItem() - m_OrderList.SetCurSel((ORDERINDEX)lParam); - SetCurrentPattern(pSndFile->Order[lParam]); + m_OrderList.SelectSequence(nSeq); + m_OrderList.SetCurSel(nOrd); + SetCurrentPattern(m_pSndFile->Order[nOrd]); } } if (m_hWndView) Modified: trunk/OpenMPT/mptrack/Ctrl_pat.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-10-02 15:49:41 UTC (rev 384) +++ trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-10-04 12:50:16 UTC (rev 385) @@ -81,6 +81,9 @@ // is not interpreted to be in margins regardless of the margin value. bool IsOrderInMargins(int order, int startOrder); + // Set given sqeuence and update orderlist display. + void SelectSequence(const SEQUENCEINDEX nSeq); + public: //{{AFX_VIRTUAL(COrderList) virtual BOOL PreTranslateMessage(MSG *pMsg); @@ -164,7 +167,7 @@ LONG* GetSplitPosRef() {return &CMainFrame::glPatternWindowHeight;} //rewbs.varWindowSize public: - void SetCurrentPattern(UINT nPat); + void SetCurrentPattern(PATTERNINDEX nPat); BOOL SetCurrentInstrument(UINT nIns); BOOL GetFollowSong() { return IsDlgButtonChecked(IDC_PATTERN_FOLLOWSONG); } BOOL GetLoopPattern() {return IsDlgButtonChecked(IDC_PATTERN_LOOP);} Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-10-02 15:49:41 UTC (rev 384) +++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-10-04 12:50:16 UTC (rev 385) @@ -786,37 +786,7 @@ void COrderList::OnSelectSequence(UINT nid) //----------------------------------------- { - BEGIN_CRITICAL(); - CMainFrame::GetMainFrame()->ResetNotificationBuffer(); - const SEQUENCEINDEX nId = static_cast<SEQUENCEINDEX>(nid - ID_SEQUENCE_ITEM); - CSoundFile& rSf = *m_pModDoc->GetSoundFile(); - if (nId == MAX_SEQUENCES + 1) - { - CString strParam; strParam.Format(TEXT("%u: %s"), rSf.Order.GetCurrentSequenceIndex(), rSf.Order.m_sName); - CString str; - AfxFormatString1(str, IDS_CONFIRM_SEQUENCE_DELETE, strParam); - if (AfxMessageBox(str, MB_YESNO | MB_ICONQUESTION) == IDYES) - rSf.Order.RemoveSequence(); - else - { - END_CRITICAL(); - return; - } - } - else if (nId == MAX_SEQUENCES) - rSf.Order.AddSequence(); - else if (nId < rSf.Order.GetNumSequences()) - rSf.Order.SetSequence(nId); - ORDERINDEX nPosCandidate = rSf.Order.GetLengthTailTrimmed() - 1; - SetCurSel(min(m_nScrollPos, nPosCandidate), true, false, true); - if (m_pParent) - m_pParent->SetCurrentPattern(rSf.Order[m_nScrollPos]); - - UpdateScrollInfo(); - END_CRITICAL(); - UpdateView(HINT_MODSEQUENCE); - m_pModDoc->SetModified(); - m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this); + SelectSequence(static_cast<SEQUENCEINDEX>(nid - ID_SEQUENCE_ITEM)); } @@ -1168,3 +1138,38 @@ m_nOrderlistMargins = static_cast<BYTE>(i); return GetMargins(); } + +void COrderList::SelectSequence(const SEQUENCEINDEX nSeq) +//------------------------------------------------------- +{ + BEGIN_CRITICAL(); + CMainFrame::GetMainFrame()->ResetNotificationBuffer(); + CSoundFile& rSf = *m_pModDoc->GetSoundFile(); + if (nSeq == MAX_SEQUENCES + 1) + { + CString strParam; strParam.Format(TEXT("%u: %s"), rSf.Order.GetCurrentSequenceIndex(), rSf.Order.m_sName); + CString str; + AfxFormatString1(str, IDS_CONFIRM_SEQUENCE_DELETE, strParam); + if (AfxMessageBox(str, MB_YESNO | MB_ICONQUESTION) == IDYES) + rSf.Order.RemoveSequence(); + else + { + END_CRITICAL(); + return; + } + } + else if (nSeq == MAX_SEQUENCES) + rSf.Order.AddSequence(); + else if (nSeq < rSf.Order.GetNumSequences()) + rSf.Order.SetSequence(nSeq); + ORDERINDEX nPosCandidate = rSf.Order.GetLengthTailTrimmed() - 1; + SetCurSel(min(m_nScrollPos, nPosCandidate), true, false, true); + if (m_pParent) + m_pParent->SetCurrentPattern(rSf.Order[m_nScrollPos]); + + UpdateScrollInfo(); + END_CRITICAL(); + UpdateView(HINT_MODSEQUENCE); + m_pModDoc->SetModified(); + m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this); +} Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-10-02 15:49:41 UTC (rev 384) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-10-04 12:50:16 UTC (rev 385) @@ -242,7 +242,7 @@ BOOL IsChildSample(UINT nIns, UINT nSmp) const; UINT FindSampleParent(UINT nSmp) const; UINT FindInstrumentChild(UINT nIns) const; - bool MoveOrder(UINT nSourceNdx, UINT nDestNdx, bool bUpdate = true, bool bCopy = false); + bool MoveOrder(ORDERINDEX nSourceNdx, ORDERINDEX nDestNdx, bool bUpdate = true, bool bCopy = false); BOOL ExpandPattern(PATTERNINDEX nPattern); BOOL ShrinkPattern(PATTERNINDEX nPattern); BOOL CopyPattern(PATTERNINDEX nPattern, DWORD dwBeginSel, DWORD dwEndSel); Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-02 15:49:41 UTC (rev 384) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-04 12:50:16 UTC (rev 385) @@ -1022,13 +1022,18 @@ vector<MODCOMMAND*> pPatterns(maxPatIndex, NULL); vector<BOOL> bPatUsed(maxPatIndex, false); - const ORDERINDEX nLengthSub0 = m_SndFile.Order.GetLengthFirstEmpty(); - const ORDERINDEX nLengthUsed = m_SndFile.Order.GetLengthTailTrimmed(); + bool bSubtunesDetected = false; + // detect subtunes (separated by "---") + for(SEQUENCEINDEX nSeq = 0; nSeq < m_SndFile.Order.GetNumSequences(); nSeq++) + { + if(m_SndFile.Order.GetSequence(nSeq).GetLengthFirstEmpty() != m_SndFile.Order.GetSequence(nSeq).GetLengthTailTrimmed()) + bSubtunesDetected = true; + } // Flag to tell whether keeping sequence items which are after the first empty('---') order. bool bKeepSubSequences = false; - if(nLengthUsed != nLengthSub0) + if(bSubtunesDetected) { // There are used sequence items after first '---'; ask user whether to remove those. if (CMainFrame::GetMainFrame()->MessageBox( _TEXT("Do you want to remove sequence items which are after the first '---' item?"), @@ -2009,8 +2014,8 @@ } -bool CModDoc::MoveOrder(UINT nSourceNdx, UINT nDestNdx, bool bUpdate, bool bCopy) -//------------------------------------------------------------------------------- +bool CModDoc::MoveOrder(ORDERINDEX nSourceNdx, ORDERINDEX nDestNdx, bool bUpdate, bool bCopy) +//------------------------------------------------------------------------------------------- { if ((nSourceNdx >= m_SndFile.Order.size()) || (nDestNdx >= m_SndFile.Order.size())) return false; if (nDestNdx >= m_SndFile.GetModSpecifications().ordersMax) return false; Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-10-02 15:49:41 UTC (rev 384) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-10-04 12:50:16 UTC (rev 385) @@ -3707,6 +3707,7 @@ { CSoundFile *pSndFile = pModDoc->GetSoundFile(); + if(pSndFile->m_nType & MOD_TYPE_MOD) return; // no volume column PrepareUndo(m_dwBeginSel, m_dwEndSel); @@ -3745,7 +3746,7 @@ case kcSetVolumeITVelocity: if (pSndFile->m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) volcmd = VOLCMD_VELOCITY; break; //rewbs.velocity case kcSetVolumeITOffset: if (pSndFile->m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) volcmd = VOLCMD_OFFSET; break; //rewbs.volOff } - if ((pSndFile->m_nType & MOD_TYPE_MOD) && (volcmd > VOLCMD_PANNING)) volcmd = vol = 0; + //if ((pSndFile->m_nType & MOD_TYPE_MOD) && (volcmd > VOLCMD_PANNING)) volcmd = vol = 0; UINT max = 64; if (volcmd > VOLCMD_PANNING) Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2009-10-02 15:49:41 UTC (rev 384) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2009-10-04 12:50:16 UTC (rev 385) @@ -6,7 +6,6 @@ #include "dlsbank.h" #include "dlg_misc.h" #include "vstplug.h" -#include ".\view_tre.h" #ifndef TVS_SINGLEEXPAND #define TVS_SINGLEEXPAND 0x400 @@ -704,6 +703,8 @@ pInfo->tiOrders.resize(pSndFile->Order.GetNumSequences()); } + // TODO what to do when seq count changed from 2 to 1 or from 1 to 2? + /* // number of sequences changed: wipe tree first (is this necessary?) if(pInfo->tiOrders.size() != pSndFile->Order.GetNumSequences()) { @@ -728,11 +729,14 @@ if(pSndFile->Order.GetNumSequences() > 1) { // more than one sequence -> add folder + CString sSeqName = pSndFile->Order.GetSequence(nSeq).m_sName; + if(sSeqName.IsEmpty()) sSeqName.Format("Sequence %d", nSeq); if(pInfo->tiSequences[nSeq] == NULL) { - CString sSeqName = pSndFile->Order.GetSequence(nSeq).m_sName; - if(sSeqName.IsEmpty()) sSeqName.Format("Sequence %d", nSeq); pInfo->tiSequences[nSeq] = InsertItem(sSeqName, IMAGE_FOLDER, IMAGE_FOLDER, pInfo->hOrders, TVI_LAST); + } else + { + } hAncestorNode = pInfo->tiSequences[nSeq]; } @@ -861,7 +865,7 @@ { if (iSmp <= pSndFile->m_nSamples) { - BOOL bSamplePresent = (pSndFile->Samples[iSmp].pSample) ? TRUE : FALSE; + bool bSamplePresent = (pSndFile->Samples[iSmp].pSample) ? true : false; UINT nImage = (bSamplePresent) ? IMAGE_SAMPLES : IMAGE_NOSAMPLE; wsprintf(s, "%3d: %s", iSmp, pSndFile->m_szNames[iSmp]); if (!pInfo->tiSamples[iSmp]) @@ -948,7 +952,7 @@ } -DWORD CModTree::GetModItem(HTREEITEM hItem) +uint64 CModTree::GetModItem(HTREEITEM hItem) //----------------------------------------- { LPARAM lParam; @@ -1025,8 +1029,8 @@ if (hItem == pSong->hSamples) return MODITEM_HDR_SAMPLES; if (hItem == pSong->hInstruments) return MODITEM_HDR_INSTRUMENTS; if (hItem == pSong->hComments) return MODITEM_COMMENTS; - // Order List? (either "order list" or "sequence x" item as parent) - if ((hItemParent == pSong->hOrders && pSong->tiSequences.size() == 1) || (hItemParentParent == pSong->hOrders)) + // Order List or Sequence item? + if ((hItemParent == pSong->hOrders) || (hItemParentParent == pSong->hOrders)) { // find sequence this item belongs to for(SEQUENCEINDEX nSeq = 0; nSeq < pSong->tiOrders.size(); nSeq++) @@ -1036,16 +1040,10 @@ { if (hItem == pSong->tiOrders[nSeq][nOrd]) { - if(pSong->pModDoc->GetSoundFile() != nullptr) - { - pSong->pModDoc->GetSoundFile()->Order.SetSequence(nSeq); - // TODO this is buggy - //OnSelectSequence must be called? Or send a message? - } - //if(nSeq != pSong->nSeqSel) // sequence change - // return (MODITEM_ORDER_SEQUENCE | (nOrd << 16)); - //else // same sequence - return (MODITEM_ORDER | (nOrd << 16)); + return (MODITEM_ORDER | (nOrd << 16) | (((uint64)nSeq) << 32)); + } else if(hItem == pSong->tiSequences[nSeq]) + { + return (MODITEM_SEQUENCE | (nSeq << 16)); } } } @@ -1111,11 +1109,11 @@ { if (hItem) { - DWORD dwItemType = GetModItem(hItem); - DWORD dwItem = dwItemType >> 16; + uint64 qwItemType = GetModItem(hItem); + DWORD dwItem = (DWORD)(qwItemType >> 16); PMODTREEDOCINFO pInfo = DocInfo[m_nDocNdx]; CModDoc *pModDoc = (pInfo) ? pInfo->pModDoc : NULL; - switch(dwItemType & 0xFFFF) + switch(qwItemType & 0xFFFF) { case MODITEM_COMMENTS: if (pModDoc) pModDoc->ActivateView(IDD_CONTROL_COMMENTS, 0); @@ -1155,7 +1153,7 @@ return TRUE; default: - if (dwItemType & 0x8000) + if (qwItemType & 0x8000) { PlayItem(hItem); return TRUE; @@ -1171,11 +1169,11 @@ { if (hItem) { - DWORD dwItemType = GetModItem(hItem); - DWORD dwItem = dwItemType >> 16; + uint64 qwItemType = GetModItem(hItem); + DWORD dwItem = (DWORD)(qwItemType >> 16); PMODTREEDOCINFO pInfo = DocInfo[m_nDocNdx]; CModDoc *pModDoc = (pInfo) ? pInfo->pModDoc : NULL; - switch(dwItemType & 0xFFFF) + switch(qwItemType & 0xFFFF) { case MODITEM_SAMPLE: if (pModDoc) @@ -1234,7 +1232,7 @@ CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); if (pMainFrm) { - if ((dwItemType & 0xFFFF) == MODITEM_INSLIB_INSTRUMENT) + if ((qwItemType & 0xFFFF) == MODITEM_INSLIB_INSTRUMENT) { pMainFrm->PlaySoundFile(&m_SongFile, n, 0, nParam); } else @@ -1265,21 +1263,21 @@ break; default: - if (dwItemType & 0x8000) + if (qwItemType & 0x8000) { CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); - UINT bank = (dwItemType & 0x3F000000) >> 24; + UINT bank = (qwItemType & 0x3F000000) >> 24; if ((bank < MAX_DLS_BANKS) && (CTrackApp::gpDLSBanks[bank]) && (pMainFrm)) { CDLSBank *pDLSBank = CTrackApp::gpDLSBanks[bank]; - UINT rgn = 0, instr = (dwItemType & 0x00007FFF); + UINT rgn = 0, instr = (qwItemType & 0x00007FFF); // Drum - if (dwItemType & 0x80000000) + if (qwItemType & 0x80000000) { - rgn = (dwItemType & 0x007F0000) >> 16; + rgn = (qwItemType & 0x007F0000) >> 16; } else // Melodic - if (dwItemType & 0x40000000) + if (qwItemType & 0x40000000) { if ((!nParam) || (nParam > NOTE_MAX)) nParam = NOTE_MIDDLEC; rgn = pDLSBank->GetRegionFromKey(instr, nParam-1); @@ -1333,54 +1331,54 @@ BOOL CModTree::DeleteTreeItem(HTREEITEM hItem) //-------------------------------------------- { - DWORD dwItemType = GetModItem(hItem); - WORD nItem = WORD(dwItemType >> 16); + uint64 qwItemType = GetModItem(hItem); + DWORD dwItem = (DWORD)(qwItemType >> 16); PMODTREEDOCINFO pInfo = DocInfo[m_nDocNdx]; CModDoc *pModDoc = (pInfo) ? pInfo->pModDoc : NULL; - switch(dwItemType & 0xFFFF) + switch(qwItemType & 0xFFFF) { case MODITEM_ORDER: - if ((pModDoc) && (pModDoc->RemoveOrder(nItem))) + if ((pModDoc) && (pModDoc->RemoveOrder((ORDERINDEX)dwItem))) { pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, NULL); } break; case MODITEM_PATTERN: - if ((pModDoc) && (pModDoc->RemovePattern(nItem))) + if ((pModDoc) && (pModDoc->RemovePattern((PATTERNINDEX)dwItem))) { //pModDoc->UpdateAllViews(NULL, (dwItem << 16)|HINT_PATTERNDATA|HINT_PATNAMES); - pModDoc->UpdateAllViews(NULL, (UINT(nItem) << HINT_SHIFT_PAT) | HINT_PATTERNDATA|HINT_PATNAMES); + pModDoc->UpdateAllViews(NULL, (UINT(dwItem) << HINT_SHIFT_PAT) | HINT_PATTERNDATA|HINT_PATNAMES); } break; case MODITEM_SAMPLE: - if ((pModDoc) && (pModDoc->RemoveSample(nItem))) + if ((pModDoc) && (pModDoc->RemoveSample((SAMPLEINDEX)dwItem))) { //pModDoc->UpdateAllViews(NULL, (dwItem << 16) | HINT_SMPNAMES|HINT_SAMPLEDATA|HINT_SAMPLEINFO); - pModDoc->UpdateAllViews(NULL, (UINT(nItem) << HINT_SHIFT_SMP) | HINT_SMPNAMES|HINT_SAMPLEDATA|HINT_SAMPLEINFO); + pModDoc->UpdateAllViews(NULL, (UINT(dwItem) << HINT_SHIFT_SMP) | HINT_SMPNAMES|HINT_SAMPLEDATA|HINT_SAMPLEINFO); } break; case MODITEM_INSTRUMENT: - if ((pModDoc) && (pModDoc->RemoveInstrument(nItem))) + if ((pModDoc) && (pModDoc->RemoveInstrument((INSTRUMENTINDEX)dwItem))) { //pModDoc->UpdateAllViews(NULL, (dwItem << 16)|HINT_MODTYPE|HINT_ENVELOPE|HINT_INSTRUMENT); - pModDoc->UpdateAllViews(NULL, (UINT(nItem) << HINT_SHIFT_INS) | HINT_MODTYPE|HINT_ENVELOPE|HINT_INSTRUMENT); + pModDoc->UpdateAllViews(NULL, (UINT(dwItem) << HINT_SHIFT_INS) | HINT_MODTYPE|HINT_ENVELOPE|HINT_INSTRUMENT); } break; case MODITEM_MIDIINSTRUMENT: - SetMidiInstrument(nItem, ""); + SetMidiInstrument(dwItem, ""); RefreshMidiLibrary(); break; case MODITEM_MIDIPERCUSSION: - SetMidiPercussion(nItem, ""); + SetMidiPercussion(dwItem, ""); RefreshMidiLibrary(); break; case MODITEM_DLSBANK_FOLDER: - CTrackApp::RemoveDLSBank(nItem); + CTrackApp::RemoveDLSBank(dwItem); RefreshDlsBanks(); break; @@ -1408,12 +1406,12 @@ BOOL CModTree::OpenTreeItem(HTREEITEM hItem) //------------------------------------------ { - DWORD dwItemType = GetModItem(hItem); + uint64 qwItemType = GetModItem(hItem); //DWORD dwItem = dwItemType >> 16; //PMODTREEDOCINFO pInfo = DocInfo[m_nDocNdx]; //CModDoc *pModDoc = (pInfo) ? pInfo->pModDoc : NULL; - switch(dwItemType & 0xFFFF) + switch(qwItemType & 0xFFFF) { case MODITEM_INSLIB_SONG: { @@ -1853,9 +1851,9 @@ PMODTREEDOCINFO pInfo = DocInfo[m_nDragDocNdx]; pdropinfo->pModDoc = (pInfo) ? pInfo->pModDoc : NULL; pdropinfo->dwDropType = DRAGONDROP_NOTHING; - pdropinfo->dwDropItem = m_dwItemDrag >> 16; + pdropinfo->dwDropItem = (DWORD)(m_qwItemDrag >> 16); pdropinfo->lDropParam = 0; - switch(m_dwItemDrag & 0xFFFF) + switch(m_qwItemDrag & 0xFFFF) { case MODITEM_ORDER: pdropinfo->dwDropType = DRAGONDROP_ORDER; @@ -1883,7 +1881,7 @@ if (s[0] >= '0') n += (s[0] - '0'); if ((s[1] >= '0') && (s[1] <= '9')) n = n*10 + (s[1] - '0'); if ((s[2] >= '0') && (s[2] <= '9')) n = n*10 + (s[2] - '0'); - pdropinfo->dwDropType = ((m_dwItemDrag & 0xFFFF) == MODITEM_INSLIB_SAMPLE) ? DRAGONDROP_SAMPLE : DRAGONDROP_INSTRUMENT; + pdropinfo->dwDropType = ((m_qwItemDrag & 0xFFFF) == MODITEM_INSLIB_SAMPLE) ? DRAGONDROP_SAMPLE : DRAGONDROP_INSTRUMENT; pdropinfo->dwDropItem = n; pdropinfo->pModDoc = NULL; pdropinfo->lDropParam = (LPARAM)&m_SongFile; @@ -1918,14 +1916,14 @@ break; default: - if (m_dwItemDrag & 0xC0000000) + if (m_qwItemDrag & 0xC0000000) { pdropinfo->dwDropType = DRAGONDROP_DLS; // dwDropItem = DLS Bank # - pdropinfo->dwDropItem = (m_dwItemDrag & 0x3F000000) >> 24; // bank # + pdropinfo->dwDropItem = (DWORD)((m_qwItemDrag & 0x3F000000) >> 24); // bank # // Melodic: (Instrument) // Drums: (0x80000000) | (Region << 16) | (Instrument) - pdropinfo->lDropParam = (m_dwItemDrag & 0x80FF7FFF); // + pdropinfo->lDropParam = (LPARAM)((m_qwItemDrag & 0x80FF7FFF)); // break; } } @@ -1936,13 +1934,13 @@ BOOL CModTree::CanDrop(HTREEITEM hItem, BOOL bDoDrop) //--------------------------------------------------- { - DWORD dwItemDrop = GetModItem(hItem); - DWORD dwItemDrag = m_dwItemDrag >> 16; - DWORD dwDragType = m_dwItemDrag & 0xFFFF; - DWORD dwDropType = dwItemDrop & 0xFFFF; + uint64 qwItemDrop = GetModItem(hItem); + DWORD dwItemDrag = (DWORD)(m_qwItemDrag >> 16); + DWORD dwDragType = m_qwItemDrag & 0xFFFF; + DWORD dwDropType = (DWORD)(qwItemDrop & 0xFFFF); PMODTREEDOCINFO pInfo = DocInfo[m_nDocNdx]; CModDoc *pModDoc = (pInfo) ? pInfo->pModDoc : NULL; - dwItemDrop >>= 16; + qwItemDrop >>= 16; switch(dwDropType) { case MODITEM_ORDER: @@ -1950,7 +1948,7 @@ { if (bDoDrop) { - if (dwItemDrag != dwItemDrop) pModDoc->MoveOrder(dwItemDrag, dwItemDrop, true); + if (dwItemDrag != qwItemDrop) pModDoc->MoveOrder((ORDERINDEX)dwItemDrag, (ORDERINDEX)qwItemDrop, true); } return TRUE; } @@ -1969,9 +1967,9 @@ CHAR szFullPath[_MAX_PATH] = ""; InsLibGetFullPath(m_hItemDrag, szFullPath); if (dwDropType == MODITEM_MIDIINSTRUMENT) - SetMidiInstrument(dwItemDrop, szFullPath); + SetMidiInstrument((DWORD)qwItemDrop, szFullPath); else - SetMidiPercussion(dwItemDrop, szFullPath); + SetMidiPercussion((DWORD)qwItemDrop, szFullPath); } return TRUE; } @@ -2046,9 +2044,9 @@ { if (!ItemHasChildren(m_hItemDrag)) SelectItem(m_hItemDrag); } - m_dwItemDrag = GetModItem(m_hItemDrag); + m_qwItemDrag = GetModItem(m_hItemDrag); m_nDragDocNdx = m_nDocNdx; - switch(m_dwItemDrag & 0xFFFF) + switch(m_qwItemDrag & 0xFFFF) { case MODITEM_ORDER: case MODITEM_PATTERN: @@ -2062,7 +2060,7 @@ bDrag = TRUE; break; default: - if (m_dwItemDrag & 0x8000) bDrag = TRUE; + if (m_qwItemDrag & 0x8000) bDrag = TRUE; } if (bDrag) { @@ -2158,13 +2156,13 @@ { UINT nDefault = 0; BOOL bSep = FALSE; - DWORD dwItemType; + uint64 qwItemType; - dwItemType = GetModItem(hItem); - const uint16 nItemNo = HIWORD(dwItemType); - dwItemType &= 0xFFFF; + qwItemType = GetModItem(hItem); + const DWORD dwItemNo = (DWORD)(qwItemType >> 16); + qwItemType &= 0xFFFF; SelectItem(hItem); - switch(dwItemType) + switch(qwItemType) { case MODITEM_COMMENTS: nDefault = ID_MODTREE_EXECUTE; @@ -2176,9 +2174,17 @@ nDefault = ID_MODTREE_EXECUTE; AppendMenu(hMenu, MF_STRING, nDefault, "&Edit Pattern"); AppendMenu(hMenu, MF_STRING, ID_MODTREE_REMOVE, - (dwItemType == MODITEM_ORDER) ? "&Delete from list" : "&Delete Pattern"); + (qwItemType == MODITEM_ORDER) ? "&Delete from list" : "&Delete Pattern"); break; + case MODITEM_SEQUENCE: + // TODO: Right-click menu for sequences + //nDefault = ID_MODTREE_EXECUTE; + //AppendMenu(hMenu, MF_STRING, nDefault, "&Switch to Seqeuence"); + //AppendMenu(hMenu, MF_STRING, ID_MODTREE_REMOVE, "&Delete Sequence"); + //AppendMenu(hMenu, MF_STRING, ID_MODTREE_REMOVE, "D&uplicate Sequence"); + break; + case MODITEM_SAMPLE: { CModDoc *pModDoc = GetDocumentFromItem(hItem); @@ -2189,7 +2195,7 @@ if ((pModDoc) && (!pModDoc->GetNumInstruments())) { AppendMenu(hMenu, MF_SEPARATOR, NULL, ""); - AppendMenu(hMenu, (pModDoc->IsSampleMuted(nItemNo) ? MF_CHECKED:0)|MF_STRING, ID_MODTREE_MUTE, "&Mute Sample"); + AppendMenu(hMenu, (pModDoc->IsSampleMuted((SAMPLEINDEX)dwItemNo) ? MF_CHECKED:0)|MF_STRING, ID_MODTREE_MUTE, "&Mute Sample"); AppendMenu(hMenu, MF_STRING, ID_MODTREE_SOLO, "&Solo Sample"); AppendMenu(hMenu, MF_STRING, ID_MODTREE_UNMUTEALL, "&Unmute all"); } @@ -2206,7 +2212,7 @@ if ((pModDoc) && (pModDoc->GetNumInstruments())) { AppendMenu(hMenu, MF_SEPARATOR, NULL, ""); - AppendMenu(hMenu, (pModDoc->IsInstrumentMuted(nItemNo) ? MF_CHECKED:0)|MF_STRING, ID_MODTREE_MUTE, "&Mute Instrument"); + AppendMenu(hMenu, (pModDoc->IsInstrumentMuted((INSTRUMENTINDEX)dwItemNo) ? MF_CHECKED:0)|MF_STRING, ID_MODTREE_MUTE, "&Mute Instrument"); AppendMenu(hMenu, MF_STRING, ID_MODTREE_SOLO, "&Solo Instrument"); AppendMenu(hMenu, MF_STRING, ID_MODTREE_UNMUTEALL, "&Unmute all"); // -> CODE#0023 @@ -2227,7 +2233,7 @@ CModDoc *pModDoc = GetDocumentFromItem(hItem); CSoundFile *pSndFile = pModDoc ? pModDoc->GetSoundFile() : NULL; if (pSndFile) { - PSNDMIXPLUGIN pPlugin = &pSndFile->m_MixPlugins[nItemNo]; + PSNDMIXPLUGIN pPlugin = &pSndFile->m_MixPlugins[dwItemNo]; if (pPlugin) { bool bypassed = ((pPlugin->Info.dwInputRouting&MIXPLUG_INPUTF_BYPASS) != 0); AppendMenu(hMenu, (bypassed?MF_CHECKED:0)|MF_STRING, ID_MODTREE_MUTE, "&Bypass"); @@ -2286,7 +2292,7 @@ break; default: - if (dwItemType & 0x8000) + if (qwItemType & 0x8000) { nDefault = ID_MODTREE_PLAY; AppendMenu(hMenu, MF_STRING, ID_MODTREE_PLAY, "&Play Instrument"); @@ -2294,9 +2300,9 @@ break; } if (nDefault) SetMenuDefaultItem(hMenu, nDefault, FALSE); - if ((dwItemType == MODITEM_INSLIB_FOLDER) - || (dwItemType == MODITEM_INSLIB_SONG) - || (dwItemType == MODITEM_HDR_INSTRUMENTLIB)) + if ((qwItemType == MODITEM_INSLIB_FOLDER) + || (qwItemType == MODITEM_INSLIB_SONG) + || (qwItemType == MODITEM_HDR_INSTRUMENTLIB)) { if ((bSep) || (nDefault)) AppendMenu(hMenu, MF_SEPARATOR, NULL, ""); AppendMenu(hMenu, (m_bShowAllFiles) ? (MF_STRING|MF_CHECKED) : MF_STRING, ID_MODTREE_SHOWALLFILES, "Show All Files"); @@ -2325,8 +2331,8 @@ HTREEITEM hItem = HitTest(pt, &flags); if (hItem != NULL) { - DWORD dwItem = GetModItem(hItem); - switch(dwItem & 0xFFFF) + uint64 qwItem = GetModItem(hItem); + switch(qwItem & 0xFFFF) { case MODITEM_INSLIB_FOLDER: case MODITEM_INSLIB_SONG: @@ -2341,8 +2347,8 @@ if (pFrame) { pFrame->SendMessage(WM_MOD_INSTRSELECTED, - ((dwItem & 0xffff) == MODITEM_INSTRUMENT) ? TRUE : FALSE, - dwItem >> 16); + ((qwItem & 0xffff) == MODITEM_INSTRUMENT) ? TRUE : FALSE, + (LPARAM)(qwItem >> 16)); } } break; @@ -2415,7 +2421,7 @@ // Bug? if (!(nFlags & (MK_LBUTTON|MK_RBUTTON))) { - m_dwItemDrag = 0; + m_qwItemDrag = 0; m_hItemDrag = NULL; OnEndDrag(TREESTATUS_DRAGGING); return; @@ -2568,29 +2574,29 @@ //----------------------------- { HTREEITEM hItem = GetSelectedItem(); - DWORD dwItemType; + uint64 qwItemType; CModDoc *pModDoc; - dwItemType = GetModItem(hItem); - const uint16 nItemNo = HIWORD(dwItemType); - dwItemType &= 0xFFFF; + qwItemType = GetModItem(hItem); + const DWORD dwItemNo = (DWORD)(qwItemType >> 16); + qwItemType &= 0xFFFF; pModDoc = GetDocumentFromItem(hItem); if (pModDoc) { - if ((dwItemType == MODITEM_SAMPLE) && (!pModDoc->GetNumInstruments())) + if ((qwItemType == MODITEM_SAMPLE) && (!pModDoc->GetNumInstruments())) { - pModDoc->MuteSample(nItemNo, (pModDoc->IsSampleMuted(nItemNo)) ? FALSE : TRUE); + pModDoc->MuteSample((SAMPLEINDEX)dwItemNo, (pModDoc->IsSampleMuted((SAMPLEINDEX)dwItemNo)) ? false : true); } else - if ((dwItemType == MODITEM_INSTRUMENT) && (pModDoc->GetNumInstruments())) + if ((qwItemType == MODITEM_INSTRUMENT) && (pModDoc->GetNumInstruments())) { - pModDoc->MuteInstrument(nItemNo, (pModDoc->IsInstrumentMuted(nItemNo)) ? FALSE : TRUE); + pModDoc->MuteInstrument((INSTRUMENTINDEX)dwItemNo, (pModDoc->IsInstrumentMuted((INSTRUMENTINDEX)dwItemNo)) ? false : true); } - if ((dwItemType == MODITEM_EFFECT)) + if ((qwItemType == MODITEM_EFFECT)) { CSoundFile *pSndFile = pModDoc ? pModDoc->GetSoundFile() : NULL; if (pSndFile) { - PSNDMIXPLUGIN pPlugin = &pSndFile->m_MixPlugins[nItemNo]; + PSNDMIXPLUGIN pPlugin = &pSndFile->m_MixPlugins[dwItemNo]; if (pPlugin) { CVstPlugin *pVstPlugin = (CVstPlugin *)pPlugin->pMixPlugin; if (pVstPlugin) pVstPlugin->Bypass(); @@ -2606,29 +2612,29 @@ //----------------------------- { HTREEITEM hItem = GetSelectedItem(); - DWORD dwItemType; + uint64 qwItemType; CModDoc *pModDoc; - dwItemType = GetModItem(hItem); - const uint16 nItemNo = HIWORD(dwItemType); - dwItemType &= 0xFFFF; + qwItemType = GetModItem(hItem); + const DWORD dwItemNo = (DWORD)(qwItemType >> 16); + qwItemType &= 0xFFFF; pModDoc = GetDocumentFromItem(hItem); if (pModDoc) { SAMPLEINDEX nSamples = pModDoc->GetNumSamples(); INSTRUMENTINDEX nInstruments = pModDoc->GetNumInstruments(); - if ((dwItemType == MODITEM_SAMPLE) && (!nInstruments)) + if ((qwItemType == MODITEM_SAMPLE) && (!nInstruments)) { for (SAMPLEINDEX i=1; i<=nSamples; i++) { - pModDoc->MuteSample(i, (i == nItemNo) ? FALSE : TRUE); + pModDoc->MuteSample(i, (i == dwItemNo) ? false : true); } } else - if ((dwItemType == MODITEM_INSTRUMENT) && (nInstruments)) + if ((qwItemType == MODITEM_INSTRUMENT) && (nInstruments)) { for (INSTRUMENTINDEX i=1; i<=nInstruments; i++) { - pModDoc->MuteInstrument(i, (i == nItemNo) ? FALSE : TRUE); + pModDoc->MuteInstrument(i, (i == dwItemNo) ? false : true); } } } @@ -2639,16 +2645,16 @@ //---------------------------------- { HTREEITEM hItem = GetSelectedItem(); - DWORD dwItemType; + uint64 qwItemType; CModDoc *pModDoc; - dwItemType = GetModItem(hItem) & 0xFFFF; + qwItemType = GetModItem(hItem) & 0xFFFF; pModDoc = GetDocumentFromItem(hItem); if (pModDoc) { SAMPLEINDEX nSamples = pModDoc->GetNumSamples(); INSTRUMENTINDEX nInstruments = pModDoc->GetNumInstruments(); - if ((dwItemType == MODITEM_SAMPLE) || (dwItemType == MODITEM_INSTRUMENT)) + if ((qwItemType == MODITEM_SAMPLE) || (qwItemType == MODITEM_INSTRUMENT)) { for (SAMPLEINDEX i=1; i<=nSamples; i++) { @@ -2668,9 +2674,9 @@ void CModTree::OnSetItemPath() { HTREEITEM hItem = GetSelectedItem(); - DWORD dwItemType = GetModItem(hItem); - DWORD dwItem = dwItemType >> 16; - dwItemType &= 0xFFFF; + uint64 qwItemType = GetModItem(hItem); + DWORD dwItem = (DWORD)(qwItemType >> 16); + qwItemType &= 0xFFFF; CModDoc *pModDoc = GetDocumentFromItem(hItem); CSoundFile *pSndFile = pModDoc ? pModDoc->GetSoundFile() : NULL; @@ -2700,15 +2706,15 @@ void CModTree::OnSaveItem() { HTREEITEM hItem = GetSelectedItem(); - DWORD dwItemType = GetModItem(hItem); - const uint16 nItem = HIWORD(dwItemType); - dwItemType &= 0xFFFF; + uint64 qwItemType = GetModItem(hItem); + const DWORD dwItem = HIWORD(qwItemType); + qwItemType &= 0xFFFF; CModDoc *pModDoc = GetDocumentFromItem(hItem); CSoundFile *pSndFile = pModDoc ? pModDoc->GetSoundFile() : NULL; - if(pSndFile && nItem){ + if(pSndFile && dwItem){ - if(pSndFile->m_szInstrumentPath[nItem-1][0] == '\0'){ + if(pSndFile->m_szInstrumentPath[dwItem-1][0] == '\0'){ CHAR pszFileNames[_MAX_PATH]; CFileDialog dlg(FALSE, (pSndFile->m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) ? "iti" : "xi", NULL, @@ -2724,23 +2730,23 @@ dlg.m_ofn.lpstrFile = pszFileNames; dlg.m_ofn.nMaxFile = _MAX_PATH; - if(dlg.DoModal() == IDOK) strcpy(pSndFile->m_szInstrumentPath[nItem-1], pszFileNames); + if(dlg.DoModal() == IDOK) strcpy(pSndFile->m_szInstrumentPath[dwItem - 1], pszFileNames); dlg.m_ofn.lpstrFile = NULL; dlg.m_ofn.nMaxFile = 0; } - if(pSndFile->m_szInstrumentPath[nItem-1][0] != '\0'){ - int size = strlen(pSndFile->m_szInstrumentPath[nItem-1]); - BOOL iti = _stricmp(&pSndFile->m_szInstrumentPath[nItem-1][size-3],"iti") == 0; - BOOL xi = _stricmp(&pSndFile->m_szInstrumentPath[nItem-1][size-2],"xi") == 0; + if(pSndFile->m_szInstrumentPath[dwItem - 1][0] != '\0'){ + int size = strlen(pSndFile->m_szInstrumentPath[dwItem - 1]); + BOOL iti = _stricmp(&pSndFile->m_szInstrumentPath[dwItem - 1][size-3],"iti") == 0; + BOOL xi = _stricmp(&pSndFile->m_szInstrumentPath[dwItem - 1][size-2],"xi") == 0; if(iti || (!iti && !xi && pSndFile->m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) - pSndFile->SaveITIInstrument(nItem, pSndFile->m_szInstrumentPath[nItem-1]); + pSndFile->SaveITIInstrument((INSTRUMENTINDEX)dwItem, pSndFile->m_szInstrumentPath[dwItem - 1]); if(xi || (!xi && !iti && pSndFile->m_nType == MOD_TYPE_XM)) - pSndFile->SaveXIInstrument(nItem, pSndFile->m_szInstrumentPath[nItem-1]); + pSndFile->SaveXIInstrument((INSTRUMENTINDEX)dwItem, pSndFile->m_szInstrumentPath[dwItem - 1]); - pSndFile->instrumentModified[nItem-1] = FALSE; + pSndFile->instrumentModified[dwItem - 1] = FALSE; } if(pModDoc) pModDoc->UpdateAllViews(NULL, HINT_MODTYPE); @@ -2799,8 +2805,8 @@ { UINT flags; HTREEITEM hItem = HitTest(point, &flags); - DWORD dwItemType = GetModItem(hItem); - switch(dwItemType & 0xFFFF) + uint64 qwItemType = GetModItem(hItem); + switch(qwItemType & 0xFFFF) { case MODITEM_MIDIINSTRUMENT: case MODITEM_MIDIPERCUSSION: @@ -2810,7 +2816,7 @@ EnsureVisible(hItem); } m_hItemDrag = hItem; - m_dwItemDrag = dwItemType; + m_qwItemDrag = qwItemType; return DROPEFFECT_LINK; // Folders: case MODITEM_HDR_MIDILIB: @@ -2842,8 +2848,8 @@ DragQueryFile(hDropInfo, 0, szFileName, _MAX_PATH); if (szFileName[0]) { - DWORD dwItem = m_dwItemDrag >> 16; - switch(m_dwItemDrag & 0xFFFF) + DWORD dwItem = (DWORD)(m_qwItemDrag >> 16); + switch(m_qwItemDrag & 0xFFFF) { case MODITEM_MIDIINSTRUMENT: bOk = SetMidiInstrument(dwItem, szFileName); @@ -2918,10 +2924,10 @@ //------------------------------------ { HTREEITEM hItem = GetSelectedItem(); - DWORD dwItemType = GetModItem(hItem); - if ((dwItemType & 0xFFFF) == MODITEM_DLSBANK_FOLDER) + uint64 qwItemType = GetModItem(hItem); + if ((qwItemType & 0xFFFF) == MODITEM_DLSBANK_FOLDER) { - UINT nBank = dwItemType >> 16; + UINT nBank = (UINT)(qwItemType >> 16); if ((nBank < MAX_DLS_BANKS) && (CTrackApp::gpDLSBanks[nBank])) { CSoundBankProperties dlg(CTrackApp::gpDLSBanks[nBank], this); Modified: trunk/OpenMPT/mptrack/View_tre.h =================================================================== --- trunk/OpenMPT/mptrack/View_tre.h 2009-10-02 15:49:41 UTC (rev 384) +++ trunk/OpenMPT/mptrack/View_tre.h 2009-10-04 12:50:16 UTC (rev 385) @@ -32,6 +32,7 @@ MODITEM_INSLIB_SONG, MODITEM_DLSBANK_FOLDER, MODITEM_DLSBANK_INSTRUMENT, + MODITEM_SEQUENCE, }; #define TREESTATUS_RDRAG 0x01 @@ -109,7 +110,7 @@ CModTree *m_pDataTree; DWORD m_dwStatus; HWND m_hDropWnd; - DWORD m_dwItemDrag; + uint64 m_qwItemDrag; BOOL m_bShowAllFiles; UINT m_nDocNdx, m_nDragDocNdx; HTREEITEM m_hItemDrag, m_hItemDrop; @@ -135,7 +136,7 @@ VOID RefreshInstrumentLibrary(); VOID EmptyInstrumentLibrary(); VOID FillInstrumentLibrary(); - DWORD GetModItem(HTREEITEM hItem); + uint64 GetModItem(HTREEITEM hItem); BOOL SetMidiInstrument(UINT nIns, LPCSTR lpszFileName); BOOL SetMidiPercussion(UINT nPerc, LPCSTR lpszFileName); BOOL ExecuteItem(HTREEITEM hItem); Modified: trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb =================================================================== --- trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-10-02 15:49:41 UTC (rev 384) +++ trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-10-04 12:50:16 UTC (rev 385) @@ -18,7 +18,7 @@ 0:1027:0:118:5 //Play pattern from start: F7 (KeyDown|KeyHold) 0:1026:2:118:5 //Play pattern from cursor: Ctrl+F7 (KeyDown|KeyHold) 0:1376:0:120:1 //Toggle Midi Record: F9 (KeyDown) -0:1359:2:90:1 //Undo: Ctrl+Z (KeyDown) +0:1359:2:90:5 //Undo: Ctrl+Z (KeyDown|KeyHold) 0:1360:2:88:1 //Cut: Ctrl+X (KeyDown) 0:1361:2:67:1 //Copy: Ctrl+C (KeyDown) 0:1361:2:45:1 //Copy: Ctrl+EINFG (KeyDown) @@ -77,6 +77,7 @@ 2:1662:6:80:1 //Toggle channel's plugin editor: Ctrl+Alt+P (KeyDown) 2:1062:0:93:1 //Show note properties: ANWENDUNG (KeyDown) 2:1780:2:80:1 //Show playback time at current row: Ctrl+P (KeyDown) +2:1786:2:82:1 //Reset channel: Ctrl+R (KeyDown) 2:1007:2:81:5 //Transpose +1: Ctrl+Q (KeyDown|KeyHold) 2:1008:2:65:5 //Transpose -1: Ctrl+A (KeyDown|KeyHold) 2:1009:3:81:5 //Transpose +12: Shift+Ctrl+Q (KeyDown|KeyHold) @@ -155,9 +156,9 @@ 3:1221:0:57:1 //Set octave 9: 9 (KeyDown) 3:1221:0:105:1 //Set octave 9: 9 (ZEHNERTASTATUR) (KeyDown) 3:1316:1:16:1 //Chord Modifier: Shift+UMSCHALT (KeyDown) -3:1200:0:220:1 //Note Cut: ZIRKUMFLEX (KeyDown) -3:1201:0:221:1 //Note Off: AKUT (KeyDown) -3:1791:0:219:1 //Note Fade: \xDF (KeyDown) +3:1667:0:220:1 //Note Cut (don't remember instrument): ZIRKUMFLEX (KeyDown) +3:1668:0:221:1 //Note Off (don't remember instrument): AKUT (KeyDown) +3:1792:0:219:1 //Note Fade (don't remember instrument): \xDF (KeyDown) 3:1788:0:226:1 //Parameter control(MPTm only): < (KeyDown) 3:1789:1:226:1 //Parameter control(smooth)(MPTm only): Shift+< (KeyDown) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-10-04 18:13:42
|
Revision: 386 http://modplug.svn.sourceforge.net/modplug/?rev=386&view=rev Author: saga-games Date: 2009-10-04 18:13:30 +0000 (Sun, 04 Oct 2009) Log Message: ----------- [Fix] Mod Creation: MOD Panning scheme is set up correctly now. [Fix] Treeview: Removing orders works correctly now. [Imp] Treeview: Show whole sequence (don't stop on first "---" item) [Imp] Pattern editor: If "record note off" is enabled and Note Off commands are not supported by the current format, try Note Cut and volume commands [Ref] Fixed various compiler warnings Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/mptrack/View_tre.h trunk/OpenMPT/soundlib/Load_med.cpp trunk/OpenMPT/soundlib/Load_mod.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-10-04 12:50:16 UTC (rev 385) +++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-10-04 18:13:30 UTC (rev 386) @@ -266,7 +266,7 @@ InvalidateSelection(); if ((m_pParent) && (m_pModDoc) && (bEdit)) { - UINT n = pSndFile->Order[m_nScrollPos]; + PATTERNINDEX n = pSndFile->Order[m_nScrollPos]; if ((n < pSndFile->Patterns.Size()) && (pSndFile->Patterns[n]) && !bShiftClick) { BOOL bIsPlaying = (pMainFrm->GetModPlaying() == m_pModDoc); @@ -1000,7 +1000,7 @@ for(int i = 0; i <= (selection.nOrdHi - selection.nOrdLo); i++) { - m_pModDoc->RemoveOrder(selection.nOrdLo); + m_pModDoc->RemoveOrder(pSndFile->Order.GetCurrentSequenceIndex(), selection.nOrdLo); } InvalidateRect(NULL, FALSE); m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this); Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-04 12:50:16 UTC (rev 385) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-04 18:13:30 UTC (rev 386) @@ -657,16 +657,15 @@ m_SndFile.m_nSamplePreAmp = m_SndFile.m_nVSTiVolume = 128; } - for (UINT init=0; init<MAX_BASECHANNELS; init++) + for (CHANNELINDEX nChn=0; nChn < MAX_BASECHANNELS; nChn++) { - m_SndFile.ChnSettings[init].dwFlags = 0; - m_SndFile.ChnSettings[init].nVolume = 64; - if (m_SndFile.m_nType & (MOD_TYPE_XM|MOD_TYPE_IT | MOD_TYPE_MPT)) - m_SndFile.ChnSettings[init].nPan = 128; - else - m_SndFile.ChnSettings[init].nPan = (init & 0x01) ? 64 : 192; - m_SndFile.Chn[init].nGlobalVol = 64; + m_SndFile.ChnSettings[nChn].dwFlags = 0; + m_SndFile.ChnSettings[nChn].nVolume = 64; + m_SndFile.ChnSettings[nChn].nPan = 128; + m_SndFile.Chn[nChn].nGlobalVol = 64; } + // Setup LRRL panning scheme for MODs + m_SndFile.SetupMODPanning(); } if (!m_SndFile.m_nSamples) { Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-10-04 12:50:16 UTC (rev 385) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-10-04 18:13:30 UTC (rev 386) @@ -203,10 +203,10 @@ SAMPLEINDEX InsertSample(bool bLimit = false); INSTRUMENTINDEX InsertInstrument(LONG lSample = 0, LONG lDuplicate = 0); void InitializeInstrument(MODINSTRUMENT *pIns, UINT nsample=0); - bool RemoveOrder(ORDERINDEX n); - bool RemovePattern(PATTERNINDEX n); - bool RemoveSample(SAMPLEINDEX n); - bool RemoveInstrument(INSTRUMENTINDEX n); + bool RemoveOrder(SEQUENCEINDEX nSeq, ORDERINDEX nOrd); + bool RemovePattern(PATTERNINDEX nPat); + bool RemoveSample(SAMPLEINDEX nSmp); + bool RemoveInstrument(INSTRUMENTINDEX nIns); UINT PlayNote(UINT note, UINT nins, UINT nsmp, BOOL bpause, LONG nVol=-1, LONG loopstart=0, LONG loopend=0, int nCurrentChn=-1, const uint32 nStartPos = uint32_max); //rewbs.vstiLive: added current chan param BOOL NoteOff(UINT note, BOOL bFade=FALSE, UINT nins=-1, UINT nCurrentChn=-1); //rewbs.vstiLive: add params Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-04 12:50:16 UTC (rev 385) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-04 18:13:30 UTC (rev 386) @@ -152,7 +152,7 @@ MODCOMMAND *pDest = m_SndFile.Patterns[nNewPat]; memcpy(pDest, pSrc, m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels * sizeof(MODCOMMAND)); m = pDest + len; - patternsFixed.resize(max(nNewPat + 1, patternsFixed.size()), SEQUENCEINDEX_INVALID); + patternsFixed.resize(max(nNewPat + 1, (PATTERNINDEX)patternsFixed.size()), SEQUENCEINDEX_INVALID); nPat = nNewPat; } else { @@ -923,6 +923,7 @@ } m_SndFile.m_nChannels = nNewChannels; + m_SndFile.SetupMODPanning(); END_CRITICAL(); EndWaitCursor(); } @@ -1939,34 +1940,37 @@ } -bool CModDoc::RemoveOrder(ORDERINDEX n) -//------------------------------- +bool CModDoc::RemoveOrder(SEQUENCEINDEX nSeq, ORDERINDEX nOrd) +//------------------------------------------------------------ { - if (n < m_SndFile.Order.size()) + if (nSeq >= m_SndFile.Order.GetNumSequences() || nOrd >= m_SndFile.Order.GetSequence(nSeq).size()) + return false; + + BEGIN_CRITICAL(); + SEQUENCEINDEX nOldSeq = m_SndFile.Order.GetCurrentSequenceIndex(); + m_SndFile.Order.SetSequence(nSeq); + for (ORDERINDEX i = nOrd; i < m_SndFile.Order.GetSequence(nSeq).size() - 1; i++) { - BEGIN_CRITICAL(); - for (ORDERINDEX i=n; i<m_SndFile.Order.size()-1; i++) - { - m_SndFile.Order[i] = m_SndFile.Order[i+1]; - } - m_SndFile.Order[m_SndFile.Order.size()-1] = m_SndFile.Order.GetInvalidPatIndex(); - END_CRITICAL(); - SetModified(); - return true; + m_SndFile.Order[i] = m_SndFile.Order[i + 1]; } - return false; + m_SndFile.Order[m_SndFile.Order.GetLastIndex()] = m_SndFile.Order.GetInvalidPatIndex(); + m_SndFile.Order.SetSequence(nOldSeq); + END_CRITICAL(); + SetModified(); + return true; } -bool CModDoc::RemovePattern(PATTERNINDEX n) -//--------------------------------- + +bool CModDoc::RemovePattern(PATTERNINDEX nPat) +//-------------------------------------------- { - if ((n < m_SndFile.Patterns.Size()) && (m_SndFile.Patterns[n])) + if ((nPat < m_SndFile.Patterns.Size()) && (m_SndFile.Patterns[nPat])) { BEGIN_CRITICAL(); - LPVOID p = m_SndFile.Patterns[n]; - m_SndFile.Patterns[n] = nullptr; - m_SndFile.SetPatternName(n, ""); + LPVOID p = m_SndFile.Patterns[nPat]; + m_SndFile.Patterns[nPat] = nullptr; + m_SndFile.SetPatternName(nPat, ""); CSoundFile::FreePattern(p); END_CRITICAL(); SetModified(); @@ -1976,14 +1980,14 @@ } -bool CModDoc::RemoveSample(SAMPLEINDEX n) -//-------------------------------- +bool CModDoc::RemoveSample(SAMPLEINDEX nSmp) +//------------------------------------------ { - if ((n) && (n <= m_SndFile.m_nSamples)) + if ((nSmp) && (nSmp <= m_SndFile.m_nSamples)) { BEGIN_CRITICAL(); - m_SndFile.DestroySample(n); - m_SndFile.m_szNames[n][0] = 0; + m_SndFile.DestroySample(nSmp); + m_SndFile.m_szNames[nSmp][0] = 0; while ((m_SndFile.m_nSamples > 1) && (!m_SndFile.m_szNames[m_SndFile.m_nSamples][0]) && (!m_SndFile.Samples[m_SndFile.m_nSamples].pSample)) m_SndFile.m_nSamples--; @@ -1995,15 +1999,15 @@ } -bool CModDoc::RemoveInstrument(INSTRUMENTINDEX n) -//------------------------------------ +bool CModDoc::RemoveInstrument(INSTRUMENTINDEX nIns) +//-------------------------------------------------- { - if ((n) && (n <= m_SndFile.m_nInstruments) && (m_SndFile.Instruments[n])) + if ((nIns) && (nIns <= m_SndFile.m_nInstruments) && (m_SndFile.Instruments[nIns])) { BOOL bIns = FALSE; BEGIN_CRITICAL(); - m_SndFile.DestroyInstrument(n); - if (n == m_SndFile.m_nInstruments) m_SndFile.m_nInstruments--; + m_SndFile.DestroyInstrument(nIns); + if (nIns == m_SndFile.m_nInstruments) m_SndFile.m_nInstruments--; for (UINT i=1; i<MAX_INSTRUMENTS; i++) if (m_SndFile.Instruments[i]) bIns = TRUE; if (!bIns) m_SndFile.m_nInstruments = 0; END_CRITICAL(); Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-10-04 12:50:16 UTC (rev 385) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-10-04 18:13:30 UTC (rev 386) @@ -3999,12 +3999,27 @@ if (usePlaybackPosition && nTick) { // avoid SD0 which will be mis-interpreted if (p->command == 0) { //make sure we don't overwrite any existing commands. p->command = (pSndFile->TypeIsS3M_IT_MPT()) ? CMD_S3MCMDEX : CMD_MODCMDEX; - p->param = 0xD0 + min(0xF, nTick); + p->param = 0xD0 | min(0xF, nTick); } } //Enter note off - p->note = NOTE_KEYOFF; + if(pModDoc->GetSoundFile()->GetModSpecifications().hasNoteOff) // === + p->note = NOTE_KEYOFF; + else if(pModDoc->GetSoundFile()->GetModSpecifications().hasNoteCut) // ^^^ + p->note = NOTE_NOTECUT; + else { // we don't have anything to cut (MOD format) - use volume or ECx + if(usePlaybackPosition && nTick) // ECx + { + p->command = (pSndFile->TypeIsS3M_IT_MPT()) ? CMD_S3MCMDEX : CMD_MODCMDEX; + p->param = 0xC0 | min(0xF, nTick); + } else // C00 + { + p->note = NOTE_NONE; + p->command = CMD_VOLUME; + p->param = 0; + } + } p->instr = (bChordMode) ? 0 : ins; //p->instr = 0; //Writing the instrument as well - probably someone finds this annoying :) p->volcmd = 0; Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2009-10-04 12:50:16 UTC (rev 385) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2009-10-04 18:13:30 UTC (rev 386) @@ -742,65 +742,52 @@ } // If there are items past the new sequence length, delete them. - for(size_t nOrd = pSndFile->Order.GetSequence(nSeq).GetLength(); nOrd < pInfo->tiOrders[nSeq].size(); nOrd++) if (pInfo->tiOrders[nSeq][nOrd]) + for(size_t nOrd = pSndFile->Order.GetSequence(nSeq).GetLengthTailTrimmed(); nOrd < pInfo->tiOrders[nSeq].size(); nOrd++) if (pInfo->tiOrders[nSeq][nOrd]) { DeleteItem(pInfo->tiOrders[nSeq][nOrd]); pInfo->tiOrders[nSeq][nOrd] = NULL; } - if (pInfo->tiOrders[nSeq].size() < pSndFile->Order.GetSequence(nSeq).GetLength()) // Resize tiOrders if needed. - pInfo->tiOrders[nSeq].resize(pSndFile->Order.GetSequence(nSeq).GetLength(), NULL); - UINT imin = 0, imax = pSndFile->Order.GetSequence(nSeq).GetLastIndex(); + if (pInfo->tiOrders[nSeq].size() < pSndFile->Order.GetSequence(nSeq).GetLengthTailTrimmed()) // Resize tiOrders if needed. + pInfo->tiOrders[nSeq].resize(pSndFile->Order.GetSequence(nSeq).GetLengthTailTrimmed(), NULL); const bool patNamesOnly = (hintFlagPart == HINT_PATNAMES); //if (hintFlagPart == HINT_PATNAMES) && (dwHintParam < pSndFile->Order.size())) imin = imax = dwHintParam; - bool bEnded = false; - for (UINT iOrd=imin; iOrd<=imax; iOrd++) + for (ORDERINDEX iOrd = 0; iOrd < pSndFile->Order.GetSequence(nSeq).GetLengthTailTrimmed(); iOrd++) { - if (pSndFile->Order.GetSequence(nSeq)[iOrd] == pSndFile->Order.GetInvalidPatIndex()) bEnded = true; - if (bEnded) + if(patNamesOnly && pSndFile->Order.GetSequence(nSeq)[iOrd] != nPat) + continue; + UINT state = (iOrd == pInfo->nOrdSel && nSeq == pInfo->nSeqSel) ? TVIS_BOLD : 0; + if (pSndFile->Order.GetSequence(nSeq)[iOrd] < pSndFile->Patterns.Size()) { - if (pInfo->tiOrders[nSeq][iOrd]) + stmp[0] = 0; + pSndFile->GetPatternName(pSndFile->Order.GetSequence(nSeq)[iOrd], stmp, sizeof(stmp)); + if (stmp[0]) { - DeleteItem(pInfo->tiOrders[nSeq][iOrd]); - pInfo->tiOrders[nSeq][iOrd] = NULL; - } - } else - { - if(patNamesOnly && pSndFile->Order.GetSequence(nSeq)[iOrd] != nPat) - continue; - UINT state = (iOrd == pInfo->nOrdSel && nSeq == pInfo->nSeqSel) ? TVIS_BOLD : 0; - if (pSndFile->Order.GetSequence(nSeq)[iOrd] < pSndFile->Patterns.Size()) - { - stmp[0] = 0; - pSndFile->GetPatternName(pSndFile->Order.GetSequence(nSeq)[iOrd], stmp, sizeof(stmp)); - if (stmp[0]) - { - wsprintf(s, (CMainFrame::m_dwPatternSetup & PATTERN_HEXDISPLAY) ? "[%02Xh] %d: %s" : "[%02d] %d: %s", - iOrd, pSndFile->Order.GetSequence(nSeq)[iOrd], stmp); - } else - { - wsprintf(s, (CMainFrame::m_dwPatternSetup & PATTERN_HEXDISPLAY) ? "[%02Xh] Pattern %d" : "[%02d] Pattern %d", - iOrd, pSndFile->Order.GetSequence(nSeq)[iOrd]); - } + wsprintf(s, (CMainFrame::m_dwPatternSetup & PATTERN_HEXDISPLAY) ? "[%02Xh] %d: %s" : "[%02d] %d: %s", + iOrd, pSndFile->Order.GetSequence(nSeq)[iOrd], stmp); } else { - wsprintf(s, "[%02d] Skip", iOrd); + wsprintf(s, (CMainFrame::m_dwPatternSetup & PATTERN_HEXDISPLAY) ? "[%02Xh] Pattern %d" : "[%02d] Pattern %d", + iOrd, pSndFile->Order.GetSequence(nSeq)[iOrd]); } - if (pInfo->tiOrders[nSeq][iOrd]) - { - tvi.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_STATE; - tvi.state = 0; - tvi.stateMask = TVIS_BOLD; - tvi.hItem = pInfo->tiOrders[nSeq][iOrd]; - tvi.pszText = stmp; - tvi.cchTextMax = sizeof(stmp); - GetItem(&tvi); - if ((strcmp(s, stmp)) || (tvi.state != state)) - SetItem(pInfo->tiOrders[nSeq][iOrd], TVIF_TEXT | TVIF_STATE, s, 0, 0, state, TVIS_BOLD, 0); - } else - { - pInfo->tiOrders[nSeq][iOrd] = InsertItem(s, IMAGE_PARTITION, IMAGE_PARTITION, hAncestorNode, TVI_LAST); - } + } else + { + wsprintf(s, "[%02d] Skip", iOrd); } + if (pInfo->tiOrders[nSeq][iOrd]) + { + tvi.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_STATE; + tvi.state = 0; + tvi.stateMask = TVIS_BOLD; + tvi.hItem = pInfo->tiOrders[nSeq][iOrd]; + tvi.pszText = stmp; + tvi.cchTextMax = sizeof(stmp); + GetItem(&tvi); + if ((strcmp(s, stmp)) || (tvi.state != state)) + SetItem(pInfo->tiOrders[nSeq][iOrd], TVIF_TEXT | TVIF_STATE, s, 0, 0, state, TVIS_BOLD, 0); + } else + { + pInfo->tiOrders[nSeq][iOrd] = InsertItem(s, IMAGE_PARTITION, IMAGE_PARTITION, hAncestorNode, TVI_LAST); + } } } } @@ -1035,7 +1022,6 @@ // find sequence this item belongs to for(SEQUENCEINDEX nSeq = 0; nSeq < pSong->tiOrders.size(); nSeq++) { - ASSERT(pSong->tiOrders[nSeq].size() == pSndFile->Order.size()); for(ORDERINDEX nOrd = 0; nOrd < pSong->tiOrders[nSeq].size(); nOrd++) { if (hItem == pSong->tiOrders[nSeq][nOrd]) @@ -1338,7 +1324,7 @@ switch(qwItemType & 0xFFFF) { case MODITEM_ORDER: - if ((pModDoc) && (pModDoc->RemoveOrder((ORDERINDEX)dwItem))) + if ((pModDoc) && (pModDoc->RemoveOrder((SEQUENCEINDEX)(dwItem >> 16), (ORDERINDEX)(dwItem & 0xFFFF)))) { pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, NULL); } Modified: trunk/OpenMPT/mptrack/View_tre.h =================================================================== --- trunk/OpenMPT/mptrack/View_tre.h 2009-10-04 12:50:16 UTC (rev 385) +++ trunk/OpenMPT/mptrack/View_tre.h 2009-10-04 18:13:30 UTC (rev 386) @@ -45,8 +45,10 @@ struct MODTREEDOCINFO { CModDoc *pModDoc; + // Module information SEQUENCEINDEX nSeqSel; ORDERINDEX nOrdSel; + // Tree state variables HTREEITEM hSong, hPatterns, hSamples, hInstruments, hComments, hOrders, hEffects; vector<HTREEITEM> tiPatterns; HTREEITEM tiSamples[MAX_SAMPLES]; Modified: trunk/OpenMPT/soundlib/Load_med.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_med.cpp 2009-10-04 12:50:16 UTC (rev 385) +++ trunk/OpenMPT/soundlib/Load_med.cpp 2009-10-04 18:13:30 UTC (rev 386) @@ -912,12 +912,8 @@ } } } - // Setup channel pan positions - for (UINT iCh=0; iCh<m_nChannels; iCh++) - { - ChnSettings[iCh].nPan = (((iCh&3) == 1) || ((iCh&3) == 2)) ? 0xC0 : 0x40; - ChnSettings[iCh].nVolume = 64; - } + // Setup channel pan positions and volume + SetupMODPanning(true); return true; } Modified: trunk/OpenMPT/soundlib/Load_mod.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mod.cpp 2009-10-04 12:50:16 UTC (rev 385) +++ trunk/OpenMPT/soundlib/Load_mod.cpp 2009-10-04 18:13:30 UTC (rev 386) @@ -348,15 +348,9 @@ m_nMinPeriod = 14 << 2; m_nMaxPeriod = 3424 << 2; memcpy(m_szNames, lpStream, 20); - // Setting channels pan - for (UINT ich=0; ich<m_nChannels; ich++) - { - ChnSettings[ich].nVolume = 64; - if (gdwSoundSetup & SNDMIX_MAXDEFAULTPAN) - ChnSettings[ich].nPan = (((ich&3)==1) || ((ich&3)==2)) ? 256 : 0; - else - ChnSettings[ich].nPan = (((ich&3)==1) || ((ich&3)==2)) ? 0xC0 : 0x40; // this should be inverted for Amiga playback - } + // Setup channel pan positions and volume + SetupMODPanning(); + // Reading channels for (UINT ipat=0; ipat<nbp; ipat++) { Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-04 12:50:16 UTC (rev 385) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-04 18:13:30 UTC (rev 386) @@ -516,12 +516,9 @@ memset(&m_SongEQ, 0, sizeof(m_SongEQ)); ResetMidiCfg(); //for (UINT npt=0; npt<Patterns.Size(); npt++) PatternSize[npt] = 64; - for (UINT nch=0; nch<MAX_BASECHANNELS; nch++) + for (CHANNELINDEX nChn = 0; nChn < MAX_BASECHANNELS; nChn++) { - ChnSettings[nch].nPan = 128; - ChnSettings[nch].nVolume = 64; - ChnSettings[nch].dwFlags = 0; - ChnSettings[nch].szName[0] = 0; + InitChannel(nChn); } if (lpStream) { @@ -1337,19 +1334,21 @@ //m_nSeqOverride = 0; } -ORDERINDEX CSoundFile::FindOrder(PATTERNINDEX pat, UINT startFromOrder, bool direction) +ORDERINDEX CSoundFile::FindOrder(PATTERNINDEX nPat, UINT startFromOrder, bool direction) //------------------------------------------------------------------------------------- { - int foundAtOrder = ORDERINDEX_INVALID; - int candidateOrder = 0; + ORDERINDEX foundAtOrder = ORDERINDEX_INVALID; + ORDERINDEX candidateOrder = 0; - for (UINT p=0; p<Order.size(); p++) { - if (direction) { - candidateOrder = (startFromOrder+p)%Order.size(); //wrap around MAX_ORDERS + for (ORDERINDEX p = 0; p < Order.size(); p++) + { + if (direction) + { + candidateOrder = (startFromOrder + p) % Order.size(); //wrap around MAX_ORDERS } else { - candidateOrder = (startFromOrder-p+Order.size())%Order.size(); //wrap around 0 and MAX_ORDERS + candidateOrder = (startFromOrder - p + Order.size()) % Order.size(); //wrap around 0 and MAX_ORDERS } - if (Order[candidateOrder] == pat) { + if (Order[candidateOrder] == nPat) { foundAtOrder = candidateOrder; break; } @@ -1418,25 +1417,25 @@ } -bool CSoundFile::InitChannel(UINT nch) -//------------------------------------- +bool CSoundFile::InitChannel(CHANNELINDEX nChn) +//--------------------------------------------- { - if(nch >= MAX_BASECHANNELS) return true; + if(nChn >= MAX_BASECHANNELS) return true; - ChnSettings[nch].nPan = 128; - ChnSettings[nch].nVolume = 64; - ChnSettings[nch].dwFlags = 0; - ChnSettings[nch].nMixPlugin = 0; - ChnSettings[nch].szName[0] = 0; + ChnSettings[nChn].nPan = 128; + ChnSettings[nChn].nVolume = 64; + ChnSettings[nChn].dwFlags = 0; + ChnSettings[nChn].nMixPlugin = 0; + ChnSettings[nChn].szName[0] = 0; - ResetChannelState(nch, CHNRESET_TOTAL); + ResetChannelState(nChn, CHNRESET_TOTAL); if(m_pModDoc) { - m_pModDoc->Record1Channel(nch,FALSE); - m_pModDoc->Record2Channel(nch,FALSE); + m_pModDoc->Record1Channel(nChn, false); + m_pModDoc->Record2Channel(nChn, false); } - m_bChannelMuteTogglePending[nch] = false; + m_bChannelMuteTogglePending[nChn] = false; return false; } @@ -1525,7 +1524,7 @@ //added to position i. If index of some current channel is missing from the //newOrder-vector, then the channel gets removed. - UINT nRemainingChannels = newOrder.size(); + CHANNELINDEX nRemainingChannels = newOrder.size(); if(nRemainingChannels > GetModSpecifications().channelsMax || nRemainingChannels < GetModSpecifications().channelsMin) { @@ -1536,13 +1535,12 @@ } BEGIN_CRITICAL(); - UINT i = 0; - for (i=0; i<Patterns.Size(); i++) + for (PATTERNINDEX nPat = 0; nPat < Patterns.Size(); nPat++) { - if (Patterns[i]) + if (Patterns[nPat]) { - MODCOMMAND *p = Patterns[i]; - MODCOMMAND *newp = CSoundFile::AllocatePattern(PatternSize[i], nRemainingChannels); + MODCOMMAND *p = Patterns[nPat]; + MODCOMMAND *newp = CSoundFile::AllocatePattern(PatternSize[nPat], nRemainingChannels); if (!newp) { END_CRITICAL(); @@ -1550,18 +1548,18 @@ return 0; } MODCOMMAND *tmpsrc = p, *tmpdest = newp; - for (UINT j=0; j<PatternSize[i]; j++) //Scrolling rows + for (ROWINDEX nRow = 0; nRow<PatternSize[nPat]; nRow++) //Scrolling rows { - for (UINT k=0; k<nRemainingChannels; k++, tmpdest++) //Scrolling channels. + for (CHANNELINDEX nChn = 0; nChn < nRemainingChannels; nChn++, tmpdest++) //Scrolling channels. { - if(newOrder[k] < m_nChannels) //Case: getting old channel to the new channel order. - *tmpdest = tmpsrc[j*m_nChannels+newOrder[k]]; + if(newOrder[nChn] < m_nChannels) //Case: getting old channel to the new channel order. + *tmpdest = tmpsrc[nRow*m_nChannels+newOrder[nChn]]; else //Case: figure newOrder[k] is not the index of any current channel, so adding a new channel. *tmpdest = MODCOMMAND::Empty(); } } - Patterns[i] = newp; + Patterns[nPat] = newp; CSoundFile::FreePattern(p); } } @@ -1571,36 +1569,38 @@ UINT recordStates[MAX_BASECHANNELS]; bool chnMutePendings[MAX_BASECHANNELS]; - for(i = 0 ; i < m_nChannels ; i++) + for(CHANNELINDEX nChn = 0; nChn < m_nChannels; nChn++) { - settings[i] = ChnSettings[i]; - chns[i] = Chn[i]; + settings[nChn] = ChnSettings[nChn]; + chns[nChn] = Chn[nChn]; if(m_pModDoc) - recordStates[i] = m_pModDoc->IsChannelRecord(i); - chnMutePendings[i] = m_bChannelMuteTogglePending[i]; + recordStates[nChn] = m_pModDoc->IsChannelRecord(nChn); + chnMutePendings[nChn] = m_bChannelMuteTogglePending[nChn]; } if(m_pModDoc) m_pModDoc->ReinitRecordState(); - for (UINT i=0; i<nRemainingChannels; i++) + for (CHANNELINDEX nChn = 0; nChn < nRemainingChannels; nChn++) { - if(newOrder[i] < m_nChannels) + if(newOrder[nChn] < m_nChannels) { - ChnSettings[i] = settings[newOrder[i]]; - Chn[i] = chns[newOrder[i]]; + ChnSettings[nChn] = settings[newOrder[nChn]]; + Chn[nChn] = chns[newOrder[nChn]]; if(m_pModDoc) { - if(recordStates[newOrder[i]] == 1) m_pModDoc->Record1Channel(i,TRUE); - if(recordStates[newOrder[i]] == 2) m_pModDoc->Record2Channel(i,TRUE); + if(recordStates[newOrder[nChn]] == 1) m_pModDoc->Record1Channel(nChn, true); + if(recordStates[newOrder[nChn]] == 2) m_pModDoc->Record2Channel(nChn, true); } - m_bChannelMuteTogglePending[i] = chnMutePendings[newOrder[i]]; + m_bChannelMuteTogglePending[nChn] = chnMutePendings[newOrder[nChn]]; } else { - InitChannel(i); + InitChannel(nChn); } } + // Reset MOD panning (won't affect other module formats) + SetupMODPanning(); m_nChannels = nRemainingChannels; END_CRITICAL(); @@ -2747,12 +2747,12 @@ //------------------------------------------------- { if (!pbIns) return false; - for (UINT j=1; j<MAX_SAMPLES; j++) + for (SAMPLEINDEX nSmp=1; nSmp<MAX_SAMPLES; nSmp++) { - if ((!pbIns[j]) && (Samples[j].pSample)) + if ((!pbIns[nSmp]) && (Samples[nSmp].pSample)) { - DestroySample(j); - if ((j == m_nSamples) && (j > 1)) m_nSamples--; + DestroySample(nSmp); + if ((nSmp == m_nSamples) && (nSmp > 1)) m_nSamples--; } } return true; @@ -3004,6 +3004,7 @@ const MODTYPE oldtype = m_nType; m_nType = newType; SetModSpecsPointer(m_pModSpecs, m_nType); + SetupMODPanning(); // Setup LRRL panning scheme if needed m_ModFlags = m_ModFlags & GetModFlagMask(oldtype, newType); @@ -3191,3 +3192,19 @@ return false; } + +void CSoundFile::SetupMODPanning(bool bForceSetup) +//------------------------------------------------ +{ + // Setup LRRL panning, max channel volume + if((m_nType & MOD_TYPE_MOD) == 0 && bForceSetup == false) return; + + for (CHANNELINDEX nChn = 0; nChn < MAX_BASECHANNELS; nChn++) + { + ChnSettings[nChn].nVolume = 64; + if (gdwSoundSetup & SNDMIX_MAXDEFAULTPAN) + ChnSettings[nChn].nPan = (((nChn & 3) == 1) || ((nChn & 3) == 2)) ? 256 : 0; + else + ChnSettings[nChn].nPan = (((nChn & 3) == 1) || ((nChn & 3) == 2)) ? 0xC0 : 0x40; + } +} Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-10-04 12:50:16 UTC (rev 385) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-10-04 18:13:30 UTC (rev 386) @@ -638,7 +638,7 @@ static const CModSpecifications& GetModSpecifications(const MODTYPE type); double GetCurrentBPM() const; - ORDERINDEX FindOrder(PATTERNINDEX pat, UINT startFromOrder=0, bool direction=true); //rewbs.playSongFromCursor + ORDERINDEX FindOrder(PATTERNINDEX nPat, UINT startFromOrder=0, bool direction = true); //rewbs.playSongFromCursor void DontLoopPattern(int nPat, int nRow=0); //rewbs.playSongFromCursor void SetCurrentPos(UINT nPos); void SetCurrentOrder(UINT nOrder); @@ -670,7 +670,7 @@ CHANNELINDEX ReArrangeChannels(const vector<CHANNELINDEX>& fromToArray); bool MoveChannel(UINT chn_from, UINT chn_to); - bool InitChannel(UINT nch); + bool InitChannel(CHANNELINDEX nChn); void ResetChannelState(CHANNELINDEX chn, BYTE resetStyle); // Module Loaders @@ -705,6 +705,9 @@ bool ReadGDM(const LPCBYTE lpStream, const DWORD dwMemLength); bool ReadIMF(const LPCBYTE lpStream, const DWORD dwMemLength); bool ReadMID(LPCBYTE lpStream, DWORD dwMemLength); + + void SetupMODPanning(bool bForceSetup = false); // Setup LRRL panning, max channel volume + // Save Functions #ifndef MODPLUG_NO_FILESAVE UINT WriteSample(FILE *f, MODSAMPLE *pSmp, UINT nFlags, UINT nMaxLen=0); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-10-05 17:02:33
|
Revision: 387 http://modplug.svn.sourceforge.net/modplug/?rev=387&view=rev Author: saga-games Date: 2009-10-05 17:02:19 +0000 (Mon, 05 Oct 2009) Log Message: ----------- [Fix] PSM16 Loader: It was possible to load corrupted modules with > MAX_BASECHANNELS channels (up to 0xFFFF). [Fix] Instrument tab: Update plugin list properly when cleaning up plugins while being on the plugin tab (possibly also improves instrument tab behaviour when working with multiple windows) [Imp] Cleanup: Moved all cleanup functions to a separate sourcecode file, moved cleanup functions from a submenu to an own dialog Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Ctrl_ins.h trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/Load_psm.cpp Added Paths: ----------- trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/mptrack/CleanupSong.h Added: trunk/OpenMPT/mptrack/CleanupSong.cpp =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp (rev 0) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp 2009-10-05 17:02:19 UTC (rev 387) @@ -0,0 +1,813 @@ +/* + * + * CleanupSong.cpp + * --------------- + * Purpose: Interface for cleaning up modules (rearranging, removing unused items) + * + * Authors: Olivier Lapicque + * OpenMPT Devs + * + */ + +#include "stdafx.h" +#include "moddoc.h" +#include "Mainfrm.h" +#include "modsmp_ctrl.h" +#include "CleanupSong.h" + +// Default checkbox state +bool CModCleanupDlg::m_bCheckBoxes[CU_MAX_CLEANUP_OPTIONS] = +{ + true, true, + true, true, + true, false, + true, false, +}; + +// Checkbox -> Control ID LUT +WORD const CModCleanupDlg::m_nCleanupIDtoDlgID[CU_MAX_CLEANUP_OPTIONS] = +{ + IDC_CHK_CLEANUP_PATTERNS, IDC_CHK_REARRANGE_PATTERNS, + IDC_CHK_CLEANUP_SAMPLES, IDC_CHK_REARRANGE_SAMPLES, + IDC_CHK_CLEANUP_INSTRUMENTS, IDC_CHK_REMOVE_INSTRUMENTS, + IDC_CHK_CLEANUP_PLUGINS, IDC_CHK_SAMPLEPACK, +}; + +/////////////////////////////////////////////////////////////////////// +// CModCleanupDlg + +BEGIN_MESSAGE_MAP(CModCleanupDlg, CDialog) + //{{AFX_MSG_MAP(CModTypeDlg) + /*ON_COMMAND(IDC_CHK_CLEANUP_PATTERNS, OnCheckCleanupPatterns) + ON_COMMAND(IDC_CHK_REARRANGE_PATTERNS, OnCheckRearrangePatterns) + ON_COMMAND(IDC_CHK_CLEANUP_SAMPLES, OnCheckCleanupSamples) + ON_COMMAND(IDC_CHK_REARRANGE_SAMPLES, OnCheckRearrangeSamples) + ON_COMMAND(IDC_CHK_CLEANUP_INSTRUMENTS, OnCheckCleanupInstruments) + ON_COMMAND(IDC_CHK_REMOVE_INSTRUMENTS, OnCheckRemoveInstruments) + ON_COMMAND(IDC_CHK_CLEANUP_PLUGINS, OnCheckCleanupPlugins) + ON_COMMAND(IDC_CHK_SAMPLEPACK, OnCheckCreateSamplepack)*/ + + ON_COMMAND(IDC_BTN_CLEANUP_SONG, OnPresetCleanupSong) + ON_COMMAND(IDC_BTN_COMPO_CLEANUP, OnPresetCompoCleanup) + // -! NEW_FEATURE#0023 + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +BOOL CModCleanupDlg::OnInitDialog() +//--------------------------------- +{ + CDialog::OnInitDialog(); + for(int i = 0; i < CU_MAX_CLEANUP_OPTIONS; i++) + { + CheckDlgButton(m_nCleanupIDtoDlgID[i], (m_bCheckBoxes[i]) ? MF_CHECKED : MF_UNCHECKED); + } + + CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return FALSE; + + GetDlgItem(m_nCleanupIDtoDlgID[CU_CLEANUP_INSTRUMENTS])->EnableWindow((pSndFile->m_nInstruments > 0) ? TRUE :FALSE); + GetDlgItem(m_nCleanupIDtoDlgID[CU_REMOVE_INSTRUMENTS])->EnableWindow((pSndFile->m_nInstruments > 0) ? TRUE :FALSE); + GetDlgItem(m_nCleanupIDtoDlgID[CU_REARRANGE_SAMPLES])->EnableWindow((pSndFile->m_nSamples > 1) ? TRUE :FALSE); + return TRUE; +} + +void CModCleanupDlg::OnOK() +//------------------------- +{ + for(int i = 0; i < CU_MAX_CLEANUP_OPTIONS; i++) + { + m_bCheckBoxes[i] = IsDlgButtonChecked(m_nCleanupIDtoDlgID[i]) ? true : false; + } + + bool bModified = false; + m_pModDoc->ClearLog(); + + // Patterns + if(m_bCheckBoxes[CU_CLEANUP_PATTERNS]) bModified |= RemoveUnusedPatterns(); + if(m_bCheckBoxes[CU_REARRANGE_PATTERNS]) bModified |= RemoveUnusedPatterns(false); + // Instruments + if(m_pModDoc->GetSoundFile()->m_nInstruments > 0) + { + if(m_bCheckBoxes[CU_CLEANUP_INSTRUMENTS]) bModified |= RemoveUnusedInstruments(); + if(m_bCheckBoxes[CU_REMOVE_INSTRUMENTS]) bModified |= RemoveAllInstruments(); + } + // Samples + if(m_bCheckBoxes[CU_CLEANUP_SAMPLES]) bModified |= RemoveUnusedSamples(); + if(m_pModDoc->GetSoundFile()->m_nSamples > 1) + { + if(m_bCheckBoxes[CU_REARRANGE_SAMPLES]) bModified |= RearrangeSamples(); + } + // Plugins + if(m_bCheckBoxes[CU_CLEANUP_PLUGINS]) bModified |= RemoveUnusedPlugins(); + // Create samplepack + if(m_bCheckBoxes[CU_CREATE_SAMPLEPACK]) bModified |= CreateSamplepack(); + + if(bModified) m_pModDoc->SetModified(); + m_pModDoc->UpdateAllViews(NULL, HINT_MODTYPE|HINT_MODSEQUENCE|HINT_MODGENERAL); + m_pModDoc->ShowLog("Cleanup", this); + CDialog::OnOK(); +} + + +void CModCleanupDlg::OnCancel() +//------------------------- +{ + CDialog::OnCancel(); +} + + + +void CModCleanupDlg::OnPresetCleanupSong() +//---------------------------------------- +{ + CheckDlgButton(IDC_CHK_CLEANUP_PATTERNS, MF_CHECKED); + CheckDlgButton(IDC_CHK_REARRANGE_PATTERNS, MF_CHECKED); + CheckDlgButton(IDC_CHK_CLEANUP_SAMPLES, MF_CHECKED); + CheckDlgButton(IDC_CHK_REARRANGE_SAMPLES, MF_CHECKED); + CheckDlgButton(IDC_CHK_CLEANUP_INSTRUMENTS, MF_CHECKED); + CheckDlgButton(IDC_CHK_REMOVE_INSTRUMENTS, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_CLEANUP_PLUGINS, MF_CHECKED); + CheckDlgButton(IDC_CHK_SAMPLEPACK, MF_UNCHECKED); +} + +void CModCleanupDlg::OnPresetCompoCleanup() +//---------------------------------------- +{ + CheckDlgButton(IDC_CHK_CLEANUP_PATTERNS, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_REARRANGE_PATTERNS, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_CLEANUP_SAMPLES, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_REARRANGE_SAMPLES, MF_CHECKED); + CheckDlgButton(IDC_CHK_CLEANUP_INSTRUMENTS, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_REMOVE_INSTRUMENTS, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_CLEANUP_PLUGINS, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_SAMPLEPACK, MF_CHECKED); +} + + +/////////////////////////////////////////////////////////////////////// +// Actual cleanup implementations + +// Remove unused patterns / rearrange patterns +bool CModCleanupDlg::RemoveUnusedPatterns(bool bRemove) +//----------------------------------------------------- +{ + CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return false; + + if(pSndFile->GetType() == MOD_TYPE_MPT && pSndFile->Order.GetNumSequences() > 1) + { // Multiple sequences are not taken into account in the code below. For now just make + // removing unused patterns disabled in this case. + AfxMessageBox(IDS_PATTERN_CLEANUP_UNAVAILABLE, MB_ICONINFORMATION); + return false; + } + const PATTERNINDEX maxPatIndex = pSndFile->Patterns.Size(); + const ORDERINDEX maxOrdIndex = pSndFile->Order.size(); + vector<PATTERNINDEX> nPatMap(maxPatIndex, 0); + vector<ROWINDEX> nPatRows(maxPatIndex, 0); + vector<MODCOMMAND*> pPatterns(maxPatIndex, nullptr); + vector<bool> bPatUsed(maxPatIndex, false); + + bool bSubtunesDetected = false; + // detect subtunes (separated by "---") + for(SEQUENCEINDEX nSeq = 0; nSeq < pSndFile->Order.GetNumSequences(); nSeq++) + { + if(pSndFile->Order.GetSequence(nSeq).GetLengthFirstEmpty() != pSndFile->Order.GetSequence(nSeq).GetLengthTailTrimmed()) + bSubtunesDetected = true; + } + + // Flag to tell whether keeping sequence items which are after the first empty('---') order. + bool bKeepSubSequences = false; + + if(bSubtunesDetected) + { // There are used sequence items after first '---'; ask user whether to remove those. + if (m_wParent->MessageBox( + _TEXT("Do you want to remove sequence items which are after the first '---' item?"), + _TEXT("Sequence Cleanup"), MB_YESNO) != IDYES + ) + bKeepSubSequences = true; + } + + CHAR s[512]; + bool bEnd = false, bReordered = false; + UINT nPatRemoved = 0, nMinToRemove; + PATTERNINDEX nPats; + + BeginWaitCursor(); + PATTERNINDEX maxpat = 0; + for (ORDERINDEX nOrd = 0; nOrd < maxOrdIndex; nOrd++) + { + PATTERNINDEX n = pSndFile->Order[nOrd]; + if (n < maxPatIndex) + { + if (n >= maxpat) maxpat = n + 1; + if (!bEnd || bKeepSubSequences) bPatUsed[n] = true; + } else if (n == pSndFile->Order.GetInvalidPatIndex()) bEnd = true; + } + nMinToRemove = 0; + if (!bRemove) + { + PATTERNINDEX imax = maxPatIndex; + while (imax > 0) + { + imax--; + if ((pSndFile->Patterns[imax]) && (bPatUsed[imax])) break; + } + nMinToRemove = imax + 1; + } + for (PATTERNINDEX nPat = maxpat; nPat < maxPatIndex; nPat++) if ((pSndFile->Patterns[nPat]) && (nPat >= nMinToRemove)) + { + MODCOMMAND *m = pSndFile->Patterns[nPat]; + UINT ncmd = pSndFile->m_nChannels * pSndFile->PatternSize[nPat]; + for (UINT i=0; i<ncmd; i++) + { + if ((m[i].note) || (m[i].instr) || (m[i].volcmd) || (m[i].command)) goto NotEmpty; + } + pSndFile->Patterns.Remove(nPat); + nPatRemoved++; +NotEmpty: + ; + } + UINT bWaste = 0; + for (UINT ichk=0; ichk < maxPatIndex; ichk++) + { + if ((pSndFile->Patterns[ichk]) && (!bPatUsed[ichk])) bWaste++; + } + if ((bRemove) && (bWaste)) + { + EndWaitCursor(); + wsprintf(s, "%d pattern(s) present in file, but not used in the song\nDo you want to reorder the sequence list and remove these patterns?", bWaste); + if (m_wParent->MessageBox(s, "Pattern Cleanup", MB_YESNO) != IDYES) return false; + BeginWaitCursor(); + } + + for (UINT i = 0; i < maxPatIndex; i++) nPatMap[i] = PATTERNINDEX_INVALID; + nPats = 0; + ORDERINDEX imap = 0; + for (imap = 0; imap < maxOrdIndex; imap++) + { + PATTERNINDEX n = pSndFile->Order[imap]; + if (n < maxPatIndex) + { + if (nPatMap[n] > maxPatIndex) nPatMap[n] = nPats++; + pSndFile->Order[imap] = nPatMap[n]; + } else if (n == pSndFile->Order.GetInvalidPatIndex() && (bKeepSubSequences == false)) break; + } + // Add unused patterns at the end + if ((!bRemove) || (!bWaste)) + { + for (UINT iadd=0; iadd<maxPatIndex; iadd++) + { + if ((pSndFile->Patterns[iadd]) && (nPatMap[iadd] >= maxPatIndex)) + { + nPatMap[iadd] = nPats++; + } + } + } + while (imap < maxOrdIndex) + { + pSndFile->Order[imap++] = pSndFile->Order.GetInvalidPatIndex(); + } + // Reorder patterns & Delete unused patterns + BEGIN_CRITICAL(); + { + UINT npatnames = pSndFile->m_nPatternNames; + LPSTR lpszpatnames = pSndFile->m_lpszPatternNames; + pSndFile->m_nPatternNames = 0; + pSndFile->m_lpszPatternNames = NULL; + for (PATTERNINDEX i = 0; i < maxPatIndex; i++) + { + PATTERNINDEX k = nPatMap[i]; + if (k < maxPatIndex) + { + if (i != k) bReordered = true; + // Remap pattern names + if (i < npatnames) + { + UINT noldpatnames = pSndFile->m_nPatternNames; + LPSTR lpszoldpatnames = pSndFile->m_lpszPatternNames; + pSndFile->m_nPatternNames = npatnames; + pSndFile->m_lpszPatternNames = lpszpatnames; + pSndFile->GetPatternName(i, s); + pSndFile->m_nPatternNames = noldpatnames; + pSndFile->m_lpszPatternNames = lpszoldpatnames; + if (s[0]) pSndFile->SetPatternName(k, s); + } + nPatRows[k] = pSndFile->PatternSize[i]; + pPatterns[k] = pSndFile->Patterns[i]; + } else + if (pSndFile->Patterns[i]) + { + pSndFile->Patterns.Remove(i); + nPatRemoved++; + } + } + for (PATTERNINDEX j = 0; j < maxPatIndex;j++) + { + pSndFile->Patterns[j].SetData(pPatterns[j], nPatRows[j]); + } + } + END_CRITICAL(); + EndWaitCursor(); + if ((nPatRemoved) || (bReordered)) + { + m_pModDoc->ClearUndo(); + if (nPatRemoved) + { + wsprintf(s, "%d pattern(s) removed.\n", nPatRemoved); + m_pModDoc->AddToLog(s); + } + return true; + } + return false; +} + + +// Remove unused samples +bool CModCleanupDlg::RemoveUnusedSamples() +//--------------------------------- +{ + CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return false; + + CHAR s[512]; + BOOL bIns[MAX_SAMPLES]; + UINT nExt = 0, nLoopOpt = 0; + UINT nRemoved = 0; + + BeginWaitCursor(); + for (SAMPLEINDEX nSmp = pSndFile->m_nSamples; nSmp >= 1; nSmp--) if (pSndFile->Samples[nSmp].pSample) + { + if (!pSndFile->IsSampleUsed(nSmp)) + { + BEGIN_CRITICAL(); + pSndFile->DestroySample(nSmp); + if ((nSmp == pSndFile->m_nSamples) && (nSmp > 1)) pSndFile->m_nSamples--; + END_CRITICAL(); + nRemoved++; + } + } + if (pSndFile->m_nInstruments) + { + memset(bIns, 0, sizeof(bIns)); + for (UINT ipat=0; ipat<pSndFile->Patterns.Size(); ipat++) + { + MODCOMMAND *p = pSndFile->Patterns[ipat]; + if (p) + { + UINT jmax = pSndFile->PatternSize[ipat] * pSndFile->m_nChannels; + for (UINT j=0; j<jmax; j++, p++) + { + if ((p->note) && (p->note <= NOTE_MAX)) + { + if ((p->instr) && (p->instr < MAX_INSTRUMENTS)) + { + MODINSTRUMENT *pIns = pSndFile->Instruments[p->instr]; + if (pIns) + { + UINT n = pIns->Keyboard[p->note-1]; + if (n < MAX_SAMPLES) bIns[n] = TRUE; + } + } else + { + for (UINT k=1; k<=pSndFile->m_nInstruments; k++) + { + MODINSTRUMENT *pIns = pSndFile->Instruments[k]; + if (pIns) + { + UINT n = pIns->Keyboard[p->note-1]; + if (n < MAX_SAMPLES) bIns[n] = TRUE; + } + } + } + } + } + } + } + for (UINT ichk=1; ichk<MAX_SAMPLES; ichk++) + { + if ((!bIns[ichk]) && (pSndFile->Samples[ichk].pSample)) nExt++; + } + } + EndWaitCursor(); + if (nExt && !((pSndFile->m_nType & MOD_TYPE_IT) && (pSndFile->m_dwSongFlags&SONG_ITPROJECT))) + { //We don't remove an instrument's unused samples in an ITP. + wsprintf(s, "OpenMPT detected %d sample(s) referenced by an instrument,\n" + "but not used in the song. Do you want to remove them ?", nExt); + if (::MessageBox(NULL, s, "Sample Cleanup", MB_YESNO | MB_ICONQUESTION) == IDYES) + { + for (SAMPLEINDEX j = 1; j < MAX_SAMPLES; j++) + { + if ((!bIns[j]) && (pSndFile->Samples[j].pSample)) + { + BEGIN_CRITICAL(); + pSndFile->DestroySample(j); + if ((j == pSndFile->m_nSamples) && (j > 1)) pSndFile->m_nSamples--; + END_CRITICAL(); + nRemoved++; + } + } + } + } + for (SAMPLEINDEX ilo=1; ilo<=pSndFile->m_nSamples; ilo++) if (pSndFile->Samples[ilo].pSample) + { + if ((pSndFile->Samples[ilo].uFlags & CHN_LOOP) + && (pSndFile->Samples[ilo].nLength > pSndFile->Samples[ilo].nLoopEnd + 2)) nLoopOpt++; + } + if (nLoopOpt) + { + wsprintf(s, "OpenMPT detected %d sample(s) with unused data after the loop end point,\n" + "Do you want to optimize it, and remove this unused data ?", nLoopOpt); + if (::MessageBox(NULL, s, "Sample Cleanup", MB_YESNO | MB_ICONQUESTION) == IDYES) + { + for (UINT j=1; j<=pSndFile->m_nSamples; j++) + { + if ((pSndFile->Samples[j].uFlags & CHN_LOOP) + && (pSndFile->Samples[j].nLength > pSndFile->Samples[j].nLoopEnd + 2)) + { + UINT lmax = pSndFile->Samples[j].nLoopEnd + 2; + if ((lmax < pSndFile->Samples[j].nLength) && (lmax >= 16)) pSndFile->Samples[j].nLength = lmax; + } + } + } else nLoopOpt = 0; + } + if ((nRemoved) || (nLoopOpt)) + { + if (nRemoved) + { + wsprintf(s, "%d unused sample(s) removed\n" ,nRemoved); + m_pModDoc->AddToLog(s); + } + if (nLoopOpt) + { + wsprintf(s, "%d sample loop(s) optimized\n" ,nLoopOpt); + m_pModDoc->AddToLog(s); + } + return true; + } + return false; +} + + +// Rearrange sample list +bool CModCleanupDlg::RearrangeSamples() +//------------------------------------- +{ + CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return false; + + if(pSndFile->m_nSamples < 2) + return false; + + SAMPLEINDEX nRemap = 0; // remap count + SAMPLEINDEX nSampleMap[MAX_SAMPLES + 1]; // map old => new + for(SAMPLEINDEX i = 0; i <= MAX_SAMPLES; i++) + nSampleMap[i] = i; + + // First, find out which sample slots are unused and create the new sample map + for(SAMPLEINDEX i = 1 ; i <= pSndFile->m_nSamples; i++) { + if(!pSndFile->Samples[i].pSample) + { + // Move all following samples + nRemap++; + nSampleMap[i] = 0; + for(UINT j = i + 1; j <= pSndFile->m_nSamples; j++) + nSampleMap[j]--; + } + } + + if(!nRemap) + return false; + + BEGIN_CRITICAL(); + + // Now, move everything around + for(SAMPLEINDEX i = 1; i <= pSndFile->m_nSamples; i++) + { + if(nSampleMap[i] != i) + { + // This gotta be moved + pSndFile->MoveSample(i, nSampleMap[i]); + pSndFile->Samples[i].pSample = nullptr; + if(nSampleMap[i] > 0) strcpy(pSndFile->m_szNames[nSampleMap[i]], pSndFile->m_szNames[i]); + memset(pSndFile->m_szNames[i], 0, sizeof(pSndFile->m_szNames[i])); + + // Also update instrument mapping (if module is in instrument mode) + for(INSTRUMENTINDEX iInstr = 1; iInstr <= pSndFile->m_nInstruments; iInstr++){ + if(pSndFile->Instruments[iInstr]){ + MODINSTRUMENT *p = pSndFile->Instruments[iInstr]; + for(WORD iNote = 0; iNote < 128; iNote++) + if(p->Keyboard[iNote] == i) p->Keyboard[iNote] = nSampleMap[i]; + } + } + } + } + + // Go through the patterns and remap samples (if module is in sample mode) + if(!pSndFile->m_nInstruments) + { + for (PATTERNINDEX nPat = 0; nPat < pSndFile->Patterns.Size(); nPat++) if (pSndFile->Patterns[nPat]) + { + MODCOMMAND *m = pSndFile->Patterns[nPat]; + for(UINT len = pSndFile->PatternSize[nPat] * pSndFile->m_nChannels; len; m++, len--) + { + if(m->instr <= pSndFile->m_nSamples) m->instr = (BYTE)nSampleMap[m->instr]; + } + } + } + + pSndFile->m_nSamples -= nRemap; + + END_CRITICAL(); + + return true; + +} + + +// Remove unused instruments +bool CModCleanupDlg::RemoveUnusedInstruments() +//-------------------------------------------- +{ + CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return false; + + INSTRUMENTINDEX usedmap[MAX_INSTRUMENTS]; + INSTRUMENTINDEX swapmap[MAX_INSTRUMENTS]; + INSTRUMENTINDEX swapdest[MAX_INSTRUMENTS]; + CHAR s[512]; + UINT nRemoved = 0; + INSTRUMENTINDEX nSwap, nIndex; + bool bReorg = false; + + if (!pSndFile->m_nInstruments) return false; + + char removeSamples = -1; + if ( !((pSndFile->m_nType & MOD_TYPE_IT) && (pSndFile->m_dwSongFlags&SONG_ITPROJECT))) { //never remove an instrument's samples in ITP. + if(::MessageBox(NULL, "Remove samples associated with an instrument if they are unused?", "Removing unused instruments", MB_YESNO | MB_ICONQUESTION) == IDYES) { + removeSamples = 1; + } + } else { + ::MessageBox(NULL, "This is an IT project file, so no samples associated with a used instrument will be removed.", "Removing unused instruments", MB_OK | MB_ICONINFORMATION); + } + + BeginWaitCursor(); + memset(usedmap, 0, sizeof(usedmap)); + + for(INSTRUMENTINDEX i = pSndFile->m_nInstruments; i >= 1; i--) + { + if (!pSndFile->IsInstrumentUsed(i)) + { + BEGIN_CRITICAL(); + // -> CODE#0003 + // -> DESC="remove instrument's samples" + // pSndFile->DestroyInstrument(i); + pSndFile->DestroyInstrument(i, removeSamples); + // -! BEHAVIOUR_CHANGE#0003 + if ((i == pSndFile->m_nInstruments) && (i>1)) pSndFile->m_nInstruments--; else bReorg = true; + END_CRITICAL(); + nRemoved++; + } else + { + usedmap[i] = 1; + } + } + EndWaitCursor(); + if ((bReorg) && (pSndFile->m_nInstruments > 1) + && (::MessageBox(NULL, "Do you want to reorganize the remaining instruments?", "Removing unused instruments", MB_YESNO | MB_ICONQUESTION) == IDYES)) + { + BeginWaitCursor(); + BEGIN_CRITICAL(); + nSwap = 0; + nIndex = 1; + for (INSTRUMENTINDEX nIns = 1; nIns <= pSndFile->m_nInstruments; nIns++) + { + if (usedmap[nIns]) + { + while (nIndex<nIns) + { + if ((!usedmap[nIndex]) && (!pSndFile->Instruments[nIndex])) + { + swapmap[nSwap] = nIns; + swapdest[nSwap] = nIndex; + pSndFile->Instruments[nIndex] = pSndFile->Instruments[nIns]; + pSndFile->Instruments[nIns] = nullptr; + usedmap[nIndex] = 1; + usedmap[nIns] = 0; + nSwap++; + nIndex++; + break; + } + nIndex++; + } + } + } + while ((pSndFile->m_nInstruments > 1) && (!pSndFile->Instruments[pSndFile->m_nInstruments])) pSndFile->m_nInstruments--; + END_CRITICAL(); + if (nSwap > 0) + { + for (PATTERNINDEX iPat = 0; iPat < pSndFile->Patterns.Size(); iPat++) if (pSndFile->Patterns[iPat]) + { + MODCOMMAND *p = pSndFile->Patterns[iPat]; + UINT nLen = pSndFile->m_nChannels * pSndFile->PatternSize[iPat]; + while (nLen--) + { + if (p->instr) + { + for (UINT k=0; k<nSwap; k++) + { + if (p->instr == swapmap[k]) p->instr = (BYTE)swapdest[k]; + } + } + p++; + } + } + } + EndWaitCursor(); + } + if (nRemoved) + { + wsprintf(s, "%d unused instrument(s) removed\n", nRemoved); + m_pModDoc->AddToLog(s); + return true; + } + return false; +} + + +// Remove all instruments +bool CModCleanupDlg::RemoveAllInstruments(bool bConfirm) +//----------------------------------------------- +{ + CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return false; + + if (!pSndFile->m_nInstruments) + return false; + + char removeSamples = -1; + if(bConfirm) + { + if (CMainFrame::GetMainFrame()->MessageBox("This will remove all the instruments in the song,\n" + "Do you want to continue?", "Removing all instruments", MB_YESNO | MB_ICONQUESTION) != IDYES) return false; + if (CMainFrame::GetMainFrame()->MessageBox("Do you want to convert all instruments to samples ?\n", + "Removing all instruments", MB_YESNO | MB_ICONQUESTION) == IDYES) + { + m_pModDoc->ConvertInstrumentsToSamples(); + } + + if (::MessageBox(NULL, "Remove samples associated with an instrument if they are unused?", "Removing all instruments", MB_YESNO | MB_ICONQUESTION) == IDYES) { + removeSamples = 1; + } + } + + for (INSTRUMENTINDEX i = 1; i <= pSndFile->m_nInstruments; i++) + { + pSndFile->DestroyInstrument(i, removeSamples); + } + + pSndFile->m_nInstruments = 0; + return true; +} + + +// Remove ununsed plugins +bool CModCleanupDlg::RemoveUnusedPlugins() +//-------------------------------------- +{ + CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return false; + + bool usedmap[MAX_MIXPLUGINS]; + memset(usedmap, false, sizeof(usedmap)); + + for (PLUGINDEX nPlug = 0; nPlug < MAX_MIXPLUGINS; nPlug++) { + + //Is the plugin assigned to a channel? + for (CHANNELINDEX nChn = 0; nChn < pSndFile->GetNumChannels(); nChn++) { + if (pSndFile->ChnSettings[nChn].nMixPlugin == nPlug + 1u) { + usedmap[nPlug] = true; + break; + } + } + + //Is the plugin used by an instrument? + for (INSTRUMENTINDEX nIns=1; nIns<=pSndFile->GetNumInstruments(); nIns++) { + if (pSndFile->Instruments[nIns] && (pSndFile->Instruments[nIns]->nMixPlug == nPlug+1)) { + usedmap[nPlug] = true; + break; + } + } + + //Is the plugin assigned to master? + if (pSndFile->m_MixPlugins[nPlug].Info.dwInputRouting & MIXPLUG_INPUTF_MASTEREFFECT) { + usedmap[nPlug] = true; + } + + //all outputs of used plugins count as used + if (usedmap[nPlug]!=0) { + if (pSndFile->m_MixPlugins[nPlug].Info.dwOutputRouting & 0x80) { + int output = pSndFile->m_MixPlugins[nPlug].Info.dwOutputRouting & 0x7f; + usedmap[output] = true; + } + } + + } + + UINT nRemoved = m_pModDoc->RemovePlugs(usedmap); + + return (nRemoved > 0) ? true : false; +} + + +// Turn module into samplepack (convert to IT, remove patterns, etc.) +bool CModCleanupDlg::CreateSamplepack() +//------------------------------------- +{ + CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return false; + + //jojo.compocleanup + if(::MessageBox(NULL, TEXT("WARNING: Turning this module into as samplepack means that OpenMPT will convert the module to IT format, remove all patterns and reset song, sample and instrument attributes to default values. Continue?"), TEXT("Samplepack creation"), MB_YESNO | MB_ICONWARNING) == IDNO) + return false; + + // Stop play. + CMainFrame::GetMainFrame()->StopMod(m_pModDoc); + + BeginWaitCursor(); + BEGIN_CRITICAL(); + + // convert to IT... + m_pModDoc->ChangeModType(MOD_TYPE_IT); + pSndFile->m_nMixLevels = mixLevels_original; + pSndFile->m_nTempoMode = tempo_mode_classic; + pSndFile->m_dwSongFlags = SONG_LINEARSLIDES | SONG_EXFILTERRANGE; + + // clear order list + pSndFile->Order.Init(); + pSndFile->Order[0] = 0; + + // remove all patterns + pSndFile->Patterns.Init(); + pSndFile->Patterns.Insert(0, 64); + pSndFile->SetCurrentOrder(0); + + // Global vars + pSndFile->m_nDefaultTempo = 125; + pSndFile->m_nDefaultSpeed = 6; + pSndFile->m_nDefaultGlobalVolume = 256; + pSndFile->m_nSamplePreAmp = 48; + pSndFile->m_nVSTiVolume = 48; + pSndFile->m_nRestartPos = 0; + + // Set 4 default channels. + pSndFile->ReArrangeChannels(vector<CHANNELINDEX>(4, MAX_BASECHANNELS)); + + // remove plugs + bool keepMask[MAX_MIXPLUGINS]; memset(keepMask, 0, sizeof(keepMask)); + m_pModDoc->RemovePlugs(keepMask); + + // instruments + if(pSndFile->m_nInstruments && ::MessageBox(NULL, "Keep instruments?", TEXT("Samplepack creation"), MB_YESNO | MB_ICONQUESTION) == IDNO) + { + // remove instruments + RemoveAllInstruments(false); + } + else + { + // reset instruments (if there are any) + for(INSTRUMENTINDEX i = 1; i <= pSndFile->m_nInstruments; i++) + { + pSndFile->Instruments[i]->nFadeOut = 256; + pSndFile->Instruments[i]->nGlobalVol = 64; + pSndFile->Instruments[i]->nPan = 128; + pSndFile->Instruments[i]->dwFlags &= ~ENV_SETPANNING; + pSndFile->Instruments[i]->nMixPlug = 0; + + pSndFile->Instruments[i]->nVolSwing = 0; + pSndFile->Instruments[i]->nPanSwing = 0; + pSndFile->Instruments[i]->nCutSwing = 0; + pSndFile->Instruments[i]->nResSwing = 0; + + //might be a good idea to leave those enabled... + /* + pSndFile->Instruments[i]->dwFlags &= ~ENV_VOLUME; + pSndFile->Instruments[i]->dwFlags &= ~ENV_PANNING; + pSndFile->Instruments[i]->dwFlags &= ~ENV_PITCH; + pSndFile->Instruments[i]->dwFlags &= ~ENV_FILTER; + */ + } + } + + // reset samples + ctrlSmp::ResetSamples(*pSndFile, ctrlSmp::SmpResetCompo); + + // Set modflags. + pSndFile->SetModFlag(MSF_MIDICC_BUGEMULATION, false); + pSndFile->SetModFlag(MSF_OLDVOLSWING, false); + pSndFile->SetModFlag(MSF_COMPATIBLE_PLAY, true); + + END_CRITICAL(); + EndWaitCursor(); + + return true; +} Added: trunk/OpenMPT/mptrack/CleanupSong.h =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.h (rev 0) +++ trunk/OpenMPT/mptrack/CleanupSong.h 2009-10-05 17:02:19 UTC (rev 387) @@ -0,0 +1,67 @@ +/* + * + * CleanupSong.h + * --------------- + * Purpose: Header file for CleanupSong.cpp + * + */ + +#pragma once + +enum ENUM_CLEANUP_OPTIONS +{ + CU_CLEANUP_PATTERNS = 0, + CU_REARRANGE_PATTERNS, + CU_CLEANUP_SAMPLES, + CU_REARRANGE_SAMPLES, + CU_CLEANUP_INSTRUMENTS, + CU_REMOVE_INSTRUMENTS, + CU_CLEANUP_PLUGINS, + CU_CREATE_SAMPLEPACK, + CU_MAX_CLEANUP_OPTIONS +}; + +//================================== +class CModCleanupDlg: public CDialog +//================================== +{ +private: + CModDoc *m_pModDoc; + CWnd *m_wParent; + static bool m_bCheckBoxes[CU_MAX_CLEANUP_OPTIONS]; // Checkbox state + static const WORD m_nCleanupIDtoDlgID[CU_MAX_CLEANUP_OPTIONS]; // Checkbox -> Control ID LUT + + // Actual cleanup implementations + bool RemoveUnusedPatterns(bool bRemove = true); // Remove unused patterns / rearrange patterns + bool RemoveUnusedSamples(); // Remove unused samples + bool RearrangeSamples(); // Rearrange sample list + bool RemoveUnusedInstruments(); // Remove unused instruments + bool RemoveAllInstruments(bool bConfirm = true); // Remove all instruments + bool RemoveUnusedPlugins(); // Remove ununsed plugins + bool CreateSamplepack(); // Turn module into samplepack (convert to IT, remove patterns, etc.) + +public: + CModCleanupDlg(CModDoc *pModDoc, CWnd *parent):CDialog(IDD_CLEANUP_SONG, parent) { m_pModDoc = pModDoc; m_wParent = parent; } + +protected: + //{{AFX_VIRTUAL(CModCleanupDlg) + virtual BOOL OnInitDialog(); + virtual void OnOK(); + virtual void OnCancel(); + //}}AFX_VIRTUAL + + //{{AFX_MSG(CModCleanupDlg) + /*afx_msg void OnCheckCleanupPatterns(); + afx_msg void OnCheckRearrangePatterns(); + afx_msg void OnCheckCleanupSamples(); + afx_msg void OnCheckRearrangeSamples(); + afx_msg void OnCheckCleanupInstruments(); + afx_msg void OnCheckRemoveInstruments(); + afx_msg void OnCheckCleanupPlugins(); + afx_msg void OnCheckCreateSamplepack();*/ + + afx_msg void OnPresetCleanupSong(); + afx_msg void OnPresetCompoCleanup(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; \ No newline at end of file Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-10-04 18:13:30 UTC (rev 386) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-10-05 17:02:19 UTC (rev 387) @@ -932,34 +932,8 @@ } } - //rewbs.instroVSTi - //Update plugin list - m_CbnMixPlug.Clear(); - m_CbnMixPlug.ResetContent(); - CHAR s[64]; - for (UINT plug=0; plug<=MAX_MIXPLUGINS; plug++) - { - s[0] = 0; - if (!plug) - { - strcpy(s, "No plugin"); - } - else - { - PSNDMIXPLUGIN p = &(m_pSndFile->m_MixPlugins[plug-1]); - p->Info.szLibraryName[63] = 0; - if (p->Info.szLibraryName[0]) - wsprintf(s, "FX%d: %s", plug, p->Info.szName); - else - wsprintf(s, "FX%d: undefined", plug); - } + UpdatePluginList(); - m_CbnMixPlug.SetItemData(m_CbnMixPlug.AddString(s), plug); - } - MODINSTRUMENT *pIns = m_pSndFile->Instruments[m_nInstrument]; - if ((pIns) && (pIns->nMixPlug < MAX_MIXPLUGINS)) m_CbnMixPlug.SetCurSel(pIns->nMixPlug); - //end rewbs.instroVSTi - SetCurrentInstrument((lParam > 0) ? lParam : m_nInstrument); // Initial Update @@ -1236,6 +1210,11 @@ } m_NoteMap.InvalidateRect(NULL, FALSE); } + if(dwHintMask & (HINT_MIXPLUGINS|HINT_MODTYPE)) + { + UpdatePluginList(); + } + if (!m_bInitialized) { // First update @@ -2818,3 +2797,33 @@ m_ComboTuning.AddString("Control tunings..."); m_ComboTuning.SetCurSel(0); } + +void CCtrlInstruments::UpdatePluginList() +//--------------------------------------- +{ + //Update plugin list + m_CbnMixPlug.Clear(); + m_CbnMixPlug.ResetContent(); + CHAR s[64]; + for (PLUGINDEX nPlug = 0; nPlug <= MAX_MIXPLUGINS; nPlug++) + { + s[0] = 0; + if (!nPlug) + { + strcpy(s, "No plugin"); + } + else + { + PSNDMIXPLUGIN p = &(m_pSndFile->m_MixPlugins[nPlug-1]); + p->Info.szLibraryName[63] = 0; + if (p->Info.szLibraryName[0]) + wsprintf(s, "FX%d: %s", nPlug, p->Info.szName); + else + wsprintf(s, "FX%d: undefined", nPlug); + } + + m_CbnMixPlug.SetItemData(m_CbnMixPlug.AddString(s), nPlug); + } + MODINSTRUMENT *pIns = m_pSndFile->Instruments[m_nInstrument]; + if ((pIns) && (pIns->nMixPlug < MAX_MIXPLUGINS)) m_CbnMixPlug.SetCurSel(pIns->nMixPlug); +} Modified: trunk/OpenMPT/mptrack/Ctrl_ins.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.h 2009-10-04 18:13:30 UTC (rev 386) +++ trunk/OpenMPT/mptrack/Ctrl_ins.h 2009-10-05 17:02:19 UTC (rev 387) @@ -84,6 +84,8 @@ void UpdateTuningComboBox(); void BuildTuningComboBox(); + void UpdatePluginList(); + //Pitch/Tempo lock CEdit m_EditPitchTempoLock; CButton m_CheckPitchTempoLock; Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-04 18:13:30 UTC (rev 386) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-05 17:02:19 UTC (rev 387) @@ -14,6 +14,7 @@ #include "vstplug.h" #include "version.h" #include "modsmp_ctrl.h" +#include "CleanupSong.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -52,27 +53,14 @@ ON_COMMAND(ID_INSERT_PATTERN, OnInsertPattern) ON_COMMAND(ID_INSERT_SAMPLE, OnInsertSample) ON_COMMAND(ID_INSERT_INSTRUMENT, OnInsertInstrument) - ON_COMMAND(ID_CLEANUP_SAMPLES, OnCleanupSamples) - ON_COMMAND(ID_CLEANUP_INSTRUMENTS, OnCleanupInstruments) - ON_COMMAND(ID_CLEANUP_PLUGS, OnCleanupPlugs) - ON_COMMAND(ID_CLEANUP_PATTERNS, OnCleanupPatterns) - ON_COMMAND(ID_CLEANUP_SONG, OnCleanupSong) - ON_COMMAND(ID_CLEANUP_REARRANGE, OnRearrangePatterns) - ON_COMMAND(ID_CLEANUP_COMPO, OnCompoCleanup) - ON_COMMAND(ID_INSTRUMENTS_REMOVEALL,OnRemoveAllInstruments) -// -> CODE#0020 -// -> DESC="rearrange sample list" - ON_COMMAND(ID_REARRANGE_SAMPLES, RearrangeSamples) -// -! NEW_FEATURE#0020 + ON_COMMAND(ID_EDIT_CLEANUP, OnShowCleanup) + ON_COMMAND(ID_ESTIMATESONGLENGTH, OnEstimateSongLength) ON_COMMAND(ID_APPROX_BPM, OnApproximateBPM) ON_COMMAND(ID_PATTERN_PLAY, OnPatternPlay) //rewbs.patPlayAllViews ON_COMMAND(ID_PATTERN_PLAYNOLOOP, OnPatternPlayNoLoop) //rewbs.patPlayAllViews ON_COMMAND(ID_PATTERN_RESTART, OnPatternRestart) //rewbs.patPlayAllViews ON_UPDATE_COMMAND_UI(ID_INSERT_INSTRUMENT, OnUpdateXMITMPTOnly) - ON_UPDATE_COMMAND_UI(ID_INSTRUMENTS_REMOVEALL, OnUpdateInstrumentOnly) - ON_UPDATE_COMMAND_UI(ID_CLEANUP_INSTRUMENTS, OnUpdateInstrumentOnly) - ON_UPDATE_COMMAND_UI(ID_REARRANGE_SAMPLES, OnUpdateSampleCount) ON_UPDATE_COMMAND_UI(ID_VIEW_INSTRUMENTS, OnUpdateXMITMPTOnly) ON_UPDATE_COMMAND_UI(ID_VIEW_COMMENTS, OnUpdateXMITMPTOnly) ON_UPDATE_COMMAND_UI(ID_VIEW_MIDIMAPPING, OnUpdateHasMIDIMappings) @@ -1835,89 +1823,14 @@ //end rewbs.graph -void CModDoc::OnCleanupSamples() -//------------------------------ -{ - ClearLog(); - RemoveUnusedSamples(); - UpdateAllViews(NULL, HINT_MODTYPE); - ShowLog("Sample Cleanup", CMainFrame::GetMainFrame()); -} - - -void CModDoc::OnCleanupInstruments() -//---------------------------------- -{ - ClearLog(); - RemoveUnusedInstruments(); - UpdateAllViews(NULL, HINT_MODTYPE); - ShowLog("Instrument Cleanup", CMainFrame::GetMainFrame()); -} - -void CModDoc::OnCleanupPlugs() -//---------------------------------- -{ - ClearLog(); - RemoveUnusedPlugs(); - UpdateAllViews(NULL, HINT_MODTYPE); - ShowLog("Plugin Cleanup", CMainFrame::GetMainFrame()); -} - - - -void CModDoc::OnCleanupPatterns() -//------------------------------- -{ - ClearLog(); - RemoveUnusedPatterns(); - UpdateAllViews(NULL, HINT_MODTYPE|HINT_MODSEQUENCE); - ShowLog("Pattern Cleanup", CMainFrame::GetMainFrame()); -} - - -void CModDoc::OnCleanupSong() +void CModDoc::OnShowCleanup() //--------------------------- { - ClearLog(); - RemoveUnusedPatterns(); - RemoveUnusedInstruments(); - RemoveUnusedSamples(); - RemoveUnusedPlugs(); - UpdateAllViews(NULL, HINT_MODTYPE|HINT_MODSEQUENCE); - ShowLog("Song Cleanup", CMainFrame::GetMainFrame()); + CModCleanupDlg dlg(this, CMainFrame::GetMainFrame()); + dlg.DoModal(); } -void CModDoc::OnRearrangePatterns() -//--------------------------------- -{ - ClearLog(); - RemoveUnusedPatterns(FALSE); - UpdateAllViews(NULL, HINT_MODTYPE|HINT_MODSEQUENCE); - ShowLog("Pattern Rearrange", CMainFrame::GetMainFrame()); -} - -void CModDoc::OnCompoCleanup() -//------------------------------ -{ - CompoCleanup(); - UpdateAllViews(NULL, HINT_MODTYPE); -} - - - -void CModDoc::OnUpdateInstrumentOnly(CCmdUI *p) -//--------------------------------------------- -{ - if (p) p->Enable((m_SndFile.m_nInstruments) ? TRUE : FALSE); -} - -void CModDoc::OnUpdateSampleCount(CCmdUI *p) -//------------------------------------------ -{ - if (p) p->Enable((m_SndFile.m_nSamples > 1) ? TRUE : FALSE); -} - void CModDoc::OnUpdateHasMIDIMappings(CCmdUI *p) //---------------------------------------------- { @@ -1977,13 +1890,7 @@ } -void CModDoc::OnRemoveAllInstruments() -//------------------------------------ -{ - RemoveAllInstruments(); -} - void CModDoc::OnEstimateSongLength() //---------------------------------- { Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-10-04 18:13:30 UTC (rev 386) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-10-05 17:02:19 UTC (rev 387) @@ -189,15 +189,8 @@ BOOL ChangeModType(UINT nNewType); BOOL ChangeNumChannels(UINT nNewChannels, const bool showCancelInRemoveDlg = true); - BOOL ConvertInstrumentsToSamples();; - BOOL RemoveUnusedSamples(); - BOOL RemoveUnusedInstruments(); - void RemoveAllInstruments(bool bConfirm = true); - BOOL RemoveUnusedPlugs(); + BOOL ConvertInstrumentsToSamples(); UINT RemovePlugs(const bool (&keepMask)[MAX_MIXPLUGINS]); - BOOL RemoveUnusedPatterns(BOOL bRemove=TRUE); - void RearrangeSamples(); - BOOL CompoCleanup(); PATTERNINDEX InsertPattern(ORDERINDEX nOrd = -1, ROWINDEX nRows = 64); SAMPLEINDEX InsertSample(bool bLimit = false); @@ -242,7 +235,7 @@ BOOL IsChildSample(UINT nIns, UINT nSmp) const; UINT FindSampleParent(UINT nSmp) const; UINT FindInstrumentChild(UINT nIns) const; - bool MoveOrder(ORDERINDEX nSourceNdx, ORDERINDEX nDestNdx, bool bUpdate = true, bool bCopy = false); + bool MoveOrder(ORDERINDEX nSourceNdx, ORDERINDEX nDestNdx, bool bUpdate = true, bool bCopy = false, SEQUENCEINDEX nSourceSeq = SEQUENCEINDEX_INVALID, SEQUENCEINDEX nDestSeq = SEQUENCEINDEX_INVALID); BOOL ExpandPattern(PATTERNINDEX nPattern); BOOL ShrinkPattern(PATTERNINDEX nPattern); BOOL CopyPattern(PATTERNINDEX nPattern, DWORD dwBeginSel, DWORD dwEndSel); @@ -332,20 +325,11 @@ afx_msg void OnInsertPattern(); afx_msg void OnInsertSample(); afx_msg void OnInsertInstrument(); - afx_msg void OnCleanupSamples(); - afx_msg void OnCleanupInstruments(); - afx_msg void OnCleanupPlugs(); - afx_msg void OnCleanupPatterns(); - afx_msg void OnCleanupSong(); - afx_msg void OnRearrangePatterns(); - afx_msg void OnCompoCleanup(); - afx_msg void OnRemoveAllInstruments(); + afx_msg void OnShowCleanup(); afx_msg void OnEstimateSongLength(); afx_msg void OnApproximateBPM(); afx_msg void OnUpdateXMITMPTOnly(CCmdUI *p); afx_msg void OnUpdateHasMIDIMappings(CCmdUI *p); - afx_msg void OnUpdateInstrumentOnly(CCmdUI *pCmdUI); - afx_msg void OnUpdateSampleCount(CCmdUI *pCmdUI); afx_msg void OnUpdateMP3Encode(CCmdUI *pCmdUI); afx_msg void OnPatternRestart(); //rewbs.customKeys afx_msg void OnPatternPlay(); //rewbs.customKeys Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-04 18:13:30 UTC (rev 386) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-05 17:02:19 UTC (rev 387) @@ -1007,251 +1007,6 @@ } -BOOL CModDoc::RemoveUnusedPatterns(BOOL bRemove) -//---------------------------------------------- -{ - if (GetSoundFile()->GetType() == MOD_TYPE_MPT && GetSoundFile()->Order.GetNumSequences() > 1) - { // Multiple sequences are not taken into account in the code below. For now just make - // removing unused patterns disabled in this case. - AfxMessageBox(IDS_PATTERN_CLEANUP_UNAVAILABLE, MB_ICONINFORMATION); - return FALSE; - } - const UINT maxPatIndex = m_SndFile.Patterns.Size(); - const UINT maxOrdIndex = m_SndFile.Order.size(); - vector<UINT> nPatMap(maxPatIndex, 0); - vector<UINT> nPatRows(maxPatIndex, 0); - vector<MODCOMMAND*> pPatterns(maxPatIndex, NULL); - vector<BOOL> bPatUsed(maxPatIndex, false); - - bool bSubtunesDetected = false; - // detect subtunes (separated by "---") - for(SEQUENCEINDEX nSeq = 0; nSeq < m_SndFile.Order.GetNumSequences(); nSeq++) - { - if(m_SndFile.Order.GetSequence(nSeq).GetLengthFirstEmpty() != m_SndFile.Order.GetSequence(nSeq).GetLengthTailTrimmed()) - bSubtunesDetected = true; - } - - // Flag to tell whether keeping sequence items which are after the first empty('---') order. - bool bKeepSubSequences = false; - - if(bSubtunesDetected) - { // There are used sequence items after first '---'; ask user whether to remove those. - if (CMainFrame::GetMainFrame()->MessageBox( - _TEXT("Do you want to remove sequence items which are after the first '---' item?"), - _TEXT("Sequence Cleanup"), MB_YESNO) != IDYES - ) - bKeepSubSequences = true; - } - - CHAR s[512]; - BOOL bEnd = FALSE, bReordered = FALSE; - UINT nPatRemoved = 0, nMinToRemove, nPats; - - BeginWaitCursor(); - UINT maxpat = 0; - for (UINT iord=0; iord<maxOrdIndex; iord++) - { - UINT n = m_SndFile.Order[iord]; - if (n < maxPatIndex) - { - if (n >= maxpat) maxpat = n+1; - if (!bEnd || bKeepSubSequences) bPatUsed[n] = TRUE; - } else if (n == m_SndFile.Order.GetInvalidPatIndex()) bEnd = TRUE; - } - nMinToRemove = 0; - if (!bRemove) - { - UINT imax = maxPatIndex; - while (imax > 0) - { - imax--; - if ((m_SndFile.Patterns[imax]) && (bPatUsed[imax])) break; - } - nMinToRemove = imax+1; - } - for (UINT ipat=maxpat; ipat<maxPatIndex; ipat++) if ((m_SndFile.Patterns[ipat]) && (ipat >= nMinToRemove)) - { - MODCOMMAND *m = m_SndFile.Patterns[ipat]; - UINT ncmd = m_SndFile.m_nChannels * m_SndFile.PatternSize[ipat]; - for (UINT i=0; i<ncmd; i++) - { - if ((m[i].note) || (m[i].instr) || (m[i].volcmd) || (m[i].command)) goto NotEmpty; - } - m_SndFile.Patterns.Remove(ipat); - nPatRemoved++; - NotEmpty: - ; - } - UINT bWaste = 0; - for (UINT ichk=0; ichk < maxPatIndex; ichk++) - { - if ((m_SndFile.Patterns[ichk]) && (!bPatUsed[ichk])) bWaste++; - } - if ((bRemove) && (bWaste)) - { - EndWaitCursor(); - wsprintf(s, "%d pattern(s) present in file, but not used in the song\nDo you want to reorder the sequence list and remove these patterns?", bWaste); - if (CMainFrame::GetMainFrame()->MessageBox(s, "Pattern Cleanup", MB_YESNO) != IDYES) return TRUE; - BeginWaitCursor(); - } - for (UINT irst=0; irst<maxPatIndex; irst++) nPatMap[irst] = 0xFFFF; - nPats = 0; - UINT imap = 0; - for (imap=0; imap<maxOrdIndex; imap++) - { - UINT n = m_SndFile.Order[imap]; - if (n < maxPatIndex) - { - if (nPatMap[n] > maxPatIndex) nPatMap[n] = nPats++; - m_SndFile.Order[imap] = nPatMap[n]; - } else if (n == m_SndFile.Order.GetInvalidPatIndex() && (bKeepSubSequences == false)) break; - } - // Add unused patterns at the end - if ((!bRemove) || (!bWaste)) - { - for (UINT iadd=0; iadd<maxPatIndex; iadd++) - { - if ((m_SndFile.Patterns[iadd]) && (nPatMap[iadd] >= maxPatIndex)) - { - nPatMap[iadd] = nPats++; - } - } - } - while (imap < maxOrdIndex) - { - m_SndFile.Order[imap++] = m_SndFile.Order.GetInvalidPatIndex(); - } - BEGIN_CRITICAL(); - // Reorder patterns & Delete unused patterns - { - UINT npatnames = m_SndFile.m_nPatternNames; - LPSTR lpszpatnames = m_SndFile.m_lpszPatternNames; - m_SndFile.m_nPatternNames = 0; - m_SndFile.m_lpszPatternNames = NULL; - for (UINT i=0; i<maxPatIndex; i++) - { - UINT k = nPatMap[i]; - if (k < maxPatIndex) - { - if (i != k) bReordered = TRUE; - // Remap pattern names - if (i < npatnames) - { - UINT noldpatnames = m_SndFile.m_nPatternNames; - LPSTR lpszoldpatnames = m_SndFile.m_lpszPatternNames; - m_SndFile.m_nPatternNames = npatnames; - m_SndFile.m_lpszPatternNames = lpszpatnames; - m_SndFile.GetPatternName(i, s); - m_SndFile.m_nPatternNames = noldpatnames; - m_SndFile.m_lpszPatternNames = lpszoldpatnames; - if (s[0]) m_SndFile.SetPatternName(k, s); - } - nPatRows[k] = m_SndFile.PatternSize[i]; - pPatterns[k] = m_SndFile.Patterns[i]; - } else - if (m_SndFile.Patterns[i]) - { - m_SndFile.Patterns.Remove(i); - nPatRemoved++; - } - } - for (UINT j=0; j<maxPatIndex;j++) - { - m_SndFile.Patterns[j].SetData(pPatterns[j], nPatRows[j]); - } - } - END_CRITICAL(); - EndWaitCursor(); - if ((nPatRemoved) || (bReordered)) - { - ClearUndo(); - SetModified(); - if (nPatRemoved) - { - wsprintf(s, "%d pattern(s) removed.\n", nPatRemoved); - AddToLog(s); - } - return TRUE; - } - return FALSE; -} - - - - -void CModDoc::RearrangeSamples() -//------------------------------ -{ - if(m_SndFile.m_nSamples < 2) - return; - - UINT nRemap = 0; // remap count - UINT nSampleMap[MAX_SAMPLES + 1]; // map old => new - for(UINT i = 0; i <= MAX_SAMPLES; i++) - nSampleMap[i] = i; - - // First, find out which sample slots are unused and create the new sample map - for(SAMPLEINDEX i = 1 ; i <= m_SndFile.m_nSamples; i++) { - if(!m_SndFile.Samples[i].pSample) - { - // Move all following samples - nRemap++; - nSampleMap[i] = 0; - for(UINT j = i + 1; j <= m_SndFile.m_nSamples; j++) - nSampleMap[j]--; - } - } - - if(!nRemap) - return; - - BEGIN_CRITICAL(); - - // Now, move everything around - for(SAMPLEINDEX i = 1; i <= m_SndFile.m_nSamples; i++) - { - if(nSampleMap[i] != i) - { - // This gotta be moved - m_SndFile.MoveSample(i, nSampleMap[i]); - m_SndFile.Samples[i].pSample = nullptr; - if(nSampleMap[i] > 0) strcpy(m_SndFile.m_szNames[nSampleMap[i]], m_SndFile.m_szNames[i]); - memset(m_SndFile.m_szNames[i], 0, sizeof(m_SndFile.m_szNames[i])); - - // Also update instrument mapping (if module is in instrument mode) - for(INSTRUMENTINDEX iInstr = 1; iInstr <= m_SndFile.m_nInstruments; iInstr++){ - if(m_SndFile.Instruments[iInstr]){ - MODINSTRUMENT *p = m_SndFile.Instruments[iInstr]; - for(WORD iNote = 0; iNote < 128; iNote++) - if(p->Keyboard[iNote] == i) p->Keyboard[iNote] = nSampleMap[i]; - } - } - } - } - - // Go through the patterns and remap samples (if module is in sample mode) - if(!m_SndFile.m_nInstruments) - { - for (PATTERNINDEX nPat = 0; nPat < m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat]) - { - MODCOMMAND *m = m_SndFile.Patterns[nPat]; - for(UINT len = m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; len; m++, len--) - { - if(m->instr <= m_SndFile.m_nSamples) m->instr = nSampleMap[m->instr]; - } - } - } - - m_SndFile.m_nSamples -= nRemap; - - END_CRITICAL(); - - SetModified(); - UpdateAllViews(NULL, HINT_MODTYPE); - -} - - BOOL CModDoc::ConvertInstrumentsToSamples() //----------------------------------------- { @@ -1278,130 +1033,7 @@ } -BOOL CModDoc::RemoveUnusedSamples() -//--------------------------------- -{ - CHAR s[512]; - BOOL bIns[MAX_SAMPLES]; - UINT nExt = 0, nLoopOpt = 0; - UINT nRemoved = 0; - - BeginWaitCursor(); - for (UINT i=m_SndFile.m_nSamples; i>=1; i--) if (m_SndFile.Samples[i].pSample) - { - if (!m_SndFile.IsSampleUsed(i)) - { - BEGIN_CRITICAL(); - m_SndFile.DestroySample(i); - if ((i == m_SndFile.m_nSamples) && (i > 1)) m_SndFile.m_nSamples--; - END_CRITICAL(); - nRemoved++; - } - } - if (m_SndFile.m_nInstruments) - { - memset(bIns, 0, sizeof(bIns)); - for (UINT ipat=0; ipat<m_SndFile.Patterns.Size(); ipat++) - { - MODCOMMAND *p = m_SndFile.Patterns[ipat]; - if (p) - { - UINT jmax = m_SndFile.PatternSize[ipat] * m_SndFile.m_nChannels; - for (UINT j=0; j<jmax; j++, p++) - { - if ((p->note) && (p->note <= NOTE_MAX)) - { - if ((p->instr) && (p->instr < MAX_INSTRUMENTS)) - { - MODINSTRUMENT *pIns = m_SndFile.Instruments[p->instr]; - if (pIns) - { - UINT n = pIns->Keyboard[p->note-1]; - if (n < MAX_SAMPLES) bIns[n] = TRUE; - } - } else - { - for (UINT k=1; k<=m_SndFile.m_nInstruments; k++) - { - MODINSTRUMENT *pIns = m_SndFile.Instruments[k]; - if (pIns) - { - UINT n = pIns->Keyboard[p->note-1]; - if (n < MAX_SAMPLES) bIns[n] = TRUE; - } - } - } - } - } - } - } - for (UINT ichk=1; ichk<MAX_SAMPLES; ichk++) - { - if ((!bIns[ichk]) && (m_SndFile.Samples[ichk].pSample)) nExt++; - } - } - EndWaitCursor(); - if (nExt && !((m_SndFile.m_nType & MOD_TYPE_IT) && (m_SndFile.m_dwSongFlags&SONG_ITPROJECT))) - { //We don't remove an instrument's unused samples in an ITP. - wsprintf(s, "OpenMPT detected %d sample(s) referenced by an instrument,\n" - "but not used in the song. Do you want to remove them ?", nExt); - if (::MessageBox(NULL, s, "Sample Cleanup", MB_YESNO | MB_ICONQUESTION) == IDYES) - { - for (UINT j=1; j<MAX_SAMPLES; j++) - { - if ((!bIns[j]) && (m_SndFile.Samples[j].pSample)) - { - BEGIN_CRITICAL(); - m_SndFile.DestroySample(j); - if ((j == m_SndFile.m_nSamples) && (j > 1)) m_SndFile.m_nSamples--; - END_CRITICAL(); - nRemoved++; - } - } - } - } - for (UINT ilo=1; ilo<=m_SndFile.m_nSamples; ilo++) if (m_SndFile.Samples[ilo].pSample) - { - if ((m_SndFile.Samples[ilo].uFlags & CHN_LOOP) - && (m_SndFile.Samples[ilo].nLength > m_SndFile.Samples[ilo].nLoopEnd + 2)) nLoopOpt++; - } - if (nLoopOpt) - { - wsprintf(s, "OpenMPT detected %d sample(s) with unused data after the loop end point,\n" - "Do you want to optimize it, and remove this unused data ?", nLoopOpt); - if (::MessageBox(NULL, s, "Sample Cleanup", MB_YESNO | MB_ICONQUESTION) == IDYES) - { - for (UINT j=1; j<=m_SndFile.m_nSamples; j++) - { - if ((m_SndFile.Samples[j].uFlags & CHN_LOOP) - && (m_SndFile.Samples[j].nLength > m_SndFile.Samples[j].nLoopEnd + 2)) - { - UINT lmax = m_SndFile.Samples[j].nLoopEnd + 2; - if ((lmax < m_SndFile.Samples[j].nLength) && (lmax >= 16)) m_SndFile.Samples[j].nLength = lmax; - } - } - } else nLoopOpt = 0; - } - if ((nRemoved) || (nLoopOpt)) - { - if (nRemoved) - { - wsprintf(s, "%d unused sample(s) removed\n" ,nRemoved); - AddToLog(s); - } - if (nLoopOpt) - { - wsprintf(s, "%d sample loop(s) optimized\n" ,nLoopOpt); - AddToLog(s); - } - SetModified(); - return TRUE; - } - return FALSE; -} - - UINT CModDoc::RemovePlugs(const bool (&keepMask)[MAX_MIXPLUGINS]) //--------------------------------------------------------------- { @@ -1443,288 +1075,6 @@ } -BOOL CModDoc::RemoveUnusedPlugs() -//------------------------------- -{ - bool usedmap[MAX_MIXPLUGINS]; - memset(usedmap, false, sizeof(usedmap)); - - for (PLUGINDEX nPlug=0; nPlug < MAX_MIXPLUGINS; nPlug++) { - - //Is the plugin assigned to a channel? - for (CHANNELINDEX nChn = 0; nChn < m_SndFile.GetNumChannels(); nChn++) { - if (m_SndFile.ChnSettings[nChn].nMixPlugin == nPlug + 1u) { - usedmap[nPlug]=true; - break; - } - } - - //Is the plugin used by an instrument? - for (INSTRUMENTINDEX nIns=1; nIns<=m_SndFile.GetNumInstruments(); nIns++) { - if (m_SndFile.Instruments[nIns] && (m_SndFile.Instruments[nIns]->nMixPlug == nPlug+1)) { - usedmap[nPlug]=true; - break; - } - } - - //Is the plugin assigned to master? - if (m_SndFile.m_MixPlugins[nPlug].Info.dwInputRouting & MIXPLUG_INPUTF_MASTEREFFECT) { - usedmap[nPlug]=true; - } - - //all outputs of used plugins count as used - if (usedmap[nPlug]!=0) { - if (m_SndFile.m_MixPlugins[nPlug].Info.dwOutputRouting & 0x80) { - int output = m_SndFile.m_MixPlugins[nPlug].Info.dwOutputRouting & 0x7f; - usedmap[output]=true; - } - } - - } - - UINT nRemoved = RemovePlugs(usedmap); - - if (nRemoved) { - SetModified(); - } - - return nRemoved; -} - - -void CModDoc::RemoveAllInstruments(bool bConfirm) -//----------------------------------------------- -{ - if (!m_SndFile.m_nInstruments) - return; - - char removeSamples = -1; - if(bConfirm) - { - if (CMainFrame::GetMainFrame()->MessageBox("This will remove all the instruments in the song,\n" - "Do you want to continue?", "Warning", MB_YESNO | MB_ICONQUESTION) != IDYES) return; - if (CMainFrame::GetMainFrame()->MessageBox("Do you want to convert all instruments to samples ?\n", - NULL, MB_YESNO | MB_ICONQUESTION) == IDYES) - { - ConvertInstrumentsToSamples(); - } - - if (::MessageBox(NULL, "Remove samples associated with an instrument if they are unused?", "Removing instrument", MB_YESNO | MB_ICONQUESTION) == IDYES) { - removeSamples = 1; - } - } - - for (INSTRUMENTINDEX i = 1; i <= m_SndFile.m_nInstruments; i++) - { - m_SndFile.DestroyInstrument(i,removeSamples); - } - - m_SndFile.m_nInstruments = 0; - SetModified(); - UpdateAllViews(NULL, HINT_MODTYPE); -} - - -BOOL CModDoc::RemoveUnusedInstruments() -//------------------------------------- -{ - BYTE usedmap[MAX_INSTRUMENTS]; - BYTE swapmap[MAX_INSTRUMENTS]; - BYTE swapdest[MAX_INSTRUMENTS]; - CHAR s[512]; - UINT nRemoved = 0; - UINT nSwap, nIndex; - bool bReorg = false; - - if (!m_SndFile.m_nInstruments) return FALSE; - - char removeSamples = -1; - if ( !((m_SndFile.m_nType & MOD_TYPE_IT) && (m_SndFile.m_dwSongFlags&SONG_ITPROJECT))) { //never remove an instrument's samples in ITP. - if(::MessageBox(NULL, "Remove samples associated with an instrument if they are unused?", "Removing instrument", MB_YESNO | MB_ICONQUESTION) == IDYES) { - removeSamples = 1; - } - } else { - MessageBox(NULL, "This is an IT project, so no samples associated with a used instrument will be removed.", "Removing Instruments", MB_OK | MB_ICONINFORMATION); - } - - BeginWaitCursor(); - memset(usedmap, 0, sizeof(usedmap)); - - for(INSTRUMENTINDEX i = m_SndFile.m_nInstruments; i >= 1; i--) - { - if (!m_SndFile.IsInstrumentUsed(i)) - { - BEGIN_CRITICAL(); -// -> CODE#0003 -// -> DESC="remove instrument's samples" -// m_SndFile.DestroyInstrument(i); - m_SndFile.DestroyInstrument(i, removeSamples); -// -! BEHAVIOUR_CHANGE#0003 - if ((i == m_SndFile.m_nInstruments) && (i>1)) m_SndFile.m_nInstruments--; else bReorg = true; - END_CRITICAL(); - nRemoved++; - } else - { - usedmap[i] = 1; - } - } - EndWaitCursor(); - if ((bReorg) && (m_SndFile.m_nInstruments > 1) - && (::MessageBox(NULL, "Do you want to reorganize the remaining instruments?", "Instrument Cleanup", MB_YESNO | MB_ICONQUESTION) == IDYES)) - { - BeginWaitCursor(); - BEGIN_CRITICAL(); - nSwap = 0; - nIndex = 1; - for (UINT j=1; j<=m_SndFile.m_nInstruments; j++) - { - if (usedmap[j]) - { - while (nIndex<j) - { - if ((!usedmap[nIndex]) && (!m_SndFile.Instruments[nIndex])) - { - swapmap[nSwap] = j; - swapdest[nSwap] = nIndex; - m_SndFile.Instruments[nIndex] = m_SndFile.Instruments[j]; - m_SndFile.Instruments[j] = NULL; - usedmap[nIndex] = 1; - usedmap[j] = 0; - nSwap++; - nIndex++; - break; - } - nIndex++; - } - } - } - while ((m_SndFile.m_nInstruments > 1) && (!m_SndFile.Instruments[m_SndFile.m_nInstruments])) m_SndFile.m_nInstruments--; - END_CRITICAL(); - if (nSwap > 0) - { - for (UINT iPat=0; iPat<m_SndFile.Patterns.Size(); iPat++) if (m_SndFile.Patterns[iPat]) - { - MODCOMMAND *p = m_SndFile.Patterns[iPat]; - UINT nLen = m_SndFile.m_nChannels * m_SndFile.PatternSize[iPat]; - while (nLen--) - { - if (p->instr) - { - for (UINT k=0; k<nSwap; k++) - { - if (p->instr == swapmap[k]) p->instr = swapdest[k]; - } - } - p++; - } - } - } - EndWaitCursor(); - } - if (nRemoved) - { - wsprintf(s, "%d unused instrument(s) removed\n", nRemoved); - AddToLog(s); - SetModified(); - return TRUE; - } - return FALSE; -} - - -BOOL CModDoc::CompoCleanup() -//-------------------------- -{ - //jojo.compocleanup - if(::MessageBox(NULL, TEXT("WARNING: Compo cleanup will convert module to IT format, remove all patterns and reset song, sample and instrument attributes to default values. Continue?"), TEXT("Compo Cleanup"), MB_YESNO | MB_ICONWARNING) == IDNO) - return FALSE; - - // Stop play. - CMainFrame::GetMainFrame()->StopMod(this); - - BeginWaitCursor(); - BEGIN_CRITICAL(); - - // convert to IT... - ChangeModType(MOD_TYPE_IT); - m_SndFile.m_nMixLevels = mixLevels_original; - m_SndFile.m_nTempoMode = tempo_mode_classic; - m_SndFile.m_dwSongFlags = SONG_LINEARSLIDES | SONG_EXFILTERRANGE; - - // clear order list - m_SndFile.Order.Init(); - m_SndFile.Order[0] = 0; - - // remove all patterns - m_SndFile.Patterns.Init(); - m_SndFile.Patterns.Insert(0, 64); - m_SndFile.SetCurrentOrder(0); - - // Global vars - m_SndFile.m_nDefaultTempo = 125; - m_SndFile.m_nDefaultSpeed = 6; - m_SndFile.m_nDefaultGlobalVolume = 256; - m_SndFile.m_nSamplePreAmp = 48; - m_SndFile.m_nVSTiVolume = 48; - m_SndFile.m_nRestartPos = 0; - - // Set 4 default channels. - m_SndFile.ReArrangeChannels(vector<CHANNELINDEX>(4, MAX_BASECHANNELS)); - - //remove plugs - bool keepMask[MAX_MIXPLUGINS]; memset(keepMask, 0, sizeof(keepMask)); - RemovePlugs(keepMask); - - // instruments - if(m_SndFile.m_nInstruments && ::MessageBox(NULL, "Remove instruments?", "Compo Cleanup", MB_YESNO | MB_ICONQUESTION) == IDYES) - { - // remove instruments - RemoveAllInstruments(false); - } - else - { - // reset instruments - for(UINT i = 1; i <= m_SndFile.m_nInstruments; i++) - { - m_SndFile.Instruments[i]->nFadeOut = 256; - m_SndFile.Instruments[i]->nGlobalVol = 64; - m_SndFile.Instruments[i]->nPan = 128; - m_SndFile.Instruments[i]->dwFlags &= ~ENV_SETPANNING; - m_SndFile.Instruments[i]->nMixPlug = 0; - - m_SndFile.Instruments[i]->nVolSwing = 0; - m_SndFile.Instruments[i]->nPanSwing = 0; - m_SndFile.Instruments[i]->nCutSwing = 0; - m_SndFile.Instruments[i]->nResSwing = 0; - - //might be a good idea to leave those enabled... - /* - m_SndFile.Instruments[i]->dwFlags &= ~ENV_VOLUME; - m_SndFile.Instruments[i]->dwFlags &= ~ENV_PANNING; - m_SndFile.Instruments[i]->dwFlags &= ~ENV_PITCH; - m_SndFile.Instruments[i]->dwFlags &= ~ENV_FILTER; - */ - } - } - - // reset samples - ctrlSmp::ResetSamples(m_SndFile, ctrlSmp::SmpResetCompo); - - // Set modflags. - m_SndFile.SetModFlag(MSF_MIDICC_BUGEMULATION, false); - m_SndFile.SetModFlag(MSF_OLDVOLSWING, false); - m_SndFile.SetModFlag(MSF_COMPATIBLE_PLAY, true); - - END_CRITICAL(); - EndWaitCursor(); - - UpdateAllViews(NULL, HINT_MODGENERAL, this); - - SetModified(); - return TRUE; -} - - BOOL CModDoc::AdjustEndOfSample(UINT nSample) //------------------------------------------- { @@ -2018,8 +1368,8 @@ } -bool CModDoc::MoveOrder(ORDERINDEX nSourceNdx, ORDERINDEX nDestNdx, bool bUpdate, bool bCopy) -//------------------------------------------------------------------------------------------- +bool CModDoc::MoveOrder(ORDERINDEX nSourceNdx, ORDERINDEX nDestNdx, bool bUpdate, bool bCopy, SEQUENCEINDEX nSourceSeq, SEQUENCEINDEX nDestSeq) +//--------------------------------------------------------------------------------------------------------------------------------------------- { if ((nSourceNdx >= m_SndFile.Order.size()) || (nDestNdx >= m_SndFile.Order.size())) return false; if (nDestNdx >= m_SndFile.GetModSpecifications().ordersMax) return false; Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-10-04 18:13:30 UTC (rev 386) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-10-05 17:02:19 UTC (rev 387) @@ -7,7 +7,6 @@ #include "ChildFrm.h" #include "vstplug.h" #include "ChannelManagerDlg.h" -#include ".\dlg_misc.h" #include "midi.h" #include "version.h" Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2009-10-04 18:13:30 UTC (rev 386) +++ trunk/OpenMPT/mptrack/mptrack.rc 2009-10-05 17:02:19 UTC (rev 387) @@ -36,7 +36,30 @@ LTEXT "The following problems have been encountered when loading this module:",IDC_STATIC,6,6,237,8 END +IDD_CLEANUP_SONG DIALOGEX 0, 0, 298, 161 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Cleanup" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,240,6,50,14 + PUSHBUTTON "Cancel",IDCANCEL,240,24,50,14 + GROUPBOX "Items to be cleaned up",IDC_STATIC,6,6,228,90 + CONTROL "Remove unused patterns",IDC_CHK_CLEANUP_PATTERNS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,24,102,12 + CONTROL "Rearrange patterns",IDC_CHK_REARRANGE_PATTERNS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,126,24,102,12 + CONTROL "Remove unused samples",IDC_CHK_CLEANUP_SAMPLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,42,102,12 + CONTROL "Rearrange samples",IDC_CHK_REARRANGE_SAMPLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,126,42,102,12 + CONTROL "Remove unused instruments",IDC_CHK_CLEANUP_INSTRUMENTS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,60,102,12 + CONTROL "Remove all instruments",IDC_CHK_REMOVE_INSTRUMENTS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,126,60,102,12 + CONTROL "Remove unused plugins",IDC_CHK_CLEANUP_PLUGINS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,78,102,12 + CONTROL "Turn into samplepack",IDC_CHK_SAMPLEPACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,126,78,102,12 + GROUPBOX "Presets",IDC_STATIC,6,102,228,48 + PUSHBUTTON "Remove all unused stuff",IDC_BTN_CLEANUP_SONG,18,120,96,18 + PUSHBUTTON "Compo cleanup",IDC_BTN_COM... [truncated message content] |
From: <sag...@us...> - 2009-10-07 17:12:54
|
Revision: 390 http://modplug.svn.sourceforge.net/modplug/?rev=390&view=rev Author: saga-games Date: 2009-10-07 17:12:37 +0000 (Wed, 07 Oct 2009) Log Message: ----------- [Imp] Treeview: Should behave correctly when number of sequences changed from 1 or to 1. [Mod] Mod Creation: When clicking on the "new" buton, the newly created module will be of the same type as the currently active document. Should probably be an option. Modified Paths: -------------- trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-06 12:44:31 UTC (rev 389) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-07 17:12:37 UTC (rev 390) @@ -773,6 +773,10 @@ } } } + if(m_SndFile.Order.GetLengthTailTrimmed() > specs.ordersMax) + { + AddToLog("WARNING: Order list has been trimmed!"); + } m_SndFile.Order.resize(specs.ordersMax); } Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2009-10-06 12:44:31 UTC (rev 389) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2009-10-07 17:12:37 UTC (rev 390) @@ -1265,7 +1265,46 @@ void CTrackApp::OnFileNew() //------------------------- { - if (m_bInitialized) OnFileNewIT(); + if (!m_bInitialized) return; + + // Default module type + MODTYPE nNewType = MOD_TYPE_IT; + bool bIsProject = false; + + // Get active document to make the new module of the same type + CModDoc *pModDoc = CMainFrame::GetMainFrame()->GetActiveDoc(); + if(pModDoc != nullptr) + { + CSoundFile *pSndFile = pModDoc->GetSoundFile(); + if(pSndFile != nullptr) + { + nNewType = pSndFile->GetBestSaveFormat(); + bIsProject = ((pSndFile->m_dwSongFlags & SONG_ITPROJECT) != 0) ? true: false; + } + } + + switch(nNewType) + { + case MOD_TYPE_MOD: + OnFileNewMOD(); + break; + case MOD_TYPE_S3M: + OnFileNewS3M(); + break; + case MOD_TYPE_XM: + OnFileNewXM(); + break; + case MOD_TYPE_IT: + if(bIsProject) + OnFileNewITProject(); + else + OnFileNewIT(); + break; + case MOD_TYPE_MPT: + default: + OnFileNewMPT(); + break; + } } Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2009-10-06 12:44:31 UTC (rev 389) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2009-10-07 17:12:37 UTC (rev 390) @@ -688,6 +688,25 @@ if ((pInfo->hOrders) && (hintFlagPart != HINT_INSNAMES) && (hintFlagPart != HINT_SMPNAMES)) { const DWORD nPat = (lHint >> HINT_SHIFT_PAT); + + // only one seq remaining: update parent item || previously only one sequence + if((pInfo->tiSequences.size() > 1 && pSndFile->Order.GetNumSequences() == 1) || (pInfo->tiSequences.size() == 1 && pSndFile->Order.GetNumSequences() > 1)) + { + if(pInfo->tiOrders.size() != pSndFile->Order.GetNumSequences()) + { + for(size_t nSeq = 0; nSeq < pInfo->tiOrders.size(); nSeq++) + { + for(size_t nOrd = 0; nOrd < pInfo->tiOrders[nSeq].size(); nOrd++) if (pInfo->tiOrders[nSeq][nOrd]) + { + DeleteItem(pInfo->tiOrders[nSeq][nOrd]); pInfo->tiOrders[nSeq][nOrd] = NULL; + } + DeleteItem(pInfo->tiSequences[nSeq]); pInfo->tiSequences[nSeq] = NULL; + } + pInfo->tiOrders.resize(pSndFile->Order.GetNumSequences()); + pInfo->tiSequences.resize(pSndFile->Order.GetNumSequences(), NULL); + } + } + // If there are too many sequences, delete them. for(size_t nSeq = pSndFile->Order.GetNumSequences(); nSeq < pInfo->tiSequences.size(); nSeq++) if (pInfo->tiSequences[nSeq]) { @@ -703,23 +722,6 @@ pInfo->tiOrders.resize(pSndFile->Order.GetNumSequences()); } - // TODO what to do when seq count changed from 2 to 1 or from 1 to 2? - - /* // number of sequences changed: wipe tree first (is this necessary?) - if(pInfo->tiOrders.size() != pSndFile->Order.GetNumSequences()) - { - for(size_t nSeq = 0; nSeq < pInfo->tiOrders.size(); nSeq++) - { - for(size_t nOrd = 0; nOrd < pInfo->tiOrders[nSeq].size(); nOrd++) if (pInfo->tiOrders[nSeq][nOrd]) - { - DeleteItem(pInfo->tiOrders[nSeq][nOrd]); pInfo->tiOrders[nSeq][nOrd] = NULL; - } - DeleteItem(pInfo->tiSequences[nSeq]); pInfo->tiSequences[nSeq] = NULL; - } - pInfo->tiOrders.resize(pSndFile->Order.GetNumSequences()); - pInfo->tiSequences.resize(pSndFile->Order.GetNumSequences(), NULL); - }*/ - HTREEITEM hAncestorNode = pInfo->hOrders; // go through all sequences Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-06 12:44:31 UTC (rev 389) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-07 17:12:37 UTC (rev 390) @@ -1359,8 +1359,8 @@ //end rewbs.playSongFromCursor -UINT CSoundFile::GetBestSaveFormat() const -//---------------------------------------- +MODTYPE CSoundFile::GetBestSaveFormat() const +//------------------------------------------- { if ((!m_nSamples) || (!m_nChannels)) return MOD_TYPE_NONE; if (!m_nType) return MOD_TYPE_NONE; @@ -1376,8 +1376,8 @@ } -UINT CSoundFile::GetSaveFormats() const -//------------------------------------- +MODTYPE CSoundFile::GetSaveFormats() const +//---------------------------------------- { UINT n = 0; if ((!m_nSamples) || (!m_nChannels) || (m_nType == MOD_TYPE_NONE)) return 0; @@ -2650,7 +2650,7 @@ CHAR szName[MAX_PATTERNNAME] = ""; if (nPat >= Patterns.Size()) return FALSE; if (lpszName) lstrcpyn(szName, lpszName, MAX_PATTERNNAME); - szName[MAX_PATTERNNAME-1] = 0; + SpaceToNullString(szName); //szName[MAX_PATTERNNAME-1] = 0; if (!m_lpszPatternNames) m_nPatternNames = 0; if (nPat >= m_nPatternNames) { Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-10-06 12:44:31 UTC (rev 389) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-10-07 17:12:37 UTC (rev 390) @@ -730,8 +730,8 @@ #endif // MODPLUG_NO_FILESAVE // MOD Convert function - UINT GetBestSaveFormat() const; - UINT GetSaveFormats() const; + MODTYPE GetBestSaveFormat() const; + MODTYPE GetSaveFormats() const; void ConvertModCommand(MODCOMMAND *) const; void S3MConvert(MODCOMMAND *m, BOOL bIT) const; void S3MSaveConvert(UINT *pcmd, UINT *pprm, BOOL bIT, BOOL bCompatibilityExport = false) const; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-10-09 00:01:11
|
Revision: 391 http://modplug.svn.sourceforge.net/modplug/?rev=391&view=rev Author: saga-games Date: 2009-10-09 00:00:56 +0000 (Fri, 09 Oct 2009) Log Message: ----------- [Fix] IT Compatibility: Out of range offset command with Old FX on [New] Can now import RIFF AM and RIFF AMFF files, as well as J2B files, which are compressed AM(FF) files. Added zlib 1.2.3 for J2B support. ATTENTION: The "zlibstat" project from from zlib/contrib/vstudio/ still has to be added to mptrack.sln (for VS7/8)! Modified Paths: -------------- trunk/OpenMPT/mptrack/MPTRACK_08.sln trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/mptrack_08.vcproj 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/load_j2b.cpp Added Paths: ----------- trunk/OpenMPT/zlib/ trunk/OpenMPT/zlib/ChangeLog trunk/OpenMPT/zlib/FAQ trunk/OpenMPT/zlib/INDEX trunk/OpenMPT/zlib/Makefile trunk/OpenMPT/zlib/Makefile.in trunk/OpenMPT/zlib/README trunk/OpenMPT/zlib/adler32.c trunk/OpenMPT/zlib/compress.c trunk/OpenMPT/zlib/configure trunk/OpenMPT/zlib/contrib/ trunk/OpenMPT/zlib/contrib/README.contrib trunk/OpenMPT/zlib/contrib/masmx64/ trunk/OpenMPT/zlib/contrib/masmx64/bld_ml64.bat trunk/OpenMPT/zlib/contrib/masmx64/gvmat64.asm trunk/OpenMPT/zlib/contrib/masmx64/gvmat64.obj trunk/OpenMPT/zlib/contrib/masmx64/inffas8664.c trunk/OpenMPT/zlib/contrib/masmx64/inffasx64.asm trunk/OpenMPT/zlib/contrib/masmx64/inffasx64.obj trunk/OpenMPT/zlib/contrib/masmx64/readme.txt trunk/OpenMPT/zlib/contrib/masmx86/ trunk/OpenMPT/zlib/contrib/masmx86/bld_ml32.bat trunk/OpenMPT/zlib/contrib/masmx86/gvmat32.asm trunk/OpenMPT/zlib/contrib/masmx86/gvmat32.obj trunk/OpenMPT/zlib/contrib/masmx86/gvmat32c.c trunk/OpenMPT/zlib/contrib/masmx86/inffas32.asm trunk/OpenMPT/zlib/contrib/masmx86/inffas32.obj trunk/OpenMPT/zlib/contrib/masmx86/mkasm.bat trunk/OpenMPT/zlib/contrib/masmx86/readme.txt trunk/OpenMPT/zlib/contrib/minizip/ trunk/OpenMPT/zlib/contrib/minizip/ChangeLogUnzip trunk/OpenMPT/zlib/contrib/minizip/Makefile trunk/OpenMPT/zlib/contrib/minizip/crypt.h trunk/OpenMPT/zlib/contrib/minizip/ioapi.c trunk/OpenMPT/zlib/contrib/minizip/ioapi.h trunk/OpenMPT/zlib/contrib/minizip/iowin32.c trunk/OpenMPT/zlib/contrib/minizip/iowin32.h trunk/OpenMPT/zlib/contrib/minizip/miniunz.c trunk/OpenMPT/zlib/contrib/minizip/minizip.c trunk/OpenMPT/zlib/contrib/minizip/mztools.c trunk/OpenMPT/zlib/contrib/minizip/mztools.h trunk/OpenMPT/zlib/contrib/minizip/unzip.c trunk/OpenMPT/zlib/contrib/minizip/unzip.h trunk/OpenMPT/zlib/contrib/minizip/zip.c trunk/OpenMPT/zlib/contrib/minizip/zip.h trunk/OpenMPT/zlib/contrib/vstudio/ trunk/OpenMPT/zlib/contrib/vstudio/readme.txt trunk/OpenMPT/zlib/contrib/vstudio/vc7/ trunk/OpenMPT/zlib/contrib/vstudio/vc7/miniunz.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc7/minizip.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc7/testzlib.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc7/zlib.rc trunk/OpenMPT/zlib/contrib/vstudio/vc7/zlibstat.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc7/zlibvc.def trunk/OpenMPT/zlib/contrib/vstudio/vc7/zlibvc.sln trunk/OpenMPT/zlib/contrib/vstudio/vc7/zlibvc.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc8/ trunk/OpenMPT/zlib/contrib/vstudio/vc8/miniunz.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc8/minizip.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc8/testzlib.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc8/testzlibdll.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc8/zlib.rc trunk/OpenMPT/zlib/contrib/vstudio/vc8/zlibstat.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc8/zlibvc.def trunk/OpenMPT/zlib/contrib/vstudio/vc8/zlibvc.sln trunk/OpenMPT/zlib/contrib/vstudio/vc8/zlibvc.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc9/ trunk/OpenMPT/zlib/contrib/vstudio/vc9/miniunz.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc9/minizip.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc9/testzlib.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc9/testzlibdll.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc9/zlib.rc trunk/OpenMPT/zlib/contrib/vstudio/vc9/zlibstat.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc9/zlibvc.def trunk/OpenMPT/zlib/contrib/vstudio/vc9/zlibvc.sln trunk/OpenMPT/zlib/contrib/vstudio/vc9/zlibvc.vcproj trunk/OpenMPT/zlib/crc32.c trunk/OpenMPT/zlib/crc32.h trunk/OpenMPT/zlib/deflate.c trunk/OpenMPT/zlib/deflate.h trunk/OpenMPT/zlib/example.c trunk/OpenMPT/zlib/gzio.c trunk/OpenMPT/zlib/infback.c trunk/OpenMPT/zlib/inffast.c trunk/OpenMPT/zlib/inffast.h trunk/OpenMPT/zlib/inffixed.h trunk/OpenMPT/zlib/inflate.c trunk/OpenMPT/zlib/inflate.h trunk/OpenMPT/zlib/inftrees.c trunk/OpenMPT/zlib/inftrees.h trunk/OpenMPT/zlib/minigzip.c trunk/OpenMPT/zlib/trees.c trunk/OpenMPT/zlib/trees.h trunk/OpenMPT/zlib/uncompr.c trunk/OpenMPT/zlib/zconf.h trunk/OpenMPT/zlib/zconf.in.h trunk/OpenMPT/zlib/zlib.3 trunk/OpenMPT/zlib/zlib.h trunk/OpenMPT/zlib/zutil.c trunk/OpenMPT/zlib/zutil.h Modified: trunk/OpenMPT/mptrack/MPTRACK_08.sln =================================================================== --- trunk/OpenMPT/mptrack/MPTRACK_08.sln 2009-10-07 17:12:37 UTC (rev 390) +++ trunk/OpenMPT/mptrack/MPTRACK_08.sln 2009-10-09 00:00:56 UTC (rev 391) @@ -1,9 +1,10 @@ Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual C++ Express 2008 +# Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mptrack", "mptrack_08.vcproj", "{21D95071-FB97-4E69-B3B1-050D0D4A5021}" ProjectSection(ProjectDependencies) = postProject {44316F22-904E-48AA-B841-5A3A6AC77319} = {44316F22-904E-48AA-B841-5A3A6AC77319} {FAE39936-1DC7-40BB-AD3F-3B5B9E9AB0E8} = {FAE39936-1DC7-40BB-AD3F-3B5B9E9AB0E8} + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8} = {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8} {CF3C2CA5-5D45-4635-BBA4-C1F435E10896} = {CF3C2CA5-5D45-4635-BBA4-C1F435E10896} {FF541CE2-DAA1-4F84-9883-0A0F111BAA0B} = {FF541CE2-DAA1-4F84-9883-0A0F111BAA0B} EndProjectSection @@ -18,36 +19,57 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SoundTouch", "..\soundtouch\soundtouch_08.vcproj", "{CF3C2CA5-5D45-4635-BBA4-C1F435E10896}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "..\zlib\contrib\vstudio\vc9\zlibstat.vcproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 + ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {21D95071-FB97-4E69-B3B1-050D0D4A5021}.Debug|Win32.ActiveCfg = Debug|Win32 {21D95071-FB97-4E69-B3B1-050D0D4A5021}.Debug|Win32.Build.0 = Debug|Win32 {21D95071-FB97-4E69-B3B1-050D0D4A5021}.Release|Win32.ActiveCfg = Release|Win32 {21D95071-FB97-4E69-B3B1-050D0D4A5021}.Release|Win32.Build.0 = Release|Win32 + {21D95071-FB97-4E69-B3B1-050D0D4A5021}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {21D95071-FB97-4E69-B3B1-050D0D4A5021}.ReleaseWithoutAsm|Win32.Build.0 = Release|Win32 {FAE39936-1DC7-40BB-AD3F-3B5B9E9AB0E8}.Debug|Win32.ActiveCfg = Debug|Win32 {FAE39936-1DC7-40BB-AD3F-3B5B9E9AB0E8}.Debug|Win32.Build.0 = Debug|Win32 {FAE39936-1DC7-40BB-AD3F-3B5B9E9AB0E8}.Release|Win32.ActiveCfg = Release|Win32 {FAE39936-1DC7-40BB-AD3F-3B5B9E9AB0E8}.Release|Win32.Build.0 = Release|Win32 + {FAE39936-1DC7-40BB-AD3F-3B5B9E9AB0E8}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {FAE39936-1DC7-40BB-AD3F-3B5B9E9AB0E8}.ReleaseWithoutAsm|Win32.Build.0 = Release|Win32 {FF541CE2-DAA1-4F84-9883-0A0F111BAA0B}.Debug|Win32.ActiveCfg = Debug|Win32 {FF541CE2-DAA1-4F84-9883-0A0F111BAA0B}.Debug|Win32.Build.0 = Debug|Win32 {FF541CE2-DAA1-4F84-9883-0A0F111BAA0B}.Release|Win32.ActiveCfg = Release|Win32 {FF541CE2-DAA1-4F84-9883-0A0F111BAA0B}.Release|Win32.Build.0 = Release|Win32 + {FF541CE2-DAA1-4F84-9883-0A0F111BAA0B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {FF541CE2-DAA1-4F84-9883-0A0F111BAA0B}.ReleaseWithoutAsm|Win32.Build.0 = Release|Win32 {44316F22-904E-48AA-B841-5A3A6AC77319}.Debug|Win32.ActiveCfg = Debug|Win32 {44316F22-904E-48AA-B841-5A3A6AC77319}.Debug|Win32.Build.0 = Debug|Win32 {44316F22-904E-48AA-B841-5A3A6AC77319}.Release|Win32.ActiveCfg = Release|Win32 {44316F22-904E-48AA-B841-5A3A6AC77319}.Release|Win32.Build.0 = Release|Win32 + {44316F22-904E-48AA-B841-5A3A6AC77319}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {44316F22-904E-48AA-B841-5A3A6AC77319}.ReleaseWithoutAsm|Win32.Build.0 = Release|Win32 {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.Debug|Win32.ActiveCfg = Debug|Win32 {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.Debug|Win32.Build.0 = Debug|Win32 {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.Release|Win32.ActiveCfg = Release|Win32 {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.Release|Win32.Build.0 = Release|Win32 + {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.ReleaseWithoutAsm|Win32.Build.0 = Release|Win32 {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.Debug|Win32.ActiveCfg = Debug|Win32 {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.Debug|Win32.Build.0 = Debug|Win32 {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.Release|Win32.ActiveCfg = Release|Win32 {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.Release|Win32.Build.0 = Release|Win32 + {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.ReleaseWithoutAsm|Win32.Build.0 = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-07 17:12:37 UTC (rev 390) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-09 00:00:56 UTC (rev 391) @@ -215,20 +215,7 @@ switch(m->command) { case CMD_MODCMDEX: - m->command = CMD_S3MCMDEX; - switch(m->param & 0xF0) - { - case 0x10: m->command = CMD_PORTAMENTOUP; m->param |= 0xF0; break; - case 0x20: m->command = CMD_PORTAMENTODOWN; m->param |= 0xF0; break; - case 0x30: m->param = (m->param & 0x0F) | 0x10; break; - case 0x40: m->param = (m->param & 0x0F) | 0x30; break; - case 0x50: m->param = (m->param & 0x0F) | 0x20; break; - case 0x60: m->param = (m->param & 0x0F) | 0xB0; break; - case 0x70: m->param = (m->param & 0x0F) | 0x40; break; - case 0x90: m->command = CMD_RETRIG; m->param = 0x80 | (m->param & 0x0F); break; - case 0xA0: if (m->param & 0x0F) { m->command = CMD_VOLUMESLIDE; m->param = (m->param << 4) | 0x0F; } else m->command = 0; break; - case 0xB0: if (m->param & 0x0F) { m->command = CMD_VOLUMESLIDE; m->param |= 0xF0; } else m->command = 0; break; - } + CSoundFile::MODExx2S3MSxx(m); break; case CMD_VOLUME: if (!m->volcmd) @@ -301,20 +288,7 @@ cEffectMemory[nChannel][CMD_ARPEGGIO] = m->param; break; case CMD_S3MCMDEX: - m->command = CMD_MODCMDEX; - switch(m->param & 0xF0) - { - case 0x10: m->param = (m->param & 0x0F) | 0x30; break; - case 0x20: m->param = (m->param & 0x0F) | 0x50; break; - case 0x30: m->param = (m->param & 0x0F) | 0x40; break; - case 0x40: m->param = (m->param & 0x0F) | 0x70; break; - case 0x50: - case 0x60: - case 0x70: - case 0x90: - case 0xA0: m->command = CMD_XFINEPORTAUPDOWN; break; - case 0xB0: m->param = (m->param & 0x0F) | 0x60; break; - } + CSoundFile::S3MSxx2MODExx(m); break; case CMD_VOLUMESLIDE: if ((m->param & 0xF0) && ((m->param & 0x0F) == 0x0F)) Modified: trunk/OpenMPT/mptrack/mptrack.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack.vcproj 2009-10-07 17:12:37 UTC (rev 390) +++ trunk/OpenMPT/mptrack/mptrack.vcproj 2009-10-09 00:00:56 UTC (rev 391) @@ -289,6 +289,9 @@ RelativePath="..\soundlib\Load_it.cpp"> </File> <File + RelativePath="..\soundlib\load_j2b.cpp"> + </File> + <File RelativePath="..\soundlib\Load_mdl.cpp"> </File> <File Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-10-07 17:12:37 UTC (rev 390) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-10-09 00:00:56 UTC (rev 391) @@ -389,6 +389,10 @@ > </File> <File + RelativePath="..\soundlib\load_j2b.cpp" + > + </File> + <File RelativePath="..\soundlib\Load_mdl.cpp" > </File> Modified: trunk/OpenMPT/soundlib/Snd_defs.h =================================================================== --- trunk/OpenMPT/soundlib/Snd_defs.h 2009-10-07 17:12:37 UTC (rev 390) +++ trunk/OpenMPT/soundlib/Snd_defs.h 2009-10-09 00:00:56 UTC (rev 391) @@ -256,10 +256,10 @@ // Module flags #define SONG_EMBEDMIDICFG 0x0001 -#define SONG_FASTVOLSLIDES 0x0002 -#define SONG_ITOLDEFFECTS 0x0004 -#define SONG_ITCOMPATMODE 0x0008 -#define SONG_LINEARSLIDES 0x0010 +#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 Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-10-07 17:12:37 UTC (rev 390) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-10-09 00:00:56 UTC (rev 391) @@ -3051,8 +3051,12 @@ // Offset beyond sample size if (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))) { + // IT Compatibility: Offset if(IsCompatibleMode(TRK_IMPULSETRACKER)) - pChn->nPos = 0; // IT Compatibility: Reset to beginning of sample + if(m_dwSongFlags & SONG_ITOLDEFFECTS) + pChn->nPos = pChn->nLength; // Old FX: Clip to end of sample + else + pChn->nPos = 0; // Reset to beginning of sample else pChn->nPos = pChn->nLoopStart; if ((m_dwSongFlags & SONG_ITOLDEFFECTS) && (pChn->nLength > 4)) Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-07 17:12:37 UTC (rev 390) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-09 00:00:56 UTC (rev 391) @@ -593,6 +593,8 @@ #endif // MODPLUG_BASIC_SUPPORT && (!ReadGDM(lpStream, dwMemLength)) && (!ReadIMF(lpStream, dwMemLength)) + && (!ReadAM(lpStream, dwMemLength)) + && (!ReadJ2B(lpStream, dwMemLength)) && (!ReadMO3(lpStream, dwMemLength)) && (!ReadMod(lpStream, dwMemLength))) m_nType = MOD_TYPE_NONE; #ifdef ZIPPED_MOD_SUPPORT @@ -3193,6 +3195,7 @@ return false; } + void CSoundFile::SetupMODPanning(bool bForceSetup) //------------------------------------------------ { @@ -3208,3 +3211,47 @@ ChnSettings[nChn].nPan = (((nChn & 3) == 1) || ((nChn & 3) == 2)) ? 0xC0 : 0x40; } } + +// Convert an Exx command (MOD) to Sxx command (S3M) +void CSoundFile::MODExx2S3MSxx(MODCOMMAND *m) +//------------------------------------------- +{ + if(m->command != CMD_MODCMDEX) return; + m->command = CMD_S3MCMDEX; + switch(m->param & 0xF0) + { + case 0x10: m->command = CMD_PORTAMENTOUP; m->param |= 0xF0; break; + case 0x20: m->command = CMD_PORTAMENTODOWN; m->param |= 0xF0; break; + case 0x30: m->param = (m->param & 0x0F) | 0x10; break; + case 0x40: m->param = (m->param & 0x0F) | 0x30; break; + case 0x50: m->param = (m->param & 0x0F) | 0x20; break; + case 0x60: m->param = (m->param & 0x0F) | 0xB0; break; + case 0x70: m->param = (m->param & 0x0F) | 0x40; break; + case 0x90: m->command = CMD_RETRIG; m->param = 0x80 | (m->param & 0x0F); break; + case 0xA0: if (m->param & 0x0F) { m->command = CMD_VOLUMESLIDE; m->param = (m->param << 4) | 0x0F; } else m->command = 0; break; + case 0xB0: if (m->param & 0x0F) { m->command = CMD_VOLUMESLIDE; m->param |= 0xF0; } else m->command = 0; break; + // rest are the same + } +} + +// Convert an Sxx command (S3M) to Exx command (MOD) +void CSoundFile::S3MSxx2MODExx(MODCOMMAND *m) +//------------------------------------------- +{ + if(m->command != CMD_S3MCMDEX) return; + m->command = CMD_MODCMDEX; + switch(m->param & 0xF0) + { + case 0x10: m->param = (m->param & 0x0F) | 0x30; break; + case 0x20: m->param = (m->param & 0x0F) | 0x50; break; + case 0x30: m->param = (m->param & 0x0F) | 0x40; break; + case 0x40: m->param = (m->param & 0x0F) | 0x70; break; + case 0x50: + case 0x60: + case 0x70: + case 0x90: + case 0xA0: m->command = CMD_XFINEPORTAUPDOWN; break; + case 0xB0: m->param = (m->param & 0x0F) | 0x60; break; + // rest are the same + } +} \ No newline at end of file Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-10-07 17:12:37 UTC (rev 390) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-10-09 00:00:56 UTC (rev 391) @@ -699,14 +699,16 @@ bool ReadMT2(LPCBYTE lpStream, DWORD dwMemLength); bool ReadPSM(LPCBYTE lpStream, DWORD dwMemLength); bool ReadPSM16(LPCBYTE lpStream, DWORD dwMemLength); - bool ReadJ2B(LPCBYTE lpStream, DWORD dwMemLength); bool ReadUMX(LPCBYTE lpStream, DWORD dwMemLength); bool ReadMO3(LPCBYTE lpStream, const DWORD dwMemLength); bool ReadGDM(const LPCBYTE lpStream, const DWORD dwMemLength); bool ReadIMF(const LPCBYTE lpStream, const DWORD dwMemLength); + bool ReadAM(const LPCBYTE lpStream, const DWORD dwMemLength); + bool ReadJ2B(const LPCBYTE lpStream, const DWORD dwMemLength); bool ReadMID(LPCBYTE lpStream, DWORD dwMemLength); void SetupMODPanning(bool bForceSetup = false); // Setup LRRL panning, max channel volume + bool Convert_RIFF_AM_Pattern(PATTERNINDEX nPat, const LPCBYTE lpStream, DWORD dwMemLength, bool bIsAM); // Save Functions #ifndef MODPLUG_NO_FILESAVE @@ -737,6 +739,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); + public: // Real-time sound functions VOID SuspendPlugins(); //rewbs.VSTCompliance Modified: trunk/OpenMPT/soundlib/load_j2b.cpp =================================================================== --- trunk/OpenMPT/soundlib/load_j2b.cpp 2009-10-07 17:12:37 UTC (rev 390) +++ trunk/OpenMPT/soundlib/load_j2b.cpp 2009-10-09 00:00:56 UTC (rev 391) @@ -1,15 +1,507 @@ /* - * This source code is public domain. + * Purpose: Load RIFF AM and RIFF AMFF modules. + * Note: J2B is a compressed variant of RIFF AM and RIFF AMFF files used in Jazz Jackrabbit 2 + * Authors: Johannes Schultz + * Chris Moeller (foo_dumb) + * Luigi Elettrico (J2B To IT Convertor Class) * - * Authors: Olivier Lapicque <oli...@jp...> -*/ + */ - -/////////////////////////////////////////////////// -// -// J2B module loader -// -/////////////////////////////////////////////////// #include "stdafx.h" #include "sndfile.h" +#define ZLIB_WINAPI +#include "../zlib/zlib.h" +#pragma pack(1) + +// header for compressed j2b files +struct J2BHEADER +{ + DWORD signature; // MUSE + DWORD deadbeaf; // 0xDEADBEAF or 0xDEADBABE + DWORD j2blength; + DWORD crc32; + DWORD packed_length; + DWORD unpacked_length; +}; + +// am(ff) stuff + +struct RIFFCHUNK +{ + DWORD signature; // "RIFF" + DWORD chunksize; // chunk size without header +}; + +// this header is used for both AM's "INIT" as well as AMFF's "MAIN" chunk +struct AMFFCHUNK_MAIN +{ + char songname[64]; + BYTE flags; + BYTE channels; + BYTE speed; + BYTE tempo; + DWORD unknown; + BYTE globalvolume; +}; + +struct AMFFCHUNK_INSTRUMENT +{ + BYTE unknown; // 0x00 + BYTE sample; // sample number + char name[28]; + char stuff[195]; // lots of NULs? +}; + +struct AMFFCHUNK_SAMPLE +{ + DWORD signature; // "SAMP" + DWORD chunksize; // header + sample size + char name[28]; + BYTE pan; + BYTE volume; + WORD flags; + DWORD length; + DWORD loopstart; + DWORD loopend; + DWORD samplerate; + DWORD reserved1; + DWORD reserved2; +}; + +struct AMCHUNK_INSTRUMENT +{ + BYTE unknown; // 0x00 + BYTE sample; // sample number + char name[32]; +}; + +struct AMCHUNK_SAMPLE +{ + DWORD signature; // "SAMP" + DWORD chunksize; // header + sample size + DWORD headsize; // header size + char name[32]; + WORD pan; + WORD volume; + WORD flags; + WORD unkown; + DWORD length; + DWORD loopstart; + DWORD loopend; + DWORD samplerate; +}; + +#pragma pack() + +bool CSoundFile::Convert_RIFF_AM_Pattern(PATTERNINDEX nPat, const LPCBYTE lpStream, DWORD dwMemLength, bool bIsAM) +//---------------------------------------------------------------------------------------------------------------- +{ + // version 0 = AMFF, else = AM + #define ASSERT_CAN_READ(x) \ + if( dwMemPos > dwMemLength || x > dwMemLength - dwMemPos ) return false; + + DWORD dwMemPos = 0; + + ASSERT_CAN_READ(1); + + ROWINDEX nRows = lpStream[0] + 1; + + if(Patterns.Insert(nPat, nRows)) + return false; + + dwMemPos++; + + MODCOMMAND *mrow = Patterns[nPat]; + MODCOMMAND *m = mrow; + ROWINDEX nRow = 0; + BYTE flags; + + while((nRow < nRows) && (dwMemPos < dwMemLength)) + { + ASSERT_CAN_READ(1); + flags = lpStream[dwMemPos]; + dwMemPos++; + if (flags == 0) + { + nRow++; + m = mrow = Patterns[nPat] + nRow * m_nChannels; + continue; + } + + m = mrow + min((flags & 0x1F), m_nChannels - 1); + + if(flags & 0xE0) + { + if (flags & 0x80) // effect + { + ASSERT_CAN_READ(2); + m->command = lpStream[dwMemPos + 1]; + m->param = lpStream[dwMemPos]; + dwMemPos += 2; + switch(m->command) + { + case 0x00: if (m->param) m->command = CMD_ARPEGGIO; break; + case 0x01: m->command = CMD_PORTAMENTOUP; break; + case 0x02: m->command = CMD_PORTAMENTODOWN; break; + case 0x03: m->command = CMD_TONEPORTAMENTO; break; + case 0x04: m->command = CMD_VIBRATO; break; + case 0x05: m->command = CMD_TONEPORTAVOL; if (m->param & 0xF0) m->param &= 0xF0; break; + case 0x06: m->command = CMD_VIBRATOVOL; if (m->param & 0xF0) m->param &= 0xF0; break; + case 0x07: m->command = CMD_TREMOLO; break; + case 0x08: m->command = CMD_PANNING8; + if(m->param <= 0x80) m->param = min(m->param << 1, 0xFF); + else if(m->param == 0xA4) {m->command = CMD_S3MCMDEX; m->param = 0x91;} + break; + case 0x09: m->command = CMD_OFFSET; break; + case 0x0A: m->command = CMD_VOLUMESLIDE; if (m->param & 0xF0) m->param &= 0xF0; break; + case 0x0B: m->command = CMD_POSITIONJUMP; break; + case 0x0C: m->command = CMD_VOLUME; break; + case 0x0D: m->command = CMD_PATTERNBREAK; m->param = ((m->param >> 4) * 10) + (m->param & 0x0F); break; + case 0x0E: m->command = CMD_MODCMDEX; MODExx2S3MSxx(m); break; + case 0x0F: m->command = (m->param <= 0x1F) ? CMD_SPEED : CMD_TEMPO; break; + case 'G' - 55: m->command = CMD_GLOBALVOLUME; break; + case 'H' - 55: m->command = CMD_GLOBALVOLSLIDE; if (m->param & 0xF0) m->param &= 0xF0; break; + case 'K' - 55: m->command = CMD_KEYOFF; break; + case 'L' - 55: m->command = CMD_SETENVPOSITION; break; + case 'M' - 55: m->command = CMD_CHANNELVOLUME; break; + case 'N' - 55: m->command = CMD_CHANNELVOLSLIDE; break; + case 'P' - 55: m->command = CMD_PANNINGSLIDE; if (m->param & 0xF0) m->param &= 0xF0; break; + case 'R' - 55: m->command = CMD_RETRIG; break; + case 'T' - 55: m->command = CMD_TREMOR; break; + case 'X' - 55: + 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; + default: m->command = CMD_S3MCMDEX; break; + } + break; + default: +#ifdef DEBUG + { + CHAR s[64]; + wsprintf(s, "J2B: Unknown command: 0x%X, param 0x%X", m->command, m->param); + Log(s); + } +#endif + m->command = CMD_NONE; + break; + } + } + + if (flags & 0x40) // note + ins + { + ASSERT_CAN_READ(2); + m->instr = lpStream[dwMemPos]; + m->note = lpStream[dwMemPos + 1]; + if(m->note > NOTE_MAX) m->note = NOTE_NOTECUT; + dwMemPos += 2; + } + + if (flags & 0x20) // volume + { + ASSERT_CAN_READ(1); + m->volcmd = VOLCMD_VOLUME; + if(!bIsAM) + m->vol = lpStream[dwMemPos]; + else + m->vol = lpStream[dwMemPos] * 64 / 127; + dwMemPos++; + } + } + } + + return true; + + #undef ASSERT_CAN_READ +} + +bool CSoundFile::ReadAM(const LPCBYTE lpStream, const DWORD dwMemLength) +//------------------------------------------------------------------------ +{ + #define ASSERT_CAN_READ(x) \ + if( dwMemPos > dwMemLength || x > dwMemLength - dwMemPos ) return false; + #define ASSERT_CAN_READ_CHUNK(x) \ + if( dwMemPos > dwChunkEnd || x > dwChunkEnd - dwMemPos ) break; + + DWORD dwMemPos = 0; + + ASSERT_CAN_READ(sizeof(RIFFCHUNK)); + RIFFCHUNK *chunkheader = (RIFFCHUNK *)lpStream; + + if(LittleEndian(chunkheader->signature) != 0x46464952 // "RIFF" + || LittleEndian(chunkheader->chunksize) != dwMemLength - sizeof(RIFFCHUNK) + ) return false; + + dwMemPos += sizeof(RIFFCHUNK); + + bool bIsAM; // false: AMFF, true: AM + + if(LittleEndian(*(DWORD *)(lpStream + dwMemPos)) == 0x46464D41) bIsAM = false; // "AMFF" + else if(LittleEndian(*(DWORD *)(lpStream + dwMemPos)) == 0x20204D41) bIsAM = true; // "AM " + else return false; + dwMemPos += 4; + + // go through all chunks now + while(dwMemPos < dwMemLength) + { + ASSERT_CAN_READ(sizeof(RIFFCHUNK)); + chunkheader = (RIFFCHUNK *)(lpStream + dwMemPos); + dwMemPos += sizeof(RIFFCHUNK); + ASSERT_CAN_READ(LittleEndian(chunkheader->chunksize)); + + DWORD dwChunkEnd = dwMemPos + LittleEndian(chunkheader->chunksize); + if(bIsAM && (LittleEndian(chunkheader->chunksize) & 1)) dwChunkEnd++; + + switch(LittleEndian(chunkheader->signature)) + { + case 0x4E49414D: // "MAIN" - Song info (AMFF) + case 0x54494E49: // "INIT" - Song info (AM) + if((LittleEndian(chunkheader->signature) == 0x4E49414D && !bIsAM) || (LittleEndian(chunkheader->signature) == 0x54494E49 && bIsAM)) + { + ASSERT_CAN_READ_CHUNK(sizeof(AMFFCHUNK_MAIN)); + AMFFCHUNK_MAIN *mainchunk = (AMFFCHUNK_MAIN *)(lpStream + dwMemPos); + dwMemPos += sizeof(AMFFCHUNK_MAIN); + + ASSERT_CAN_READ_CHUNK(mainchunk->channels); + + memcpy(m_szNames[0], mainchunk->songname, 32); + SetNullTerminator(m_szNames[0]); + m_dwSongFlags = SONG_ITOLDEFFECTS | SONG_ITCOMPATMODE; + if(!(mainchunk->flags & 0x01)) m_dwSongFlags |= SONG_LINEARSLIDES; + if(mainchunk->channels < 1) return false; + m_nChannels = min(mainchunk->channels, MAX_BASECHANNELS); + m_nDefaultSpeed = mainchunk->speed; + m_nDefaultTempo = mainchunk->tempo; + m_nDefaultGlobalVolume = mainchunk->globalvolume << 1; + m_nSamplePreAmp = m_nVSTiVolume = 48; + m_nType = MOD_TYPE_IT; + + for(CHANNELINDEX nChn = 0; nChn < m_nChannels; nChn++) + { + if(bIsAM) + { + if(lpStream[dwMemPos + nChn] > 128) + { + ChnSettings[nChn].nPan = 128; + ChnSettings[nChn].nVolume = 0; + } else + { + ChnSettings[nChn].nPan = lpStream[dwMemPos + nChn] << 1; + ChnSettings[nChn].nVolume = 64; + } + } else + { + if(lpStream[dwMemPos + nChn] >= 128) + { + ChnSettings[nChn].nPan = 128; + ChnSettings[nChn].nVolume = 0; + } else + { + ChnSettings[nChn].nPan = lpStream[dwMemPos + nChn] << 2; + ChnSettings[nChn].nVolume = 64; + } + } + } + dwMemPos += mainchunk->channels; + } + break; + + case 0x5244524F: // "ORDR" - Order list + ASSERT_CAN_READ_CHUNK(1); + Order.ReadAsByte(&lpStream[dwMemPos + 1], lpStream[dwMemPos] + 1, dwChunkEnd - (dwMemPos + 1)); + break; + + case 0x54544150: // "PATT" - Pattern data for one pattern + ASSERT_CAN_READ_CHUNK(5); + Convert_RIFF_AM_Pattern(lpStream[dwMemPos], (LPCBYTE)(lpStream + dwMemPos + 5), LittleEndian(*(DWORD *)(lpStream + dwMemPos + 1)), bIsAM); + break; + + case 0x54534E49: // "INST" - Instrument (only in RIFF AMFF) + if(!bIsAM) + { + ASSERT_CAN_READ_CHUNK(sizeof(AMFFCHUNK_INSTRUMENT)); + AMFFCHUNK_INSTRUMENT *inschunk = (AMFFCHUNK_INSTRUMENT *)(lpStream + dwMemPos); + dwMemPos += sizeof(AMFFCHUNK_INSTRUMENT); + + SAMPLEINDEX nSmp = inschunk->sample + 1; + if(nSmp > MAX_SAMPLES) + break; + m_nSamples = max(m_nSamples, nSmp); + + memcpy(m_szNames[nSmp], inschunk->name, 28); + m_szNames[nSmp][28] = 0; + + ASSERT_CAN_READ_CHUNK(sizeof(AMFFCHUNK_SAMPLE)); + AMFFCHUNK_SAMPLE *smpchunk = (AMFFCHUNK_SAMPLE *)(lpStream + dwMemPos); + dwMemPos += sizeof(AMFFCHUNK_SAMPLE); + + if(smpchunk->signature != 0x504D4153) break; // SAMP + + memcpy(m_szNames[nSmp], smpchunk->name, 28); + m_szNames[nSmp][28] = 0; + + Samples[nSmp].nPan = smpchunk->pan << 2; + Samples[nSmp].nVolume = smpchunk->volume << 2; + Samples[nSmp].nGlobalVol = 64; + Samples[nSmp].nLength = LittleEndian(smpchunk->length); + Samples[nSmp].nLoopStart = LittleEndian(smpchunk->loopstart); + Samples[nSmp].nLoopEnd = LittleEndian(smpchunk->loopend); + Samples[nSmp].nC5Speed = LittleEndian(smpchunk->samplerate); + + if(LittleEndianW(smpchunk->flags) & 0x04) + Samples[nSmp].uFlags |= CHN_16BIT; + if(LittleEndianW(smpchunk->flags) & 0x08) + Samples[nSmp].uFlags |= CHN_LOOP; + if(LittleEndianW(smpchunk->flags) & 0x10) + Samples[nSmp].uFlags |= CHN_PINGPONGLOOP; + if(LittleEndianW(smpchunk->flags) & 0x20) + Samples[nSmp].uFlags |= CHN_PANNING; + + dwMemPos += ReadSample(&Samples[nSmp], (LittleEndianW(smpchunk->flags) & 0x04) ? RS_PCM16S : RS_PCM8S, (LPCSTR)(lpStream + dwMemPos), dwMemLength - dwMemPos); + } + break; + + case 0x46464952: // "RIFF" - Instrument (only in RIFF AM) + if(bIsAM) + { + ASSERT_CAN_READ_CHUNK(4); + if(LittleEndian(*(DWORD *)(lpStream + dwMemPos)) != 0x20204941) break; // "AI " + dwMemPos += 4; + + ASSERT_CAN_READ_CHUNK(sizeof(RIFFCHUNK)); + RIFFCHUNK *instchunk = (RIFFCHUNK *)(lpStream + dwMemPos); + dwMemPos += sizeof(RIFFCHUNK); + ASSERT_CAN_READ_CHUNK(LittleEndian(instchunk->chunksize)); + if(LittleEndian(instchunk->signature) != 0x54534E49) break; // "INST" + + ASSERT_CAN_READ_CHUNK(4); + DWORD dwHeadlen = LittleEndian(*(DWORD *)(lpStream + dwMemPos)); + dwMemPos +=4 ; + + ASSERT_CAN_READ_CHUNK(sizeof(AMCHUNK_INSTRUMENT)); + AMCHUNK_INSTRUMENT *instheadchunk = (AMCHUNK_INSTRUMENT *)(lpStream + dwMemPos); + dwMemPos += dwHeadlen; + + SAMPLEINDEX nSmp = instheadchunk->sample + 1; + if(nSmp > MAX_SAMPLES) + break; + m_nSamples = max(m_nSamples, nSmp); + + memcpy(m_szNames[nSmp], instheadchunk->name, 32); + m_szNames[nSmp][32] = 0; + + ASSERT_CAN_READ_CHUNK(sizeof(RIFFCHUNK)); + instchunk = (RIFFCHUNK *)(lpStream + dwMemPos); + dwMemPos += sizeof(RIFFCHUNK); + ASSERT_CAN_READ_CHUNK(LittleEndian(instchunk->chunksize)); + if(LittleEndian(instchunk->signature) != 0x46464952) break; // yet another "RIFF"... + + ASSERT_CAN_READ_CHUNK(4); + if(LittleEndian(*(DWORD *)(lpStream + dwMemPos)) != 0x20205341) break; // "AS " (ain't this boring?) + dwMemPos += 4; + + ASSERT_CAN_READ_CHUNK(sizeof(AMCHUNK_SAMPLE)); + AMCHUNK_SAMPLE *smpchunk = (AMCHUNK_SAMPLE *)(lpStream + dwMemPos); + + if(smpchunk->signature != 0x504D4153) break; // SAMP + + memcpy(m_szNames[nSmp], smpchunk->name, 32); + m_szNames[nSmp][32] = 0; + + if(LittleEndianW(smpchunk->pan) > 0x7FFF || LittleEndianW(smpchunk->volume) > 0x7FFF) + break; + + Samples[nSmp].nPan = LittleEndianW(smpchunk->pan) * 256 / 32767; + Samples[nSmp].nVolume = LittleEndianW(smpchunk->volume) * 256 / 32767; + Samples[nSmp].nGlobalVol = 64; + Samples[nSmp].nLength = LittleEndian(smpchunk->length); + Samples[nSmp].nLoopStart = LittleEndian(smpchunk->loopstart); + Samples[nSmp].nLoopEnd = LittleEndian(smpchunk->loopend); + Samples[nSmp].nC5Speed = LittleEndian(smpchunk->samplerate); + + if(LittleEndianW(smpchunk->flags) & 0x04) + Samples[nSmp].uFlags |= CHN_16BIT; + if(LittleEndianW(smpchunk->flags) & 0x08) + Samples[nSmp].uFlags |= CHN_LOOP; + if(LittleEndianW(smpchunk->flags) & 0x10) + Samples[nSmp].uFlags |= CHN_PINGPONGLOOP; + if(LittleEndianW(smpchunk->flags) & 0x20) + Samples[nSmp].uFlags |= CHN_PANNING; + + dwMemPos += LittleEndian(smpchunk->headsize); + dwMemPos += ReadSample(&Samples[nSmp], (LittleEndianW(smpchunk->flags) & 0x04) ? RS_PCM16S : RS_PCM8S, (LPCSTR)(lpStream + dwMemPos), dwMemLength - dwMemPos); + } + break; + + } + dwMemPos = dwChunkEnd; + } + + return true; + + #undef ASSERT_CAN_READ + #undef ASSERT_CAN_READ_CHUNK +} + +bool CSoundFile::ReadJ2B(const LPCBYTE lpStream, const DWORD dwMemLength) +//----------------------------------------------------------------------- +{ + #define ASSERT_CAN_READ(x) \ + if( dwMemPos > dwMemLength || x > dwMemLength - dwMemPos ) return false; + + DWORD dwMemPos = 0; + + ASSERT_CAN_READ(sizeof(J2BHEADER)); + J2BHEADER *header = (J2BHEADER *)lpStream; + + if(LittleEndian(header->signature) != 0x4553554D // "MUSE" + || (LittleEndian(header->deadbeaf) != 0xAFBEADDE // 0xDEADBEAF (RIFF AM) + && LittleEndian(header->deadbeaf) != 0xBEBAADDE) // 0xDEADBABE (RIFF AMFF) + || LittleEndian(header->j2blength) != dwMemLength + || LittleEndian(header->packed_length) != dwMemLength - sizeof(J2BHEADER) + || LittleEndian(header->packed_length) == 0 + || LittleEndian(header->crc32) != crc32(0, (lpStream + sizeof(J2BHEADER)), dwMemLength - sizeof(J2BHEADER)) + ) return false; + + dwMemPos += sizeof(J2BHEADER); + + // header is valid, now unpack the RIFF AM file using inflate + z_stream strm; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + if(inflateInit(&strm) != Z_OK) + return false; + + Bytef* bOutput = new Bytef[LittleEndian(header->unpacked_length) + 1]; + + strm.avail_in = dwMemLength - dwMemPos; + strm.next_in = (Bytef *)(lpStream + dwMemPos); + strm.avail_out = LittleEndian(header->unpacked_length); + strm.next_out = bOutput; + + int nRetVal = inflate(&strm, Z_NO_FLUSH); + (void)inflateEnd(&strm); + + if(strm.avail_in != 0 || nRetVal == Z_STREAM_ERROR || nRetVal == Z_NEED_DICT || nRetVal == Z_DATA_ERROR || nRetVal == Z_MEM_ERROR || nRetVal != Z_STREAM_END) + { + return false; + } + + bool bResult = false; + + if(strm.total_out == LittleEndian(header->unpacked_length)) + { + // Success, now load the RIFF AM(FF) module. + bResult = ReadAM(bOutput, strm.total_out); + } + delete[] bOutput; + + return bResult; + + #undef ASSERT_CAN_READ +} Added: trunk/OpenMPT/zlib/ChangeLog =================================================================== --- trunk/OpenMPT/zlib/ChangeLog (rev 0) +++ trunk/OpenMPT/zlib/ChangeLog 2009-10-09 00:00:56 UTC (rev 391) @@ -0,0 +1,855 @@ + + ChangeLog file for zlib + +Changes in 1.2.3 (18 July 2005) +- Apply security vulnerability fixes to contrib/infback9 as well +- Clean up some text files (carriage returns, trailing space) +- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] + +Changes in 1.2.2.4 (11 July 2005) +- Add inflatePrime() function for starting inflation at bit boundary +- Avoid some Visual C warnings in deflate.c +- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit + compile +- Fix some spelling errors in comments [Betts] +- Correct inflateInit2() error return documentation in zlib.h +- Added zran.c example of compressed data random access to examples + directory, shows use of inflatePrime() +- Fix cast for assignments to strm->state in inflate.c and infback.c +- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] +- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] +- Add cast in trees.c t avoid a warning [Oberhumer] +- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] +- Update make_vms.com [Zinser] +- Initialize state->write in inflateReset() since copied in inflate_fast() +- Be more strict on incomplete code sets in inflate_table() and increase + ENOUGH and MAXD -- this repairs a possible security vulnerability for + invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for + discovering the vulnerability and providing test cases. +- Add ia64 support to configure for HP-UX [Smith] +- Add error return to gzread() for format or i/o error [Levin] +- Use malloc.h for OS/2 [Necasek] + +Changes in 1.2.2.3 (27 May 2005) +- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile +- Typecast fread() return values in gzio.c [Vollant] +- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) +- Fix crc check bug in gzread() after gzungetc() [Heiner] +- Add the deflateTune() function to adjust internal compression parameters +- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) +- Remove an incorrect assertion in examples/zpipe.c +- Add C++ wrapper in infback9.h [Donais] +- Fix bug in inflateCopy() when decoding fixed codes +- Note in zlib.h how much deflateSetDictionary() actually uses +- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) +- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] +- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] +- Add gzdirect() function to indicate transparent reads +- Update contrib/minizip [Vollant] +- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] +- Add casts in crc32.c to avoid warnings [Oberhumer] +- Add contrib/masmx64 [Vollant] +- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] + +Changes in 1.2.2.2 (30 December 2004) +- Replace structure assignments in deflate.c and inflate.c with zmemcpy to + avoid implicit memcpy calls (portability for no-library compilation) +- Increase sprintf() buffer size in gzdopen() to allow for large numbers +- Add INFLATE_STRICT to check distances against zlib header +- Improve WinCE errno handling and comments [Chang] +- Remove comment about no gzip header processing in FAQ +- Add Z_FIXED strategy option to deflateInit2() to force fixed trees +- Add updated make_vms.com [Coghlan], update README +- Create a new "examples" directory, move gzappend.c there, add zpipe.c, + fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. +- Add FAQ entry and comments in deflate.c on uninitialized memory access +- Add Solaris 9 make options in configure [Gilbert] +- Allow strerror() usage in gzio.c for STDC +- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] +- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] +- Use z_off_t for adler32_combine() and crc32_combine() lengths +- Make adler32() much faster for small len +- Use OS_CODE in deflate() default gzip header + +Changes in 1.2.2.1 (31 October 2004) +- Allow inflateSetDictionary() call for raw inflate +- Fix inflate header crc check bug for file names and comments +- Add deflateSetHeader() and gz_header structure for custom gzip headers +- Add inflateGetheader() to retrieve gzip headers +- Add crc32_combine() and adler32_combine() functions +- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list +- Use zstreamp consistently in zlib.h (inflate_back functions) +- Remove GUNZIP condition from definition of inflate_mode in inflate.h + and in contrib/inflate86/inffast.S [Truta, Anderson] +- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] +- Update projects/README.projects and projects/visualc6 [Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] +- Deprecate Z_ASCII; use Z_TEXT instead [Truta] +- Use a new algorithm for setting strm->data_type in trees.c [Truta] +- Do not define an exit() prototype in zutil.c unless DEBUG defined +- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] +- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() +- Fix Darwin build version identification [Peterson] + +Changes in 1.2.2 (3 October 2004) +- Update zlib.h comments on gzip in-memory processing +- Set adler to 1 in inflateReset() to support Java test suite [Walles] +- Add contrib/dotzlib [Ravn] +- Update win32/DLL_FAQ.txt [Truta] +- Update contrib/minizip [Vollant] +- Move contrib/visual-basic.txt to old/ [Truta] +- Fix assembler builds in projects/visualc6/ [Truta] + +Changes in 1.2.1.2 (9 September 2004) +- Update INDEX file +- Fix trees.c to update strm->data_type (no one ever noticed!) +- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] +- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) +- Add limited multitasking protection to DYNAMIC_CRC_TABLE +- Add NO_vsnprintf for VMS in zutil.h [Mozilla] +- Don't declare strerror() under VMS [Mozilla] +- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize +- Update contrib/ada [Anisimkov] +- Update contrib/minizip [Vollant] +- Fix configure to not hardcode directories for Darwin [Peterson] +- Fix gzio.c to not return error on empty files [Brown] +- Fix indentation; update version in contrib/delphi/ZLib.pas and + contrib/pascal/zlibpas.pas [Truta] +- Update mkasm.bat in contrib/masmx86 [Truta] +- Update contrib/untgz [Truta] +- Add projects/README.projects [Truta] +- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] +- Remove an unnecessary assignment to curr in inftrees.c [Truta] +- Add OS/2 to exe builds in configure [Poltorak] +- Remove err dummy parameter in zlib.h [Kientzle] + +Changes in 1.2.1.1 (9 January 2004) +- Update email address in README +- Several FAQ updates +- Fix a big fat bug in inftrees.c that prevented decoding valid + dynamic blocks with only literals and no distance codes -- + Thanks to "Hot Emu" for the bug report and sample file +- Add a note to puff.c on no distance codes case. + +Changes in 1.2.1 (17 November 2003) +- Remove a tab in contrib/gzappend/gzappend.c +- Update some interfaces in contrib for new zlib functions +- Update zlib version number in some contrib entries +- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] +- Support shared libraries on Hurd and KFreeBSD [Brown] +- Fix error in NO_DIVIDE option of adler32.c + +Changes in 1.2.0.8 (4 November 2003) +- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas +- Add experimental NO_DIVIDE #define in adler32.c + - Possibly faster on some processors (let me know if it is) +- Correct Z_BLOCK to not return on first inflate call if no wrap +- Fix strm->data_type on inflate() return to correctly indicate EOB +- Add deflatePrime() function for appending in the middle of a byte +- Add contrib/gzappend for an example of appending to a stream +- Update win32/DLL_FAQ.txt [Truta] +- Delete Turbo C comment in README [Truta] +- Improve some indentation in zconf.h [Truta] +- Fix infinite loop on bad input in configure script [Church] +- Fix gzeof() for concatenated gzip files [Johnson] +- Add example to contrib/visual-basic.txt [Michael B.] +- Add -p to mkdir's in Makefile.in [vda] +- Fix configure to properly detect presence or lack of printf functions +- Add AS400 support [Monnerat] +- Add a little Cygwin support [Wilson] + +Changes in 1.2.0.7 (21 September 2003) +- Correct some debug formats in contrib/infback9 +- Cast a type in a debug statement in trees.c +- Change search and replace delimiter in configure from % to # [Beebe] +- Update contrib/untgz to 0.2 with various fixes [Truta] +- Add build support for Amiga [Nikl] +- Remove some directories in old that have been updated to 1.2 +- Add dylib building for Mac OS X in configure and Makefile.in +- Remove old distribution stuff from Makefile +- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X +- Update links in README + +Changes in 1.2.0.6 (13 September 2003) +- Minor FAQ updates +- Update contrib/minizip to 1.00 [Vollant] +- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] +- Update POSTINC comment for 68060 [Nikl] +- Add contrib/infback9 with deflate64 decoding (unsupported) +- For MVS define NO_vsnprintf and undefine FAR [van Burik] +- Add pragma for fdopen on MVS [van Burik] + +Changes in 1.2.0.5 (8 September 2003) +- Add OF to inflateBackEnd() declaration in zlib.h +- Remember start when using gzdopen in the middle of a file +- Use internal off_t counters in gz* functions to properly handle seeks +- Perform more rigorous check for distance-too-far in inffast.c +- Add Z_BLOCK flush option to return from inflate at block boundary +- Set strm->data_type on return from inflate + - Indicate bits unused, if at block boundary, and if in last block +- Replace size_t with ptrdiff_t in crc32.c, and check for correct size +- Add condition so old NO_DEFLATE define still works for compatibility +- FAQ update regarding the Windows DLL [Truta] +- INDEX update: add qnx entry, remove aix entry [Truta] +- Install zlib.3 into mandir [Wilson] +- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] +- Adapt the zlib interface to the new DLL convention guidelines [Truta] +- Introduce ZLIB_WINAPI macro to allow the export of functions using + the WINAPI calling convention, for Visual Basic [Vollant, Truta] +- Update msdos and win32 scripts and makefiles [Truta] +- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] +- Add contrib/ada [Anisimkov] +- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] +- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] +- Add contrib/masm686 [Truta] +- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm + [Truta, Vollant] +- Update contrib/delphi; rename to contrib/pascal; add example [Truta] +- Remove contrib/delphi2; add a new contrib/delphi [Truta] +- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream, + and fix some method prototypes [Truta] +- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip + [Truta] +- Avoid the use of backslash (\) in contrib/minizip [Vollant] +- Fix file time handling in contrib/untgz; update makefiles [Truta] +- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines + [Vollant] +- Remove contrib/vstudio/vc15_16 [Vollant] +- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] +- Update README.contrib [Truta] +- Invert the assignment order of match_head and s->prev[...] in + INSERT_STRING [Truta] +- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings + [Truta] +- Compare function pointers with 0, not with NULL or Z_NULL [Truta] +- Fix prototype of syncsearch in inflate.c [Truta] +- Introduce ASMINF macro to be enabled when using an ASM implementation + of inflate_fast [Truta] +- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] +- Modify test_gzio in example.c to take a single file name as a + parameter [Truta] +- Exit the example.c program if gzopen fails [Truta] +- Add type casts around strlen in example.c [Truta] +- Remove casting to sizeof in minigzip.c; give a proper type + to the variable compared with SUFFIX_LEN [Truta] +- Update definitions of STDC and STDC99 in zconf.h [Truta] +- Synchronize zconf.h with the new Windows DLL interface [Truta] +- Use SYS16BIT instead of __32BIT__ to distinguish between + 16- and 32-bit platforms [Truta] +- Use far memory allocators in small 16-bit memory models for + Turbo C [Truta] +- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in + zlibCompileFlags [Truta] +- Cygwin has vsnprintf [Wilson] +- In Windows16, OS_CODE is 0, as in MSDOS [Truta] +- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] + +Changes in 1.2.0.4 (10 August 2003) +- Minor FAQ updates +- Be more strict when checking inflateInit2's windowBits parameter +- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well +- Add gzip wrapper option to deflateInit2 using windowBits +- Add updated QNX rule in configure and qnx directory [Bonnefoy] +- Make inflate distance-too-far checks more rigorous +- Clean up FAR usage in inflate +- Add casting to sizeof() in gzio.c and minigzip.c + +Changes in 1.2.0.3 (19 July 2003) +- Fix silly error in gzungetc() implementation [Vollant] +- Update contrib/minizip and contrib/vstudio [Vollant] +- Fix printf format in example.c +- Correct cdecl support in zconf.in.h [Anisimkov] +- Minor FAQ updates + +Changes in 1.2.0.2 (13 July 2003) +- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons +- Attempt to avoid warnings in crc32.c for pointer-int conversion +- Add AIX to configure, remove aix directory [Bakker] +- Add some casts to minigzip.c +- Improve checking after insecure sprintf() or vsprintf() calls +- Remove #elif's from crc32.c +- Change leave label to inf_leave in inflate.c and infback.c to avoid + library conflicts +- Remove inflate gzip decoding by default--only enable gzip decoding by + special request for stricter backward compatibility +- Add zlibCompileFlags() function to return compilation information +- More typecasting in deflate.c to avoid warnings +- Remove leading underscore from _Capital #defines [Truta] +- Fix configure to link shared library when testing +- Add some Windows CE target adjustments [Mai] +- Remove #define ZLIB_DLL in zconf.h [Vollant] +- Add zlib.3 [Rodgers] +- Update RFC URL in deflate.c and algorithm.txt [Mai] +- Add zlib_dll_FAQ.txt to contrib [Truta] +- Add UL to some constants [Truta] +- Update minizip and vstudio [Vollant] +- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h +- Expand use of NO_DUMMY_DECL to avoid all dummy structures +- Added iostream3 to contrib [Schwardt] +- Replace rewind() with fseek() for WinCE [Truta] +- Improve setting of zlib format compression level flags + - Report 0 for huffman and rle strategies and for level == 0 or 1 + - Report 2 only for level == 6 +- Only deal with 64K limit when necessary at compile time [Truta] +- Allow TOO_FAR check to be turned off at compile time [Truta] +- Add gzclearerr() function [Souza] +- Add gzungetc() function + +Changes in 1.2.0.1 (17 March 2003) +- Add Z_RLE strategy for run-length encoding [Truta] + - When Z_RLE requested, restrict matches to distance one + - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE +- Correct FASTEST compilation to allow level == 0 +- Clean up what gets compiled for FASTEST +- Incorporate changes to zconf.in.h [Vollant] + - Refine detection of Turbo C need for dummy returns + - Refine ZLIB_DLL compilation + - Include additional header file on VMS for off_t typedef +- Try to use _vsnprintf where it supplants vsprintf [Vollant] +- Add some casts in inffast.c +- Enchance comments in zlib.h on what happens if gzprintf() tries to + write more than 4095 bytes before compression +- Remove unused state from inflateBackEnd() +- Remove exit(0) from minigzip.c, example.c +- Get rid of all those darn tabs +- Add "check" target to Makefile.in that does the same thing as "test" +- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in +- Update contrib/inflate86 [Anderson] +- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] +- Add msdos and win32 directories with makefiles [Truta] +- More additions and improvements to the FAQ + +Changes in 1.2.0 (9 March 2003) +- New and improved inflate code + - About 20% faster + - Does not allocate 32K window unless and until needed + - Automatically detects and decompresses gzip streams + - Raw inflate no longer needs an extra dummy byte at end + - Added inflateBack functions using a callback interface--even faster + than inflate, useful for file utilities (gzip, zip) + - Added inflateCopy() function to record state for random access on + externally generated deflate streams (e.g. in gzip files) + - More readable code (I hope) +- New and improved crc32() + - About 50% faster, thanks to suggestions from Rodney Brown +- Add deflateBound() and compressBound() functions +- Fix memory leak in deflateInit2() +- Permit setting dictionary for raw deflate (for parallel deflate) +- Fix const declaration for gzwrite() +- Check for some malloc() failures in gzio.c +- Fix bug in gzopen() on single-byte file 0x1f +- Fix bug in gzread() on concatenated file with 0x1f at end of buffer + and next buffer doesn't start with 0x8b +- Fix uncompress() to return Z_DATA_ERROR on truncated input +- Free memory at end of example.c +- Remove MAX #define in trees.c (conflicted with some libraries) +- Fix static const's in deflate.c, gzio.c, and zutil.[ch] +- Declare malloc() and free() in gzio.c if STDC not defined +- Use malloc() instead of calloc() in zutil.c if int big enough +- Define STDC for AIX +- Add aix/ with approach for compiling shared library on AIX +- Add HP-UX support for shared libraries in configure +- Add OpenUNIX support for shared libraries in configure +- Use $cc instead of gcc to build shared library +- Make prefix directory if needed when installing +- Correct Macintosh avoidance of typedef Byte in zconf.h +- Correct Turbo C memory allocation when under Linux +- Use libz.a instead of -lz in Makefile (assure use of compiled library) +- Update configure to check for snprintf or vsnprintf functions and their + return value, warn during make if using an insecure function +- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that + is lost when library is used--resolution is to build new zconf.h +- Documentation improvements (in zlib.h): + - Document raw deflate and inflate + - Update RFCs URL + - Point out that zlib and gzip formats are different + - Note that Z_BUF_ERROR is not fatal + - Document string limit for gzprintf() and possible buffer overflow + - Note requirement on avail_out when flushing + - Note permitted values of flush parameter of inflate() +- Add some FAQs (and even answers) to the FAQ +- Add contrib/inflate86/ for x86 faster inflate +- Add contrib/blast/ for PKWare Data Compression Library decompression +- Add contrib/puff/ simple inflate for deflate format description + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent + occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file + (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) + See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean" (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: + . zutil.c, zutil.h: added "const" for zmem* + . Make_vms.com: fixed some typos + . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists + . msdos/Makefile.msc: remove "default rtl link library" info from obj files + . msdos/Makefile.*: use model-dependent name for the built zlib library + . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: + new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) + See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code + completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib + (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the + compression ratio on some files. This also allows inlining _tr_tally for + matches in deflate_slow. +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase siz... [truncated message content] |
From: <rel...@us...> - 2009-10-09 21:13:05
|
Revision: 392 http://modplug.svn.sourceforge.net/modplug/?rev=392&view=rev Author: relabsoluness Date: 2009-10-09 21:12:52 +0000 (Fri, 09 Oct 2009) Log Message: ----------- [Fix] Internal: Added zlib project to VC2003 solution and fixed build errors (zlib project(VC9) and VC2003 specific compilation errors). Modified Paths: -------------- trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/mptrack/MPTRACK.sln trunk/OpenMPT/mptrack/View_tre.h trunk/OpenMPT/zlib/contrib/vstudio/vc7/zlibstat.vcproj trunk/OpenMPT/zlib/contrib/vstudio/vc9/zlibstat.vcproj Modified: trunk/OpenMPT/mptrack/CleanupSong.cpp =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp 2009-10-09 00:00:56 UTC (rev 391) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp 2009-10-09 21:12:52 UTC (rev 392) @@ -261,8 +261,9 @@ if (pNMHDR->code == TTN_NEEDTEXTA) { - strncpy_s(pTTTA->szText, sizeof(pTTTA->szText), strTipText, - strTipText.GetLength() + 1); + //strncpy_s(pTTTA->szText, sizeof(pTTTA->szText), strTipText, + // strTipText.GetLength() + 1); + strncpy(pTTTA->szText, strTipText, strTipText.GetLength() + 1); } else { Modified: trunk/OpenMPT/mptrack/MPTRACK.sln =================================================================== --- trunk/OpenMPT/mptrack/MPTRACK.sln 2009-10-09 00:00:56 UTC (rev 391) +++ trunk/OpenMPT/mptrack/MPTRACK.sln 2009-10-09 21:12:52 UTC (rev 392) @@ -2,6 +2,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mptrack", "mptrack.vcproj", "{DB18719C-9177-4632-A9E0-7E72E2E6B05E}" ProjectSection(ProjectDependencies) = postProject {1FF4AB04-B22F-4CB8-AA2A-0C5095B5FEE4} = {1FF4AB04-B22F-4CB8-AA2A-0C5095B5FEE4} + {3F7D3110-B3DD-4DE1-B608-C3F491009625} = {3F7D3110-B3DD-4DE1-B608-C3F491009625} {71531076-78C7-488D-8FD6-9D841F20AADE} = {71531076-78C7-488D-8FD6-9D841F20AADE} {CF3C2CA5-5D45-4635-BBA4-C1F435E10896} = {CF3C2CA5-5D45-4635-BBA4-C1F435E10896} {3C7281B0-D0E2-48ED-AE4D-A181FC77D8F7} = {3C7281B0-D0E2-48ED-AE4D-A181FC77D8F7} @@ -23,14 +24,20 @@ ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "soundtouch", "..\soundtouch\soundtouch.vcproj", "{CF3C2CA5-5D45-4635-BBA4-C1F435E10896}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SoundTouch", "..\soundtouch\soundtouch.vcproj", "{CF3C2CA5-5D45-4635-BBA4-C1F435E10896}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "..\zlib\contrib\vstudio\vc7\zlibstat.vcproj", "{3F7D3110-B3DD-4DE1-B608-C3F491009625}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release + ReleaseAxp = ReleaseAxp + ReleaseWithoutAsm = ReleaseWithoutAsm EndGlobalSection GlobalSection(ProjectDependencies) = postSolution EndGlobalSection @@ -39,26 +46,58 @@ {DB18719C-9177-4632-A9E0-7E72E2E6B05E}.Debug.Build.0 = Debug|Win32 {DB18719C-9177-4632-A9E0-7E72E2E6B05E}.Release.ActiveCfg = Release|Win32 {DB18719C-9177-4632-A9E0-7E72E2E6B05E}.Release.Build.0 = Release|Win32 + {DB18719C-9177-4632-A9E0-7E72E2E6B05E}.ReleaseAxp.ActiveCfg = Release|Win32 + {DB18719C-9177-4632-A9E0-7E72E2E6B05E}.ReleaseAxp.Build.0 = Release|Win32 + {DB18719C-9177-4632-A9E0-7E72E2E6B05E}.ReleaseWithoutAsm.ActiveCfg = Release|Win32 + {DB18719C-9177-4632-A9E0-7E72E2E6B05E}.ReleaseWithoutAsm.Build.0 = Release|Win32 {71531076-78C7-488D-8FD6-9D841F20AADE}.Debug.ActiveCfg = Debug|Win32 {71531076-78C7-488D-8FD6-9D841F20AADE}.Debug.Build.0 = Debug|Win32 {71531076-78C7-488D-8FD6-9D841F20AADE}.Release.ActiveCfg = Release|Win32 {71531076-78C7-488D-8FD6-9D841F20AADE}.Release.Build.0 = Release|Win32 + {71531076-78C7-488D-8FD6-9D841F20AADE}.ReleaseAxp.ActiveCfg = Release|Win32 + {71531076-78C7-488D-8FD6-9D841F20AADE}.ReleaseAxp.Build.0 = Release|Win32 + {71531076-78C7-488D-8FD6-9D841F20AADE}.ReleaseWithoutAsm.ActiveCfg = Release|Win32 + {71531076-78C7-488D-8FD6-9D841F20AADE}.ReleaseWithoutAsm.Build.0 = Release|Win32 {3C7281B0-D0E2-48ED-AE4D-A181FC77D8F7}.Debug.ActiveCfg = Debug|Win32 {3C7281B0-D0E2-48ED-AE4D-A181FC77D8F7}.Debug.Build.0 = Debug|Win32 {3C7281B0-D0E2-48ED-AE4D-A181FC77D8F7}.Release.ActiveCfg = Release|Win32 {3C7281B0-D0E2-48ED-AE4D-A181FC77D8F7}.Release.Build.0 = Release|Win32 + {3C7281B0-D0E2-48ED-AE4D-A181FC77D8F7}.ReleaseAxp.ActiveCfg = Release|Win32 + {3C7281B0-D0E2-48ED-AE4D-A181FC77D8F7}.ReleaseAxp.Build.0 = Release|Win32 + {3C7281B0-D0E2-48ED-AE4D-A181FC77D8F7}.ReleaseWithoutAsm.ActiveCfg = Release|Win32 + {3C7281B0-D0E2-48ED-AE4D-A181FC77D8F7}.ReleaseWithoutAsm.Build.0 = Release|Win32 {1FF4AB04-B22F-4CB8-AA2A-0C5095B5FEE4}.Debug.ActiveCfg = Debug|Win32 {1FF4AB04-B22F-4CB8-AA2A-0C5095B5FEE4}.Debug.Build.0 = Debug|Win32 {1FF4AB04-B22F-4CB8-AA2A-0C5095B5FEE4}.Release.ActiveCfg = Release|Win32 {1FF4AB04-B22F-4CB8-AA2A-0C5095B5FEE4}.Release.Build.0 = Release|Win32 + {1FF4AB04-B22F-4CB8-AA2A-0C5095B5FEE4}.ReleaseAxp.ActiveCfg = Release|Win32 + {1FF4AB04-B22F-4CB8-AA2A-0C5095B5FEE4}.ReleaseAxp.Build.0 = Release|Win32 + {1FF4AB04-B22F-4CB8-AA2A-0C5095B5FEE4}.ReleaseWithoutAsm.ActiveCfg = Release|Win32 + {1FF4AB04-B22F-4CB8-AA2A-0C5095B5FEE4}.ReleaseWithoutAsm.Build.0 = Release|Win32 {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.Debug.ActiveCfg = Debug|Win32 {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.Debug.Build.0 = Debug|Win32 {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.Release.ActiveCfg = Release|Win32 {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.Release.Build.0 = Release|Win32 + {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.ReleaseAxp.ActiveCfg = Release|Win32 + {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.ReleaseAxp.Build.0 = Release|Win32 + {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.ReleaseWithoutAsm.ActiveCfg = Release|Win32 + {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.ReleaseWithoutAsm.Build.0 = Release|Win32 {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.Debug.ActiveCfg = Debug|Win32 {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.Debug.Build.0 = Debug|Win32 {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.Release.ActiveCfg = Release|Win32 {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.Release.Build.0 = Release|Win32 + {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.ReleaseAxp.ActiveCfg = Release|Win32 + {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.ReleaseAxp.Build.0 = Release|Win32 + {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.ReleaseWithoutAsm.ActiveCfg = Release|Win32 + {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.ReleaseWithoutAsm.Build.0 = Release|Win32 + {3F7D3110-B3DD-4DE1-B608-C3F491009625}.Debug.ActiveCfg = Debug|Win32 + {3F7D3110-B3DD-4DE1-B608-C3F491009625}.Debug.Build.0 = Debug|Win32 + {3F7D3110-B3DD-4DE1-B608-C3F491009625}.Release.ActiveCfg = Release|Win32 + {3F7D3110-B3DD-4DE1-B608-C3F491009625}.Release.Build.0 = Release|Win32 + {3F7D3110-B3DD-4DE1-B608-C3F491009625}.ReleaseAxp.ActiveCfg = ReleaseAxp|Win32 + {3F7D3110-B3DD-4DE1-B608-C3F491009625}.ReleaseAxp.Build.0 = ReleaseAxp|Win32 + {3F7D3110-B3DD-4DE1-B608-C3F491009625}.ReleaseWithoutAsm.ActiveCfg = ReleaseWithoutAsm|Win32 + {3F7D3110-B3DD-4DE1-B608-C3F491009625}.ReleaseWithoutAsm.Build.0 = ReleaseWithoutAsm|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection Modified: trunk/OpenMPT/mptrack/View_tre.h =================================================================== --- trunk/OpenMPT/mptrack/View_tre.h 2009-10-09 00:00:56 UTC (rev 391) +++ trunk/OpenMPT/mptrack/View_tre.h 2009-10-09 21:12:52 UTC (rev 392) @@ -53,7 +53,7 @@ vector<HTREEITEM> tiPatterns; HTREEITEM tiSamples[MAX_SAMPLES]; HTREEITEM tiInstruments[MAX_INSTRUMENTS]; - vector<vector<HTREEITEM>> tiOrders; + vector<vector<HTREEITEM> > tiOrders; vector<HTREEITEM> tiSequences; HTREEITEM tiEffects[MAX_MIXPLUGINS]; Modified: trunk/OpenMPT/zlib/contrib/vstudio/vc7/zlibstat.vcproj =================================================================== --- trunk/OpenMPT/zlib/contrib/vstudio/vc7/zlibstat.vcproj 2009-10-09 00:00:56 UTC (rev 391) +++ trunk/OpenMPT/zlib/contrib/vstudio/vc7/zlibstat.vcproj 2009-10-09 21:12:52 UTC (rev 392) @@ -1,8 +1,9 @@ -<?xml version="1.0" encoding = "Windows-1252"?> +<?xml version="1.0" encoding="Windows-1252"?> <VisualStudioProject ProjectType="Visual C++" - Version="7.00" + Version="7.10" Name="zlibstat" + ProjectGUID="{3F7D3110-B3DD-4DE1-B608-C3F491009625}" SccProjectName="" SccLocalPath=""> <Platforms> @@ -23,7 +24,7 @@ AdditionalIncludeDirectories="..\..\..;..\..\masmx86" PreprocessorDefinitions="WIN32;ZLIB_WINAPI" ExceptionHandling="FALSE" - RuntimeLibrary="5" + RuntimeLibrary="1" PrecompiledHeaderFile=".\zlibstatDebug/zlibstat.pch" AssemblerListingLocation=".\zlibstatDebug/" ObjectFile=".\zlibstatDebug/" @@ -51,6 +52,12 @@ Culture="1036"/> <Tool Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> </Configuration> <Configuration Name="ReleaseAxp|Win32" @@ -93,6 +100,12 @@ Name="VCResourceCompilerTool"/> <Tool Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> </Configuration> <Configuration Name="Release|Win32" @@ -108,7 +121,7 @@ PreprocessorDefinitions="WIN32;ZLIB_WINAPI;ASMV;ASMINF" StringPooling="TRUE" ExceptionHandling="FALSE" - RuntimeLibrary="4" + RuntimeLibrary="0" EnableFunctionLevelLinking="TRUE" PrecompiledHeaderFile=".\zlibstat/zlibstat.pch" AssemblerListingLocation=".\zlibstat/" @@ -136,6 +149,12 @@ Culture="1036"/> <Tool Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> </Configuration> <Configuration Name="ReleaseWithoutAsm|Win32" @@ -179,8 +198,16 @@ Culture="1036"/> <Tool Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> </Configuration> </Configurations> + <References> + </References> <Files> <Filter Name="Source Files" Modified: trunk/OpenMPT/zlib/contrib/vstudio/vc9/zlibstat.vcproj =================================================================== --- trunk/OpenMPT/zlib/contrib/vstudio/vc9/zlibstat.vcproj 2009-10-09 00:00:56 UTC (rev 391) +++ trunk/OpenMPT/zlib/contrib/vstudio/vc9/zlibstat.vcproj 2009-10-09 21:12:52 UTC (rev 392) @@ -26,7 +26,7 @@ OutputDirectory="x86\ZlibStat$(ConfigurationName)" IntermediateDirectory="x86\ZlibStat$(ConfigurationName)\Tmp" ConfigurationType="4" - InheritedPropertySheets="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\VCProjectDefaults\UpgradeFromVC70.vsprops" + InheritedPropertySheets="UpgradeFromVC70.vsprops" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="false" > @@ -99,7 +99,7 @@ OutputDirectory="x86\ZlibStat$(ConfigurationName)" IntermediateDirectory="x86\ZlibStat$(ConfigurationName)\Tmp" ConfigurationType="4" - InheritedPropertySheets="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\VCProjectDefaults\UpgradeFromVC70.vsprops" + InheritedPropertySheets="UpgradeFromVC70.vsprops" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="false" > @@ -173,7 +173,7 @@ OutputDirectory="x86\ZlibStat$(ConfigurationName)" IntermediateDirectory="x86\ZlibStat$(ConfigurationName)\Tmp" ConfigurationType="4" - InheritedPropertySheets="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\VCProjectDefaults\UpgradeFromVC70.vsprops" + InheritedPropertySheets="UpgradeFromVC70.vsprops" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="false" > This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-10-10 00:03:47
|
Revision: 393 http://modplug.svn.sourceforge.net/modplug/?rev=393&view=rev Author: saga-games Date: 2009-10-10 00:03:35 +0000 (Sat, 10 Oct 2009) Log Message: ----------- [Imp] Added *.j2b to format filter in the "open" dialog [Ref] Minor rewriting of the j2b loader Modified Paths: -------------- trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/soundlib/Load_gdm.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/load_j2b.cpp Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2009-10-09 21:12:52 UTC (rev 392) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2009-10-10 00:03:35 UTC (rev 393) @@ -1390,13 +1390,20 @@ OFN_HIDEREADONLY | OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_FORCESHOWHIDDEN | OFN_ALLOWMULTISELECT, // -> CODE#0023 // -> DESC="IT project files (.itp)" + "All Modules|*.mod;*.nst;*.wow;*.s3m;*.stm;*.669;*.mtm;*.xm;*.it;*.itp;*.mptm;*.ult;*.mdz;*.s3z;*.xmz;*.itz;mod.*;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.mdr;*.med;*.ams;*.dbm;*.dsm;*.mid;*.rmi;*.smf;*.umx;*.amf;*.psm;*.mt2;*.gdm;*.imf;*.j2b" #ifndef NO_MO3_SUPPORT - "All Modules|*.mod;*.nst;*.wow;*.s3m;*.stm;*.669;*.mtm;*.xm;*.it;*.itp;*.mptm;*.ult;*.mdz;*.s3z;*.xmz;*.itz;mod.*;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.mdr;*.med;*.ams;*.dbm;*.dsm;*.mid;*.rmi;*.smf;*.umx;*.amf;*.psm;*.mt2;*.gdm;*.imf;*.mo3|" - "Compressed Modules (*.mdz;*.s3z;*.xmz;*.itz;*.mo3)|*.mdz;*.s3z;*.xmz;*.itz;*.mdr;*.zip;*.rar;*.lha;*.mo3|" - #else - "All Modules|*.mod;*.nst;*.wow;*.s3m;*.stm;*.669;*.mtm;*.xm;*.it;*.itp;*.mptm;*.ult;*.mdz;*.s3z;*.xmz;*.itz;mod.*;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.mdr;*.med;*.ams;*.dbm;*.dsm;*.mid;*.rmi;*.smf;*.umx;*.amf;*.psm;*.mt2;*.gdm;*.imf|" - "Compressed Modules (*.mdz;*.s3z;*.xmz;*.itz)|*.mdz;*.s3z;*.xmz;*.itz;*.mdr;*.zip;*.rar;*.lha|" + ";*.mo3" #endif + "|" + "Compressed Modules (*.mdz;*.s3z;*.xmz;*.itz" + #ifndef NO_MO3_SUPPORT + ";*.mo3" + #endif + ")|*.mdz;*.s3z;*.xmz;*.itz;*.mdr;*.zip;*.rar;*.lha" + #ifndef NO_MO3_SUPPORT + ";*.mo3" + #endif + "|" // -! NEW_FEATURE#0023 "ProTracker Modules (*.mod,*.nst)|*.mod;mod.*;*.mdz;*.nst;*.m15|" "ScreamTracker Modules (*.s3m,*.stm)|*.s3m;*.stm;*.s3z|" @@ -1407,7 +1414,7 @@ "Impulse Tracker Projects (*.itp)|*.itp;*.itpz|" // -! NEW_FEATURE#0023 "OpenMPT Modules (*.mptm)|*.mptm;*.mptmz|" - "Other Modules (mtm,okt,mdl,669,far,...)|*.mtm;*.669;*.ult;*.wow;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.med;*.ams;*.dbm;*.dsm;*.umx;*.amf;*.psm;*.mt2;*.gdm;*.imf|" + "Other Modules (mtm,okt,mdl,669,far,...)|*.mtm;*.669;*.ult;*.wow;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.med;*.ams;*.dbm;*.dsm;*.umx;*.amf;*.psm;*.mt2;*.gdm;*.imf;*.j2b|" "Wave Files (*.wav)|*.wav|" "Midi Files (*.mid,*.rmi)|*.mid;*.rmi;*.smf|" "All Files (*.*)|*.*||", Modified: trunk/OpenMPT/soundlib/Load_gdm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_gdm.cpp 2009-10-09 21:12:52 UTC (rev 392) +++ trunk/OpenMPT/soundlib/Load_gdm.cpp 2009-10-10 00:03:35 UTC (rev 393) @@ -275,7 +275,7 @@ // read patterns Patterns.ResizeArray(max(MAX_PATTERNS, pHeader->NOP + 1)); - BOOL bS3MCommandSet = (GetBestSaveFormat() & (MOD_TYPE_S3M | MOD_TYPE_IT | MOD_TYPE_MPT)); + bool bS3MCommandSet = (GetBestSaveFormat() & (MOD_TYPE_S3M | MOD_TYPE_IT | MOD_TYPE_MPT)) != 0 ? true : false; // we'll start at position iPatternsOffset and decode all patterns for (PATTERNINDEX iPat = 0; iPat < pHeader->NOP + 1; iPat++) Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-10-09 21:12:52 UTC (rev 392) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-10-10 00:03:35 UTC (rev 393) @@ -708,7 +708,7 @@ bool ReadMID(LPCBYTE lpStream, DWORD dwMemLength); void SetupMODPanning(bool bForceSetup = false); // Setup LRRL panning, max channel volume - bool Convert_RIFF_AM_Pattern(PATTERNINDEX nPat, const LPCBYTE lpStream, DWORD dwMemLength, bool bIsAM); + bool Convert_RIFF_AM_Pattern(PATTERNINDEX nPat, const LPCBYTE lpStream, DWORD dwMemLength, bool bIsAM); // used by ReadAM(...) to convert AM(FF) patterns // Save Functions #ifndef MODPLUG_NO_FILESAVE Modified: trunk/OpenMPT/soundlib/load_j2b.cpp =================================================================== --- trunk/OpenMPT/soundlib/load_j2b.cpp 2009-10-09 21:12:52 UTC (rev 392) +++ trunk/OpenMPT/soundlib/load_j2b.cpp 2009-10-10 00:03:35 UTC (rev 393) @@ -1,9 +1,9 @@ /* - * Purpose: Load RIFF AM and RIFF AMFF modules. - * Note: J2B is a compressed variant of RIFF AM and RIFF AMFF files used in Jazz Jackrabbit 2 - * Authors: Johannes Schultz - * Chris Moeller (foo_dumb) - * Luigi Elettrico (J2B To IT Convertor Class) + * Purpose: Load RIFF AM and RIFF AMFF modules (Galaxy Sound System). + * Note: J2B is a compressed variant of RIFF AM and RIFF AMFF files used in Jazz Jackrabbit 2. + * It seems like no other game used the AM(FF) format. + * Authors: Johannes Schultz (OpenMPT port) + * Chris Moeller (foo_dumb - this is almost a complete port of his code, thanks) * */ @@ -17,12 +17,12 @@ // header for compressed j2b files struct J2BHEADER { - DWORD signature; // MUSE - DWORD deadbeaf; // 0xDEADBEAF or 0xDEADBABE - DWORD j2blength; - DWORD crc32; - DWORD packed_length; - DWORD unpacked_length; + DWORD signature; // MUSE + DWORD deadbeaf; // 0xDEADBEAF (AM) or 0xDEADBABE (AMFF) + DWORD j2blength; // complete filesize + DWORD crc32; // checksum of the compressed data block + DWORD packed_length; // length of the compressed data block + DWORD unpacked_length; // length of the decompressed module }; // am(ff) stuff @@ -97,7 +97,7 @@ bool CSoundFile::Convert_RIFF_AM_Pattern(PATTERNINDEX nPat, const LPCBYTE lpStream, DWORD dwMemLength, bool bIsAM) //---------------------------------------------------------------------------------------------------------------- { - // version 0 = AMFF, else = AM + // version false = AMFF, true = AM #define ASSERT_CAN_READ(x) \ if( dwMemPos > dwMemLength || x > dwMemLength - dwMemPos ) return false; @@ -252,7 +252,6 @@ ASSERT_CAN_READ(LittleEndian(chunkheader->chunksize)); DWORD dwChunkEnd = dwMemPos + LittleEndian(chunkheader->chunksize); - if(bIsAM && (LittleEndian(chunkheader->chunksize) & 1)) dwChunkEnd++; switch(LittleEndian(chunkheader->signature)) { @@ -437,6 +436,8 @@ } dwMemPos = dwChunkEnd; + // RIFF AM has a padding byte + if(bIsAM && (LittleEndian(chunkheader->chunksize) & 1)) dwMemPos++; } return true; @@ -468,36 +469,16 @@ dwMemPos += sizeof(J2BHEADER); // header is valid, now unpack the RIFF AM file using inflate - z_stream strm; - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - strm.avail_in = 0; - strm.next_in = Z_NULL; - if(inflateInit(&strm) != Z_OK) - return false; + DWORD destSize = LittleEndian(header->unpacked_length); + Bytef *bOutput = new Bytef[destSize]; + int nRetVal = uncompress(bOutput, &destSize, &lpStream[dwMemPos], LittleEndian(header->unpacked_length)); - Bytef* bOutput = new Bytef[LittleEndian(header->unpacked_length) + 1]; - - strm.avail_in = dwMemLength - dwMemPos; - strm.next_in = (Bytef *)(lpStream + dwMemPos); - strm.avail_out = LittleEndian(header->unpacked_length); - strm.next_out = bOutput; - - int nRetVal = inflate(&strm, Z_NO_FLUSH); - (void)inflateEnd(&strm); - - if(strm.avail_in != 0 || nRetVal == Z_STREAM_ERROR || nRetVal == Z_NEED_DICT || nRetVal == Z_DATA_ERROR || nRetVal == Z_MEM_ERROR || nRetVal != Z_STREAM_END) - { - return false; - } - bool bResult = false; - if(strm.total_out == LittleEndian(header->unpacked_length)) + if(destSize == LittleEndian(header->unpacked_length) && nRetVal == Z_OK) { // Success, now load the RIFF AM(FF) module. - bResult = ReadAM(bOutput, strm.total_out); + bResult = ReadAM(bOutput, destSize); } delete[] bOutput; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-10-11 16:08:01
|
Revision: 394 http://modplug.svn.sourceforge.net/modplug/?rev=394&view=rev Author: saga-games Date: 2009-10-11 16:07:45 +0000 (Sun, 11 Oct 2009) Log Message: ----------- [Fix] J2B Loader: Fixed uncompress() call, added security check in RIFF AM loader [Imp] All Loaders: Using a new template, SpaceToNullStringFixed, which filters out all null chars in song/sample/instrument/etc. names. This avoids "empty" instrument names that occured in a couple of .IT files before. [Mod] Added IMF and J2B to glpszModExtensions Modified Paths: -------------- trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/misc_util.h trunk/OpenMPT/soundlib/LOAD_AMF.CPP trunk/OpenMPT/soundlib/LOAD_DBM.CPP trunk/OpenMPT/soundlib/LOAD_DMF.CPP trunk/OpenMPT/soundlib/LOAD_DSM.CPP trunk/OpenMPT/soundlib/Load_669.cpp trunk/OpenMPT/soundlib/Load_ams.cpp trunk/OpenMPT/soundlib/Load_far.cpp trunk/OpenMPT/soundlib/Load_gdm.cpp trunk/OpenMPT/soundlib/Load_imf.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_mdl.cpp trunk/OpenMPT/soundlib/Load_med.cpp trunk/OpenMPT/soundlib/Load_mod.cpp trunk/OpenMPT/soundlib/Load_mt2.cpp trunk/OpenMPT/soundlib/Load_mtm.cpp trunk/OpenMPT/soundlib/Load_okt.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/Load_ptm.cpp trunk/OpenMPT/soundlib/Load_s3m.cpp trunk/OpenMPT/soundlib/Load_stm.cpp trunk/OpenMPT/soundlib/Load_ult.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/load_j2b.cpp Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -1836,6 +1836,8 @@ "Storlek for all the IT compatibility hints and testcases|" "as well as the IMF loader|" "http://schismtracker.org/|" + "kode54 for the PSM and J2B loaders|" + "http://kode54.foobar2000.org/|" "Pel K. Txnder for the scrolling credits control :)|" "http://tinyurl.com/4yze8|" "|The people at Modplug forums for crucial contribution|" Modified: trunk/OpenMPT/mptrack/misc_util.h =================================================================== --- trunk/OpenMPT/mptrack/misc_util.h 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/mptrack/misc_util.h 2009-10-11 16:07:45 UTC (rev 394) @@ -139,6 +139,7 @@ template <size_t size> void NullToSpaceString(char (&buffer)[size]) { + STATIC_ASSERT(size > 0); size_t pos = size; while (pos-- > 0) if (buffer[pos] == 0) @@ -149,6 +150,7 @@ template <size_t size> void SpaceToNullString(char (&buffer)[size]) { + STATIC_ASSERT(size > 0); // First, remove any Nulls NullToSpaceString(buffer); size_t pos = size; @@ -161,4 +163,22 @@ } buffer[size - 1] = 0; } + +// Convert a space-padded string to a 0-terminated string. +// Additional parameter to specifify the max length of the final string, +// not including null char (useful for e.g. mod loaders) +template <size_t size> +void SpaceToNullStringFixed(char (&buffer)[size], const size_t length) +//-------------------------------------------------------------------- +{ + STATIC_ASSERT(size > 0); + ASSERT(length < size); + // Remove Nulls in string + SpaceToNullString(buffer); + // Overwrite trailing chars + for(size_t pos = length; pos < size; pos++) + { + buffer[pos] = 0; + } +} #endif Modified: trunk/OpenMPT/soundlib/LOAD_AMF.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-10-11 16:07:45 UTC (rev 394) @@ -196,7 +196,8 @@ for (UINT iSmp=0; iSmp<numsamples; iSmp++) { MODSAMPLE *psmp = &Samples[iSmp+1]; - memcpy(m_szNames[iSmp+1], lpStream+dwMemPos, 22); + memcpy(m_szNames[iSmp + 1], lpStream+dwMemPos, 22); + SpaceToNullStringFixed(m_szNames[iSmp + 1], 22); psmp->nFineTune = MOD2XMFineTune(lpStream[dwMemPos+22]); psmp->nVolume = lpStream[dwMemPos+23]; psmp->nGlobalVol = 64; @@ -268,6 +269,7 @@ || (pfh->numchannels < 1) || (pfh->numchannels > 32)) return false; memcpy(m_szNames[0], pfh->title, 31); + SpaceToNullStringFixed(m_szNames[0], 31); dwMemPos = sizeof(AMFFILEHEADER); m_nType = MOD_TYPE_AMF; m_nChannels = pfh->numchannels; @@ -328,6 +330,8 @@ dwMemPos += sizeof(AMFSAMPLE); memcpy(m_szNames[iIns+1], psh->samplename, 31); memcpy(pSmp->filename, psh->filename, 13); + SpaceToNullStringFixed(m_szNames[iIns + 1], 31); + SpaceToNullStringFixed(pSmp->filename, 13); pSmp->nLength = LittleEndian(psh->length); pSmp->nC5Speed = LittleEndianW(psh->c2spd); pSmp->nGlobalVol = 64; Modified: trunk/OpenMPT/soundlib/LOAD_DBM.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_DBM.CPP 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/LOAD_DBM.CPP 2009-10-11 16:07:45 UTC (rev 394) @@ -119,7 +119,7 @@ if (m_nChannels < 1) m_nChannels = 1; if (m_nChannels > 64) m_nChannels = 64; memcpy(m_szNames[0], (pfh->songname[0]) ? pfh->songname : pfh->songname2, 32); - m_szNames[0][31] = 0; + SpaceToNullStringFixed(m_szNames[0], 31); Order.resize(nOrders, Order.GetInvalidPatIndex()); for (UINT iOrd=0; iOrd < nOrders; iOrd++) { @@ -155,10 +155,11 @@ psmp = ((nsmp) && (nsmp < MAX_SAMPLES)) ? &Samples[nsmp] : NULL; memset(pIns, 0, sizeof(MODINSTRUMENT)); memcpy(pIns->name, pih->name, 30); + SpaceToNullStringFixed(pIns->name, 30); if (psmp) { memcpy(m_szNames[nsmp], pih->name, 30); - m_szNames[nsmp][30] = 0; + SpaceToNullStringFixed(m_szNames[nsmp], 30); } Instruments[iIns+1] = pIns; pIns->nFadeOut = 1024; // ??? Modified: trunk/OpenMPT/soundlib/LOAD_DMF.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2009-10-11 16:07:45 UTC (rev 394) @@ -100,7 +100,7 @@ if ((pfh->id != 0x464d4444) || (!pfh->version) || (pfh->version & 0xF0)) return false; dwMemPos = 66; memcpy(m_szNames[0], pfh->songname, 30); - m_szNames[0][30] = 0; + SpaceToNullStringFixed(m_szNames[0], 30); m_nType = MOD_TYPE_DMF; m_nChannels = 0; #ifdef DMFLOG @@ -395,7 +395,7 @@ { UINT rlen = (namelen < 32) ? namelen : 31; memcpy(m_szNames[iSmp], lpStream+dwPos+1, rlen); - m_szNames[iSmp][rlen] = 0; + SpaceToNullStringFixed(m_szNames[iSmp], rlen); } dwPos += namelen + 1; DMFSAMPLE *psh = (DMFSAMPLE *)(lpStream+dwPos); @@ -439,7 +439,7 @@ pksize = *((LPDWORD)(lpStream+dwPos)); #ifdef DMFLOG Log("sample %d: pos=0x%X pksize=%d ", iSmp, dwPos, pksize); - Log("len=%d flags=0x%X [%08X]\n", Ins[iSmp].nLength, smplflags[ismpd], *((LPDWORD)(lpStream+dwPos+4))); + Log("len=%d flags=0x%X [%08X]\n", Samples[iSmp].nLength, smplflags[ismpd], *((LPDWORD)(lpStream+dwPos+4))); #endif dwPos += 4; if (pksize > dwMemLength - dwPos) Modified: trunk/OpenMPT/soundlib/LOAD_DSM.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_DSM.CPP 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/LOAD_DSM.CPP 2009-10-11 16:07:45 UTC (rev 394) @@ -121,6 +121,7 @@ } } memcpy(m_szNames[0], psong->songname, 28); + SpaceToNullStringFixed(m_szNames[0], 28); nPat = 0; nSmp = 1; while (dwMemPos < dwMemLength - 8) @@ -214,8 +215,10 @@ DWORD dwPos = dwMemPos + sizeof(DSMSAMPLE); dwMemPos += 8 + pSmp->inst_len; memcpy(m_szNames[nSmp], pSmp->samplename, 28); + SpaceToNullStringFixed(m_szNames[nSmp], 28); MODSAMPLE *psmp = &Samples[nSmp]; memcpy(psmp->filename, pSmp->filename, 13); + SpaceToNullStringFixed(psmp->filename, 13); psmp->nGlobalVol = 64; psmp->nC5Speed = pSmp->c2spd; psmp->uFlags = (WORD)((pSmp->flags & 1) ? CHN_LOOP : 0); Modified: trunk/OpenMPT/soundlib/Load_669.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_669.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_669.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -68,9 +68,12 @@ m_nDefaultTempo = 125; m_nDefaultSpeed = 6; m_nChannels = 8; + memcpy(m_szNames[0], pfh->songmessage, 16); + SpaceToNullStringFixed(m_szNames[0], 16); + m_nSamples = pfh->samples; - for (UINT nins=1; nins<=m_nSamples; nins++, psmp++) + for (SAMPLEINDEX nSmp = 1; nSmp <= m_nSamples; nSmp++, psmp++) { DWORD len = LittleEndian(*((DWORD *)(&psmp->length))); DWORD loopstart = LittleEndian(*((DWORD *)(&psmp->loopstart))); @@ -79,14 +82,15 @@ if ((loopend > len) && (!loopstart)) loopend = 0; if (loopend > len) loopend = len; if (loopstart + 4 >= loopend) loopstart = loopend = 0; - Samples[nins].nLength = len; - Samples[nins].nLoopStart = loopstart; - Samples[nins].nLoopEnd = loopend; - if (loopend) Samples[nins].uFlags |= CHN_LOOP; - memcpy(m_szNames[nins], psmp->filename, 13); - Samples[nins].nVolume = 256; - Samples[nins].nGlobalVol = 64; - Samples[nins].nPan = 128; + Samples[nSmp].nLength = len; + Samples[nSmp].nLoopStart = loopstart; + Samples[nSmp].nLoopEnd = loopend; + if (loopend) Samples[nSmp].uFlags |= CHN_LOOP; + memcpy(m_szNames[nSmp], psmp->filename, 13); + SpaceToNullStringFixed(m_szNames[nSmp], 13); + Samples[nSmp].nVolume = 256; + Samples[nSmp].nGlobalVol = 64; + Samples[nSmp].nPan = 128; } // Song Message m_lpszSongComments = new char[109]; Modified: trunk/OpenMPT/soundlib/Load_ams.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_ams.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_ams.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -88,6 +88,7 @@ if (dwMemPos + tmp + 1 >= dwMemLength) return true; tmp2 = (tmp < 32) ? tmp : 31; if (tmp2) memcpy(m_szNames[0], lpStream+dwMemPos, tmp2); + SpaceToNullStringFixed(m_szNames[0], tmp2); m_szNames[0][tmp2] = 0; dwMemPos += tmp; // Read sample names @@ -97,9 +98,10 @@ tmp = lpStream[dwMemPos++]; tmp2 = (tmp < 32) ? tmp : 31; if (tmp2) memcpy(m_szNames[sNam], lpStream+dwMemPos, tmp2); + SpaceToNullStringFixed(m_szNames[sNam], tmp2); dwMemPos += tmp; } - // Skip Channel names + // Read Channel names for (UINT cNam=0; cNam<m_nChannels; cNam++) { if (dwMemPos + 32 >= dwMemLength) return true; @@ -107,6 +109,7 @@ if ((chnnamlen) && (chnnamlen < MAX_CHANNELNAME)) { memcpy(ChnSettings[cNam].szName, lpStream + dwMemPos + 1, chnnamlen); + SpaceToNullStringFixed(ChnSettings[cNam].szName, chnnamlen); } dwMemPos += chnnamlen; } @@ -331,8 +334,8 @@ dwMemPos += sizeof(AMS2SONGHEADER); if (pfh->titlelen) { - memcpy(m_szNames, pfh->szTitle, pfh->titlelen); - m_szNames[0][pfh->titlelen] = 0; + memcpy(m_szNames[0], pfh->szTitle, pfh->titlelen); + SpaceToNullStringFixed(m_szNames[0], pfh->titlelen); } m_nType = MOD_TYPE_AMS; m_nChannels = 32; @@ -410,6 +413,7 @@ if ((psmp) && (smpnamelen) && (smpnamelen <= 22)) { memcpy(m_szNames[smpmap[ismp]], lpStream+dwMemPos+1, smpnamelen); + SpaceToNullStringFixed(m_szNames[smpmap[ismp]], smpnamelen); } dwMemPos += smpnamelen + 1; if (psmp) @@ -452,6 +456,7 @@ if ((chnnamlen) && (chnnamlen < MAX_CHANNELNAME)) { memcpy(ChnSettings[i].szName, lpStream+dwMemPos+1, chnnamlen); + SpaceToNullStringFixed(ChnSettings[i].szName, chnnamlen); } dwMemPos += chnnamlen + 1; if (dwMemPos + chnnamlen + 256 >= dwMemLength) return TRUE; @@ -487,7 +492,7 @@ { char s[MAX_PATTERNNAME]; memcpy(s, lpStream+dwMemPos+3, patnamlen); - s[patnamlen] = 0; + SpaceToNullStringFixed(s, patnamlen); SetPatternName(ipat, s); } if(Patterns.Insert(ipat, numrows)) return TRUE; Modified: trunk/OpenMPT/soundlib/Load_far.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_far.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_far.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -88,6 +88,8 @@ m_nDefaultGlobalVolume = 256; memcpy(m_szNames[0], pmh1->songname, 31); + SpaceToNullStringFixed(m_szNames[0], 31); + // Channel Setting for (UINT nchpan=0; nchpan<16; nchpan++) { @@ -248,6 +250,7 @@ dwMemPos += sizeof(FARSAMPLE); m_nSamples = ismp + 1; memcpy(m_szNames[ismp+1], pfs->samplename, 31); + SpaceToNullStringFixed(m_szNames[ismp + 1], 31); const DWORD length = LittleEndian( pfs->length ); pSmp->nLength = length; pSmp->nLoopStart = LittleEndian(pfs->reppos) ; Modified: trunk/OpenMPT/soundlib/Load_gdm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_gdm.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_gdm.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -80,11 +80,6 @@ (pHeader->DOSEOF[0] != 13 || pHeader->DOSEOF[1] != 10 || pHeader->DOSEOF[2] != 26) || //CR+LF+EOF (LittleEndian(pHeader->ID2) != 0x53464D47)) return false; //GMFS - // song name - memset(m_szNames, 0, sizeof(m_szNames)); - memcpy(m_szNames[0], pHeader->SongTitle, 32); - SetNullTerminator(m_szNames[0]); - // there are no other format versions... if(pHeader->FormMajorVer != 1 || pHeader->FormMinorVer != 0) { @@ -94,6 +89,11 @@ // interesting question: Is TrackID, TrackMajorVer, TrackMinorVer relevant? The only TrackID should be 0 - 2GDM.exe, so the answer would be no. + // song name + memset(m_szNames, 0, sizeof(m_szNames)); + memcpy(m_szNames[0], pHeader->SongTitle, 32); + SpaceToNullStringFixed(m_szNames[0], 31); + // read channel pan map... 0...15 = channel panning, 16 = surround channel, 255 = channel does not exist m_nChannels = 32; for(CHANNELINDEX i = 0; i < 32; i++) @@ -179,15 +179,16 @@ // read samples m_nSamples = pHeader->NOS + 1; - for(UINT iSmp = 1; iSmp <= m_nSamples; iSmp++) + for(SAMPLEINDEX iSmp = 1; iSmp <= m_nSamples; iSmp++) { const PGDMSAMPLEHEADER pSample = (PGDMSAMPLEHEADER)(lpStream + iSamHeadOffset + (iSmp - 1) * sizeof(GDMSAMPLEHEADER)); // sample header memcpy(m_szNames[iSmp], pSample->SamName, 32); - SetNullTerminator(m_szNames[iSmp]); + SpaceToNullStringFixed(m_szNames[iSmp], 31); memcpy(Samples[iSmp].filename, pSample->FileName, 12); + SpaceToNullStringFixed(Samples[iSmp].filename, 12); Samples[iSmp].nC5Speed = LittleEndianW(pSample->C4Hertz); Samples[iSmp].nGlobalVol = 256; // not supported in this format Modified: trunk/OpenMPT/soundlib/Load_imf.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_imf.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_imf.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -288,8 +288,7 @@ // song name memset(m_szNames, 0, sizeof(m_szNames)); memcpy(m_szNames[0], hdr.title, 31); - m_szNames[0][31] = 0; - SetNullTerminator(m_szNames[0]); + SpaceToNullStringFixed(m_szNames[0], 31); if (hdr.flags & 1) m_dwSongFlags |= SONG_LINEARSLIDES; @@ -306,8 +305,8 @@ ChnSettings[nChn].nPan = hdr.channels[nChn].panning * 64 / 255; ChnSettings[nChn].nPan *= 4; - memcpy(&ChnSettings[nChn].szName[0], hdr.channels[nChn].name, 12); - SetNullTerminator(ChnSettings[nChn].szName); + memcpy(ChnSettings[nChn].szName, hdr.channels[nChn].name, 12); + SpaceToNullStringFixed(ChnSettings[nChn].szName, 12); // TODO: reverb/chorus? switch (hdr.channels[nChn].status) { @@ -475,8 +474,8 @@ pIns->nPPC = 5 * 12; SetDefaultInstrumentValues(pIns); - strncpy(pIns->name, imfins.name, 31); - pIns->name[31] = 0; + memcpy(pIns->name, imfins.name, 31); + SpaceToNullStringFixed(pIns->name, 31); if (imfins.smpnum) { for (BYTE cNote = 0; cNote < 120; cNote++) { @@ -512,9 +511,10 @@ return false; } - strncpy(pSample->filename, imfsmp.filename, 12); - pSample->filename[12] = 0; + memcpy(pSample->filename, imfsmp.filename, 12); + SpaceToNullStringFixed(pSample->filename, 12); strcpy(m_szNames[m_nSamples], pSample->filename); + blen = pSample->nLength = LittleEndian(imfsmp.length); pSample->nLoopStart = LittleEndian(imfsmp.loop_start); pSample->nLoopEnd = LittleEndian(imfsmp.loop_end); Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -250,6 +250,8 @@ const ITOLDINSTRUMENT *pis = (const ITOLDINSTRUMENT *)p; memcpy(pIns->name, pis->name, 26); memcpy(pIns->filename, pis->filename, 12); + SpaceToNullStringFixed(pIns->name, 26); + SpaceToNullStringFixed(pIns->filename, 12); pIns->nFadeOut = pis->fadeout << 6; pIns->nGlobalVol = 64; for (UINT j=0; j<NOTE_MAX; j++) @@ -290,6 +292,8 @@ const ITINSTRUMENT *pis = (const ITINSTRUMENT *)p; memcpy(pIns->name, pis->name, 26); memcpy(pIns->filename, pis->filename, 12); + SpaceToNullStringFixed(pIns->name, 26); + SpaceToNullStringFixed(pIns->filename, 12); if (pis->mpr<=128) pIns->nMidiProgram = pis->mpr; pIns->nMidiChannel = pis->mch; @@ -941,8 +945,10 @@ if (pifh->flags & 0x20) m_dwSongFlags |= SONG_ITCOMPATMODE; if ((pifh->flags & 0x80) || (pifh->special & 0x08)) m_dwSongFlags |= SONG_EMBEDMIDICFG; if (pifh->flags & 0x1000) m_dwSongFlags |= SONG_EXFILTERRANGE; + memcpy(m_szNames[0], pifh->songname, 26); - m_szNames[0][26] = 0; + SpaceToNullStringFixed(m_szNames[0], 26); + // Global Volume if (pifh->globalvol) { @@ -1208,6 +1214,7 @@ { MODSAMPLE *pSmp = &Samples[nsmp+1]; memcpy(pSmp->filename, pis->filename, 12); + SpaceToNullStringFixed(pSmp->filename, 12); pSmp->uFlags = 0; pSmp->nLength = 0; pSmp->nLoopStart = pis->loopbegin; @@ -1258,17 +1265,10 @@ // -! NEW_FEATURE#0027 } } - memcpy(m_szNames[nsmp+1], pis->name, 26); + memcpy(m_szNames[nsmp + 1], pis->name, 26); + SpaceToNullStringFixed(m_szNames[nsmp + 1], 26); } - for (UINT ncu=0; ncu<MAX_BASECHANNELS; ncu++) - { - if (ncu>=m_nChannels) - { - ChnSettings[ncu].nVolume = 64; - ChnSettings[ncu].dwFlags &= ~CHN_MUTE; - } - } m_nMinPeriod = 8; m_nMaxPeriod = 0xF000; @@ -1309,11 +1309,7 @@ } UINT len = *((WORD *)(lpStream+patpos[npat])); UINT rows = *((WORD *)(lpStream+patpos[npat]+2)); -// -> CODE#0008 -// -> DESC="#define to set pattern size" -// if ((rows < 4) || (rows > 256)) continue; if ((rows < GetModSpecifications().patternRowsMin) || (rows > GetModSpecifications().patternRowsMax)) continue; -// -> BEHAVIOUR_CHANGE#0008 if (patpos[npat]+8+len > dwMemLength) continue; if(Patterns.Insert(npat, rows)) continue; Modified: trunk/OpenMPT/soundlib/Load_mdl.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -229,6 +229,8 @@ #endif pmib = (MDLINFOBLOCK *)(lpStream+dwMemPos); memcpy(m_szNames[0], pmib->songname, 31); + SpaceToNullStringFixed(m_szNames[0], 31); + norders = pmib->norders; if (norders > MAX_ORDERS) norders = MAX_ORDERS; m_nRestartPos = pmib->repeatpos; @@ -328,6 +330,8 @@ MODINSTRUMENT *pIns = Instruments[nins]; memset(pIns, 0, sizeof(MODINSTRUMENT)); memcpy(pIns->name, lpStream+dwPos+2, 32); + SpaceToNullStringFixed(pIns->name, 31); + pIns->nGlobalVol = 64; pIns->nPPC = 5*12; SetDefaultInstrumentValues(pIns); @@ -413,6 +417,8 @@ MODSAMPLE *pSmp = &Samples[nins]; memcpy(m_szNames[nins], lpStream+dwPos+1, 31); memcpy(pSmp->filename, lpStream+dwPos+33, 8); + SpaceToNullStringFixed(m_szNames[nins], 31); + SpaceToNullStringFixed(pSmp->filename, 8); const BYTE *p = lpStream+dwPos+41; if (pmsh->version > 0) { Modified: trunk/OpenMPT/soundlib/Load_med.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_med.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_med.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -716,6 +716,7 @@ { if (songnamelen > 31) songnamelen = 31; memcpy(m_szNames[0], lpStream+songname, songnamelen); + SpaceToNullStringFixed(m_szNames[0], songnamelen); } // Sample Names DWORD smpinfoex = BigEndian(pmex->iinfo); @@ -733,6 +734,7 @@ for (UINT i=0; i<ientries; i++) if (i < m_nSamples) { memcpy(m_szNames[i+1], psznames + i*ientrysz, maxnamelen); + SpaceToNullStringFixed(m_szNames[i + 1], maxnamelen); } } } @@ -762,8 +764,8 @@ if (trknamelen > MAX_CHANNELNAME) trknamelen = MAX_CHANNELNAME; if ((trknameofs) && (trknameofs < dwMemLength - trknamelen)) { - memcpy(ChnSettings[i].szName, (LPCSTR)(lpStream+trknameofs), MAX_CHANNELNAME); - SetNullTerminator(ChnSettings[i].szName); + memcpy(ChnSettings[i].szName, (LPCSTR)(lpStream+trknameofs), trknamelen); + SpaceToNullStringFixed(ChnSettings[i].szName, trknamelen); } } } Modified: trunk/OpenMPT/soundlib/Load_mod.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mod.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_mod.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -256,7 +256,7 @@ UINT loopstart, looplen; memcpy(m_szNames[i], pms->name, 22); - m_szNames[i][22] = 0; + SpaceToNullStringFixed(m_szNames[i], 22); psmp->uFlags = 0; psmp->nLength = BigEndianW(pms->length)*2; dwTotalSampleLen += psmp->nLength; @@ -347,7 +347,8 @@ m_nDefaultTempo = 125; m_nMinPeriod = 14 << 2; m_nMaxPeriod = 3424 << 2; - memcpy(m_szNames, lpStream, 20); + memcpy(m_szNames[0], lpStream, 20); + SpaceToNullStringFixed(m_szNames[0], 20); // Setup channel pan positions and volume SetupMODPanning(); Modified: trunk/OpenMPT/soundlib/Load_mt2.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -210,7 +210,8 @@ Order[iOrd] = (PATTERNINDEX)pfh->Orders[iOrd]; } memcpy(m_szNames[0], pfh->szSongName, 32); - m_szNames[0][31] = 0; + SpaceToNullStringFixed(m_szNames[0], 31); + dwMemPos = sizeof(MT2FILEHEADER); nDrumDataLen = *(WORD *)(lpStream + dwMemPos); dwDrumDataPos = dwMemPos + 2; @@ -407,7 +408,7 @@ { memset(pIns, 0, sizeof(MODINSTRUMENT)); memcpy(pIns->name, pmi->szName, 32); - SetNullTerminator(pIns->name); + SpaceToNullStringFixed(pIns->name, 32); pIns->nGlobalVol = 64; pIns->nPan = 128; for (UINT i=0; i<NOTE_MAX; i++) @@ -539,6 +540,7 @@ if (iSmp < MAX_SAMPLES) { memcpy(m_szNames[iSmp], pms->szName, 31); + SpaceToNullStringFixed(m_szNames[iSmp], 31); } if (pms->dwDataLen > 0) { Modified: trunk/OpenMPT/soundlib/Load_mtm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mtm.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_mtm.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -59,19 +59,20 @@ || (pmh->numsamples >= MAX_SAMPLES) || (!pmh->numsamples) || (!pmh->numtracks) || (!pmh->numchannels) || (!pmh->lastpattern) || (pmh->lastpattern > MAX_PATTERNS)) return false; - strncpy(m_szNames[0], pmh->songname, 20); - m_szNames[0][20] = 0; - if (dwMemPos + 37*pmh->numsamples + 128 + 192*pmh->numtracks + memcpy(m_szNames[0], pmh->songname, 20); + SpaceToNullStringFixed(m_szNames[0], 20); + + if (dwMemPos + 37 * pmh->numsamples + 128 + 192 * pmh->numtracks + 64 * (pmh->lastpattern+1) + pmh->commentsize >= dwMemLength) return false; m_nType = MOD_TYPE_MTM; m_nSamples = pmh->numsamples; m_nChannels = pmh->numchannels; // Reading instruments - for (UINT i=1; i<=m_nSamples; i++) + for (SAMPLEINDEX i = 1; i <= m_nSamples; i++) { MTMSAMPLE *pms = (MTMSAMPLE *)(lpStream + dwMemPos); - strncpy(m_szNames[i], pms->samplename, 22); - m_szNames[i][22] = 0; + memcpy(m_szNames[i], pms->samplename, 22); + SpaceToNullStringFixed(m_szNames[i], 22); Samples[i].nVolume = pms->volume << 2; Samples[i].nGlobalVol = 64; DWORD len = pms->length; Modified: trunk/OpenMPT/soundlib/Load_okt.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_okt.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_okt.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -69,6 +69,7 @@ MODSAMPLE *pSmp = &Samples[smp]; memcpy(m_szNames[smp], psmp->name, 20); + SpaceToNullStringFixed(m_szNames[smp], 20); pSmp->uFlags = 0; pSmp->nLength = BigEndian(psmp->length) & ~1; pSmp->nLoopStart = BigEndianW(psmp->loopstart); Modified: trunk/OpenMPT/soundlib/Load_psm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -169,7 +169,7 @@ { case 0x4C544954: // "TITL" - Song Title memcpy(m_szNames[0], lpStream + dwMemPos, (chunkSize < 31) ? chunkSize : 31); - m_szNames[0][31] = 0; + SpaceToNullStringFixed(m_szNames[0], 31); break; case 0x54464453: // "SDFT" - Format info (song data starts here) @@ -203,7 +203,7 @@ PSMSUBSONG subsong; subsong.restartPos = (ORDERINDEX)Order.size(); // restart order "offset": current orderlist length memcpy(subsong.songName, &pSong->songType, 9); // subsong name - subsong.songName[9] = 0; + SpaceToNullStringFixed(subsong.songName, 9); DWORD dwChunkPos = dwMemPos + sizeof(PSMSONGHEADER); @@ -432,9 +432,9 @@ SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1); m_nSamples = max(m_nSamples, smp); memcpy(m_szNames[smp], pSample->sampleName, 31); - m_szNames[smp][31] = 0; + SpaceToNullStringFixed(m_szNames[smp], 31); memcpy(Samples[smp].filename, pSample->fileName, 8); - Samples[smp].filename[8] = 0; + SpaceToNullStringFixed(Samples[smp].filename, 8); Samples[smp].nGlobalVol = 0x40; Samples[smp].nC5Speed = LittleEndianW(pSample->C5Freq); @@ -456,9 +456,9 @@ SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1); m_nSamples = max(m_nSamples, smp); memcpy(m_szNames[smp], pSample->sampleName, 31); - m_szNames[smp][31] = 0; + SpaceToNullStringFixed(m_szNames[smp], 31); memcpy(Samples[smp].filename, pSample->fileName, 8); - Samples[smp].filename[8] = 0; + SpaceToNullStringFixed(Samples[smp].filename, 8); Samples[smp].nGlobalVol = 0x40; Samples[smp].nC5Speed = LittleEndianW(pSample->C5Freq); @@ -893,7 +893,7 @@ memset(m_szNames, 0, sizeof(m_szNames)); memcpy(m_szNames[0], shdr->songName, 31); - m_szNames[0][31] = 0; + SpaceToNullStringFixed(m_szNames[0], 31); // Read orders dwMemPos = LittleEndian(shdr->orderOffset); @@ -933,9 +933,9 @@ m_nSamples = max(m_nSamples, iSmp); memcpy(m_szNames[iSmp], smphdr->name, 24); - m_szNames[iSmp][24] = 0; + SpaceToNullStringFixed(m_szNames[iSmp], 24); memcpy(Samples[iSmp].filename, smphdr->filename, 13); - Samples[iSmp].filename[13] = 0; + SpaceToNullStringFixed(Samples[iSmp].filename, 13); Samples[iSmp].nLength = LittleEndian(smphdr->length); Samples[iSmp].nLoopStart = LittleEndian(smphdr->loopStart); Modified: trunk/OpenMPT/soundlib/Load_ptm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_ptm.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_ptm.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -89,7 +89,8 @@ || (!pfh.npatterns) || (pfh.npatterns > 128) || (SIZEOF_PTMFILEHEADER+pfh.nsamples*SIZEOF_PTMSAMPLE >= (int)dwMemLength)) return false; memcpy(m_szNames[0], pfh.songname, 28); - m_szNames[0][28] = 0; + SpaceToNullStringFixed(m_szNames[0], 28); + m_nType = MOD_TYPE_PTM; m_nChannels = pfh.nchannels; m_nSamples = (pfh.nsamples < MAX_SAMPLES) ? pfh.nsamples : MAX_SAMPLES-1; @@ -109,7 +110,9 @@ lstrcpyn(m_szNames[ismp+1], psmp->samplename, 28); memcpy(pSmp->filename, psmp->filename, 12); - pSmp->filename[12] = 0; + SpaceToNullStringFixed(m_szNames[ismp + 1], 28); + SpaceToNullStringFixed(pSmp->filename, 12); + pSmp->nGlobalVol = 64; pSmp->nPan = 128; pSmp->nVolume = psmp->volume << 2; Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -266,6 +266,7 @@ m_nType = MOD_TYPE_S3M; memset(m_szNames,0,sizeof(m_szNames)); memcpy(m_szNames[0], psfh.name, 28); + SpaceToNullStringFixed(m_szNames[0], 28); // Speed m_nDefaultSpeed = psfh.speed; if (!m_nDefaultSpeed) m_nDefaultSpeed = 6; @@ -335,12 +336,17 @@ { UINT nInd = ((DWORD)ptr[iSmp-1])*16; if ((!nInd) || (nInd + 0x50 > dwMemLength)) continue; + memcpy(s, lpStream+nInd, 0x50); memcpy(Samples[iSmp].filename, s+1, 12); + SpaceToNullStringFixed(Samples[iSmp].filename, 12); + insflags[iSmp-1] = s[0x1F]; inspack[iSmp-1] = s[0x1E]; s[0x4C] = 0; lstrcpy(m_szNames[iSmp], (LPCSTR)&s[0x30]); + SpaceToNullStringFixed(m_szNames[iSmp], 28); + if ((s[0]==1) && (s[0x4E]=='R') && (s[0x4F]=='S')) { Samples[iSmp].nLength = CLAMP(LittleEndian(*((LPDWORD)(s + 0x10))), 4, MAX_SAMPLE_LENGTH); Modified: trunk/OpenMPT/soundlib/Load_stm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_stm.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_stm.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -70,6 +70,7 @@ || ((_strnicmp(phdr->trackername, "!SCREAM!", 8)) && (_strnicmp(phdr->trackername, "BMOD2STM", 8)))) return false; memcpy(m_szNames[0], phdr->songname, 20); + SpaceToNullStringFixed(m_szNames[0], 20); // Read STM header m_nType = MOD_TYPE_STM; m_nSamples = 31; @@ -97,6 +98,8 @@ STMSAMPLE *pStm = &phdr->sample[nIns]; // STM sample data memcpy(pIns->filename, pStm->filename, 13); memcpy(m_szNames[nIns+1], pStm->filename, 12); + SpaceToNullStringFixed(pIns->filename, 12); + SpaceToNullStringFixed(m_szNames[nIns + 1], 12); pIns->nC5Speed = LittleEndianW(pStm->c2spd); pIns->nGlobalVol = 64; pIns->nVolume = pStm->volume << 2; Modified: trunk/OpenMPT/soundlib/Load_ult.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_ult.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_ult.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -61,6 +61,7 @@ m_nDefaultSpeed = 6; m_nDefaultTempo = 125; memcpy(m_szNames[0], pmh->songtitle, 31); + SpaceToNullStringFixed(m_szNames[0], 31); // read songtext dwMemPos = sizeof(ULTHEADER); if ((pmh->reserved) && (dwMemPos + pmh->reserved * 32 < dwMemLength)) @@ -91,6 +92,8 @@ MODSAMPLE *pSmp = &Samples[ins]; memcpy(m_szNames[ins], pus->samplename, 31); memcpy(pSmp->filename, pus->dosname, 12); + SpaceToNullStringFixed(m_szNames[ins], 31); + SpaceToNullStringFixed(pSmp->filename, 12); pSmp->nLoopStart = pus->loopstart; pSmp->nLoopEnd = pus->loopend; pSmp->nLength = pus->sizeend - pus->sizestart; Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -257,6 +257,7 @@ // look for null-terminated song name - that's most likely a tune made with modplug for(int i = 0; i < 20; i++) if(lpStream[17 + i] == 0) bProbablyMadeWithModPlug = true; + SpaceToNullStringFixed(m_szNames[0], 20); // load and convert header memcpy(&xmheader, lpStream + 58, sizeof(XMFILEHEADER)); @@ -323,6 +324,7 @@ Instruments[iIns]->nPluginVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE; memcpy(Instruments[iIns]->name, pih->name, 22); + SpaceToNullStringFixed(Instruments[iIns]->name, 22); if ((nsamples = pih->samples) > 0) { @@ -524,7 +526,7 @@ if (!xmss.looplen) xmss.type &= ~3; UINT imapsmp = samplemap[ins]; memcpy(m_szNames[imapsmp], xmss.name, 22); - m_szNames[imapsmp][22] = 0; + SpaceToNullStringFixed(m_szNames[imapsmp], 22); MODSAMPLE *pSmp = &Samples[imapsmp]; pSmp->nLength = (xmss.samplen > MAX_SAMPLE_LENGTH) ? MAX_SAMPLE_LENGTH : xmss.samplen; pSmp->nLoopStart = xmss.loopstart; @@ -553,7 +555,7 @@ pSmp->nVibDepth = xmsh.vibdepth; pSmp->nVibRate = xmsh.vibrate; memcpy(pSmp->filename, xmss.name, 22); - pSmp->filename[21] = 0; + SpaceToNullStringFixed(pSmp->filename, 21); } #if 0 if ((xmsh.reserved2 > nsamples) && (xmsh.reserved2 <= 16)) Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -30,7 +30,7 @@ #define UNRAR_SUPPORT #define UNLHA_SUPPORT #define ZIPPED_MOD_SUPPORT -LPCSTR glpszModExtensions = "mod|s3m|xm|it|stm|nst|ult|669|wow|mtm|med|far|mdl|ams|dsm|amf|okt|dmf|ptm|psm|mt2|umx|gdm" +LPCSTR glpszModExtensions = "mod|s3m|xm|it|stm|nst|ult|669|wow|mtm|med|far|mdl|ams|dsm|amf|okt|dmf|ptm|psm|mt2|umx|gdm|imf|j2b" #ifndef NO_UNMO3_SUPPORT "|mo3" #endif Modified: trunk/OpenMPT/soundlib/load_j2b.cpp =================================================================== --- trunk/OpenMPT/soundlib/load_j2b.cpp 2009-10-10 00:03:35 UTC (rev 393) +++ trunk/OpenMPT/soundlib/load_j2b.cpp 2009-10-11 16:07:45 UTC (rev 394) @@ -238,6 +238,7 @@ bool bIsAM; // false: AMFF, true: AM + ASSERT_CAN_READ(4); if(LittleEndian(*(DWORD *)(lpStream + dwMemPos)) == 0x46464D41) bIsAM = false; // "AMFF" else if(LittleEndian(*(DWORD *)(lpStream + dwMemPos)) == 0x20204D41) bIsAM = true; // "AM " else return false; @@ -266,7 +267,7 @@ ASSERT_CAN_READ_CHUNK(mainchunk->channels); memcpy(m_szNames[0], mainchunk->songname, 32); - SetNullTerminator(m_szNames[0]); + SpaceToNullStringFixed(m_szNames[0], 31); m_dwSongFlags = SONG_ITOLDEFFECTS | SONG_ITCOMPATMODE; if(!(mainchunk->flags & 0x01)) m_dwSongFlags |= SONG_LINEARSLIDES; if(mainchunk->channels < 1) return false; @@ -277,30 +278,25 @@ m_nSamplePreAmp = m_nVSTiVolume = 48; m_nType = MOD_TYPE_IT; + // It seems like there's no way to differentiate between + // Muted and Surround channels (they're all 0xA0) - might + // be a limitation in mod2j2b. for(CHANNELINDEX nChn = 0; nChn < m_nChannels; nChn++) { + ChnSettings[nChn].nVolume = 64; + ChnSettings[nChn].nPan = 128; if(bIsAM) { if(lpStream[dwMemPos + nChn] > 128) - { - ChnSettings[nChn].nPan = 128; - ChnSettings[nChn].nVolume = 0; - } else - { + ChnSettings[nChn].dwFlags = CHN_MUTE; + else ChnSettings[nChn].nPan = lpStream[dwMemPos + nChn] << 1; - ChnSettings[nChn].nVolume = 64; - } } else { if(lpStream[dwMemPos + nChn] >= 128) - { - ChnSettings[nChn].nPan = 128; - ChnSettings[nChn].nVolume = 0; - } else - { + ChnSettings[nChn].dwFlags = CHN_MUTE; + else ChnSettings[nChn].nPan = lpStream[dwMemPos + nChn] << 2; - ChnSettings[nChn].nVolume = 64; - } } } dwMemPos += mainchunk->channels; @@ -330,7 +326,7 @@ m_nSamples = max(m_nSamples, nSmp); memcpy(m_szNames[nSmp], inschunk->name, 28); - m_szNames[nSmp][28] = 0; + SpaceToNullStringFixed(m_szNames[nSmp], 28); ASSERT_CAN_READ_CHUNK(sizeof(AMFFCHUNK_SAMPLE)); AMFFCHUNK_SAMPLE *smpchunk = (AMFFCHUNK_SAMPLE *)(lpStream + dwMemPos); @@ -339,7 +335,7 @@ if(smpchunk->signature != 0x504D4153) break; // SAMP memcpy(m_szNames[nSmp], smpchunk->name, 28); - m_szNames[nSmp][28] = 0; + SpaceToNullStringFixed(m_szNames[nSmp], 28); Samples[nSmp].nPan = smpchunk->pan << 2; Samples[nSmp].nVolume = smpchunk->volume << 2; @@ -389,7 +385,7 @@ m_nSamples = max(m_nSamples, nSmp); memcpy(m_szNames[nSmp], instheadchunk->name, 32); - m_szNames[nSmp][32] = 0; + SpaceToNullStringFixed(m_szNames[nSmp], 31); ASSERT_CAN_READ_CHUNK(sizeof(RIFFCHUNK)); instchunk = (RIFFCHUNK *)(lpStream + dwMemPos); @@ -407,7 +403,7 @@ if(smpchunk->signature != 0x504D4153) break; // SAMP memcpy(m_szNames[nSmp], smpchunk->name, 32); - m_szNames[nSmp][32] = 0; + SpaceToNullStringFixed(m_szNames[nSmp], 31); if(LittleEndianW(smpchunk->pan) > 0x7FFF || LittleEndianW(smpchunk->volume) > 0x7FFF) break; @@ -429,7 +425,7 @@ if(LittleEndianW(smpchunk->flags) & 0x20) Samples[nSmp].uFlags |= CHN_PANNING; - dwMemPos += LittleEndian(smpchunk->headsize); + dwMemPos += LittleEndian(smpchunk->headsize) + 12; // doesn't include the 3 first DWORDs dwMemPos += ReadSample(&Samples[nSmp], (LittleEndianW(smpchunk->flags) & 0x04) ? RS_PCM16S : RS_PCM8S, (LPCSTR)(lpStream + dwMemPos), dwMemLength - dwMemPos); } break; @@ -471,7 +467,7 @@ // header is valid, now unpack the RIFF AM file using inflate DWORD destSize = LittleEndian(header->unpacked_length); Bytef *bOutput = new Bytef[destSize]; - int nRetVal = uncompress(bOutput, &destSize, &lpStream[dwMemPos], LittleEndian(header->unpacked_length)); + int nRetVal = uncompress(bOutput, &destSize, &lpStream[dwMemPos], LittleEndian(header->packed_length)); bool bResult = false; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
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. |
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. |
From: <sag...@us...> - 2009-10-15 20:21:38
|
Revision: 399 http://modplug.svn.sourceforge.net/modplug/?rev=399&view=rev Author: saga-games Date: 2009-10-15 20:21:28 +0000 (Thu, 15 Oct 2009) Log Message: ----------- [Fix] Increased "filename" string in instrument header field to 32, since CHAR[12] is not really enough for 12 letters... [Imp] Treeview: Update sequence names, indicate current sequence by bold text [Imp] MOD Playing: Some more (minor) tweaks for Invert Loop. Thanks again, bubsy! [Imp] Mod Conversion: Changing between MOD and XM format limits CMD_SPEED/CMD_TEMPO properly now. [Ref] Renamed undo functions from "Undo" to "PatternUndo", to avoid confusion with other possibly upcoming undo functions (sample editor, etc) [Ref] Some more internal refactoring Modified Paths: -------------- trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/mptrack/Ctrl_pat.cpp trunk/OpenMPT/mptrack/Ctrl_smp.h trunk/OpenMPT/mptrack/EffectVis.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/mptrack/View_smp.h trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/soundlib/Load_med.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/pattern.cpp Modified: trunk/OpenMPT/mptrack/CleanupSong.cpp =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp 2009-10-15 20:21:28 UTC (rev 399) @@ -441,7 +441,7 @@ EndWaitCursor(); if ((nPatRemoved) || (bReordered)) { - m_pModDoc->ClearUndo(); + m_pModDoc->ClearPatternUndo(); if (nPatRemoved) { wsprintf(s, "%d pattern%s removed.\n", nPatRemoved, (nPatRemoved == 1) ? "" : "s"); Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-10-15 20:21:28 UTC (rev 399) @@ -377,7 +377,7 @@ } if (dwHintMask & (HINT_MODTYPE|HINT_UNDO)) { - m_ToolBar.EnableButton(ID_EDIT_UNDO, m_pModDoc->CanUndo()); + m_ToolBar.EnableButton(ID_EDIT_UNDO, m_pModDoc->CanPatternUndo()); } } @@ -1166,6 +1166,7 @@ { m_pSndFile->Order.m_sName = str; m_pModDoc->SetModified(); + m_pModDoc->UpdateAllViews(NULL, HINT_SEQNAMES, this); } } } Modified: trunk/OpenMPT/mptrack/Ctrl_smp.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.h 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/mptrack/Ctrl_smp.h 2009-10-15 20:21:28 UTC (rev 399) @@ -17,7 +17,7 @@ CSpinButtonCtrl m_SpinFineTune, m_SpinSample; CComboBox m_ComboAutoVib, m_ComboLoopType, m_ComboSustainType, m_ComboZoom, m_CbnBaseNote; CButton m_CheckPanning; - UINT m_nSample; + SAMPLEINDEX m_nSample; double m_dTimeStretchRatio; //rewbs.timeStretchMods uint32 m_nStretchProcessStepLength; uint32 m_nSequenceMs; Modified: trunk/OpenMPT/mptrack/EffectVis.cpp =================================================================== --- trunk/OpenMPT/mptrack/EffectVis.cpp 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/mptrack/EffectVis.cpp 2009-10-15 20:21:28 UTC (rev 399) @@ -578,7 +578,7 @@ rect.SetRect(x-NODEHALF, y-NODEHALF, x+NODEHALF+1, y+NODEHALF+1); if (rect.PtInRect(point)) { - m_pModDoc->PrepareUndo(m_nPattern, m_nChan, row, m_nChan+1, row+1); + m_pModDoc->PreparePatternUndo(m_nPattern, m_nChan, row, m_nChan+1, row+1); m_nDragItem = row; } } @@ -669,7 +669,7 @@ SetFocus(); SetCapture(); - m_pModDoc->PrepareUndo(m_nPattern, m_nChan, m_startRow, m_nChan+1, m_endRow); + m_pModDoc->PreparePatternUndo(m_nPattern, m_nChan, m_startRow, m_nChan+1, m_endRow); m_dwStatus |= FXVSTATUS_LDRAGGING; } Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-15 20:21:28 UTC (rev 399) @@ -113,7 +113,7 @@ CModDoc::~CModDoc() //----------------- { - ClearUndo(); + ClearPatternUndo(); ClearLog(); } Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-10-15 20:21:28 UTC (rev 399) @@ -36,7 +36,8 @@ #define HINT_UNDO 0x10000 #define HINT_MIXPLUGINS 0x20000 #define HINT_SPEEDCHANGE 0x40000 //rewbs.envRowGrid -#define HINT_MAXHINTFLAG HINT_SPEEDCHANGE +#define HINT_SEQNAMES 0x80000 +#define HINT_MAXHINTFLAG HINT_SEQNAMES //Bits 0-18 are reserved. #define HINT_MASK_FLAGS (2*HINT_MAXHINTFLAG - 1) //When applied to hint parameter, should give the flag part. #define HINT_MASK_ITEM (~HINT_MASK_FLAGS) //To nullify update hintbits from hint parameter. @@ -89,6 +90,7 @@ // Undo #define MAX_UNDO_LEVEL 100 +// Pattern Undo typedef struct PATTERNUNDOBUFFER { UINT pattern, patternsize; @@ -243,10 +245,10 @@ BOOL CopyEnvelope(UINT nIns, UINT nEnv); BOOL PasteEnvelope(UINT nIns, UINT nEnv); - BOOL ClearUndo(); - BOOL PrepareUndo(UINT pattern, UINT x, UINT y, UINT cx, UINT cy); - UINT DoUndo(); - BOOL CanUndo(); + BOOL ClearPatternUndo(); + BOOL PreparePatternUndo(UINT pattern, UINT x, UINT y, UINT cx, UINT cy); + UINT DoPatternUndo(); + BOOL CanPatternUndo(); LRESULT ActivateView(UINT nIdView, DWORD dwParam); void UpdateAllViews(CView *pSender, LPARAM lHint=0L, CObject *pHint=NULL); HWND GetEditPosition(ROWINDEX &row, PATTERNINDEX &pat, ORDERINDEX &ord); //rewbs.customKeys Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-15 20:21:28 UTC (rev 399) @@ -346,7 +346,7 @@ } SetModified(); - ClearUndo(); + ClearPatternUndo(); UpdateAllViews(NULL, HINT_MODTYPE | HINT_MODGENERAL); EndWaitCursor(); return TRUE; @@ -447,7 +447,7 @@ EndWaitCursor(); } SetModified(); - ClearUndo(); + ClearPatternUndo(); UpdateAllViews(NULL, HINT_MODTYPE); return TRUE; } @@ -520,7 +520,7 @@ END_CRITICAL(); EndWaitCursor(); SetModified(); - ClearUndo(); + ClearPatternUndo(); UpdateAllViews(NULL, HINT_MODTYPE); return FALSE; } @@ -1121,7 +1121,7 @@ if ((hCpy) && ((p = (LPSTR)GlobalLock(hCpy)) != NULL)) { - PrepareUndo(nPattern, 0, 0, m_SndFile.m_nChannels, m_SndFile.PatternSize[nPattern]); + PreparePatternUndo(nPattern, 0, 0, m_SndFile.m_nChannels, m_SndFile.PatternSize[nPattern]); BYTE spdmax = (m_SndFile.m_nType & MOD_TYPE_MOD) ? 0x20 : 0x1F; DWORD dwMemSize = GlobalSize(hCpy); MODCOMMAND *m = m_SndFile.Patterns[nPattern]; @@ -1321,7 +1321,7 @@ nPattern = m_SndFile.Order[oNextOrder]; if(m_SndFile.Patterns.IsValidPat(nPattern) == false) goto PasteDone; m = m_SndFile.Patterns[nPattern]; - PrepareUndo(nPattern, 0,0, m_SndFile.m_nChannels, m_SndFile.PatternSize[nPattern]); + PreparePatternUndo(nPattern, 0,0, m_SndFile.m_nChannels, m_SndFile.PatternSize[nPattern]); oCurrentOrder = oNextOrder; } } @@ -1531,10 +1531,10 @@ ///////////////////////////////////////////////////////////////////////////////////////// -// Undo Functions +// Pattern Undo Functions -BOOL CModDoc::ClearUndo() -//----------------------- +BOOL CModDoc::ClearPatternUndo() +//------------------------------ { for (UINT i=0; i<MAX_UNDO_LEVEL; i++) { @@ -1547,15 +1547,15 @@ } -BOOL CModDoc::CanUndo() -//--------------------- +BOOL CModDoc::CanPatternUndo() +//---------------------------- { return (PatternUndo[0].pbuffer) ? TRUE : FALSE; } -BOOL CModDoc::PrepareUndo(UINT pattern, UINT x, UINT y, UINT cx, UINT cy) -//----------------------------------------------------------------------- +BOOL CModDoc::PreparePatternUndo(UINT pattern, UINT x, UINT y, UINT cx, UINT cy) +//------------------------------------------------------------------------------ { MODCOMMAND *pUndo, *pPattern; UINT nRows; @@ -1604,8 +1604,8 @@ } -UINT CModDoc::DoUndo() -//-------------------- +UINT CModDoc::DoPatternUndo() +//--------------------------- { MODCOMMAND *pUndo, *pPattern; UINT nPattern, nRows; Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-10-15 20:21:28 UTC (rev 399) @@ -611,7 +611,7 @@ nChnEnd = GetChanFromCursor(dwEnd); nRowEnd = GetRowFromCursor(dwEnd); if( (nChnEnd < nChnBeg) || (nRowEnd < nRowBeg) ) return FALSE; - if (pModDoc) return pModDoc->PrepareUndo(m_nPattern, nChnBeg, nRowBeg, nChnEnd-nChnBeg+1, nRowEnd-nRowBeg+1); + if (pModDoc) return pModDoc->PreparePatternUndo(m_nPattern, nChnBeg, nRowBeg, nChnEnd-nChnBeg+1, nRowEnd-nRowBeg+1); return FALSE; } @@ -752,7 +752,7 @@ DWORD startSel = ((m_dwBeginSel>>16)<(m_dwEndSel>>16)) ? m_dwBeginSel : m_dwEndSel; DWORD endSel = ((m_dwBeginSel>>16)<(m_dwEndSel>>16)) ? m_dwEndSel : m_dwBeginSel; - pModDoc->PrepareUndo(m_nPattern, 0, 0, pSndFile->m_nChannels, pSndFile->PatternSize[m_nPattern]); + pModDoc->PreparePatternUndo(m_nPattern, 0, 0, pSndFile->m_nChannels, pSndFile->PatternSize[m_nPattern]); int finalDest = (startSel>>16)+((endSel>>16)-(startSel>>16))*2; for (int row=finalDest; row>(int)(startSel >> 16); row-=2) @@ -802,7 +802,7 @@ DWORD startSel = ((m_dwBeginSel>>16)<(m_dwEndSel>>16))?m_dwBeginSel:m_dwEndSel; DWORD endSel = ((m_dwBeginSel>>16)<(m_dwEndSel>>16))?m_dwEndSel:m_dwBeginSel; - pModDoc->PrepareUndo(m_nPattern, 0, 0, pSndFile->m_nChannels, pSndFile->PatternSize[m_nPattern]); + pModDoc->PreparePatternUndo(m_nPattern, 0, 0, pSndFile->m_nChannels, pSndFile->PatternSize[m_nPattern]); int finalDest = (startSel>>16)+((endSel>>16)-(startSel>>16))/2; @@ -1560,7 +1560,7 @@ maxrow = pSndFile->PatternSize[m_nPattern]; if (colmax >= pSndFile->m_nChannels) colmax = pSndFile->m_nChannels-1; if (colmin > colmax) return; - pModDoc->PrepareUndo(m_nPattern, 0,0, pSndFile->m_nChannels, maxrow); + pModDoc->PreparePatternUndo(m_nPattern, 0,0, pSndFile->m_nChannels, maxrow); for (UINT r=row; r<maxrow; r++) { MODCOMMAND *m = pSndFile->Patterns[m_nPattern] + r * pSndFile->m_nChannels + colmin; @@ -1626,7 +1626,7 @@ maxrow = pSndFile->PatternSize[m_nPattern]; if (colmax >= pSndFile->m_nChannels) colmax = pSndFile->m_nChannels-1; if (colmin > colmax) return; - pModDoc->PrepareUndo(m_nPattern, 0,0, pSndFile->m_nChannels, maxrow); + pModDoc->PreparePatternUndo(m_nPattern, 0,0, pSndFile->m_nChannels, maxrow); for (UINT r=maxrow; r>row; ) { @@ -2384,7 +2384,7 @@ dx = (int)((m_dwDragPos & 0xFFF8) >> 3) - (int)((m_dwStartSel & 0xFFF8) >> 3); dy = (int)(m_dwDragPos >> 16) - (int)(m_dwStartSel >> 16); if ((!dx) && (!dy)) return; - pModDoc->PrepareUndo(m_nPattern, 0,0, nChannels, nRows); + pModDoc->PreparePatternUndo(m_nPattern, 0,0, nChannels, nRows); pNewPattern = CSoundFile::AllocatePattern(nRows, nChannels); if (!pNewPattern) return; x1 = (m_dwBeginSel & 0xFFF8) >> 3; @@ -2563,7 +2563,7 @@ pSndFile->MoveChannel(pSndFile->m_nChannels-1, nChn); pModDoc->SetModified(); - pModDoc->ClearUndo(); + pModDoc->ClearPatternUndo(); pModDoc->UpdateAllViews(NULL, HINT_MODCHANNELS); //refresh channel headers pModDoc->UpdateAllViews(NULL, HINT_MODTYPE); //updates(?) the channel number to general tab display SetCurrentPattern(m_nPattern); @@ -2586,7 +2586,7 @@ pSndFile->MoveChannel(pSndFile->m_nChannels-1, nChn); pModDoc->SetModified(); - pModDoc->ClearUndo(); + pModDoc->ClearPatternUndo(); pModDoc->UpdateAllViews(NULL, HINT_MODCHANNELS); pModDoc->UpdateAllViews(NULL, HINT_MODTYPE); SetCurrentPattern(m_nPattern); @@ -2626,7 +2626,7 @@ if(nNumChnNew == vecChns.size()) { pModDoc->SetModified(); - pModDoc->ClearUndo(); + pModDoc->ClearPatternUndo(); pModDoc->UpdateAllViews(NULL, HINT_MODCHANNELS); pModDoc->UpdateAllViews(NULL, HINT_MODTYPE); SetCurrentPattern(m_nPattern); @@ -2696,7 +2696,7 @@ CModDoc *pModDoc = GetDocument(); if ((pCmdUI) && (pModDoc)) { - pCmdUI->Enable(pModDoc->CanUndo()); + pCmdUI->Enable(pModDoc->CanPatternUndo()); } } @@ -2707,7 +2707,7 @@ CModDoc *pModDoc = GetDocument(); if (pModDoc && IsEditingEnabled_bmsg()) { - UINT nPat = pModDoc->DoUndo(); + UINT nPat = pModDoc->DoPatternUndo(); if (nPat < pModDoc->GetSoundFile()->Patterns.Size()) { pModDoc->SetModified(); @@ -2966,7 +2966,7 @@ if(bUsePlaybackPosition == true) SetEditPos(*pSndFile, nRow, nPattern, pSndFile->m_nRow, pSndFile->m_nPattern); - pModDoc->PrepareUndo(nPattern, nChn, nRow, 1, 1); + pModDoc->PreparePatternUndo(nPattern, nChn, nRow, 1, 1); MODCOMMAND *pRow = pSndFile->Patterns[nPattern].GetpModCommand(nRow, nChn); @@ -3993,7 +3993,7 @@ } // Create undo-point. - pModDoc->PrepareUndo(nPat, nChn, nRow, 1, 1); + pModDoc->PreparePatternUndo(nPat, nChn, nRow, 1, 1); // -- write sdx if playing live if (usePlaybackPosition && nTick) { // avoid SD0 which will be mis-interpreted @@ -4141,7 +4141,7 @@ //Param control 'note' if((note == NOTE_PC || note == NOTE_PCS) && bRecordEnabled) { - pModDoc->PrepareUndo(m_nPattern, nChn, nRow, 1, 1); + pModDoc->PreparePatternUndo(m_nPattern, nChn, nRow, 1, 1); pSndFile->Patterns[m_nPattern].GetpModCommand(nRow, nChn)->note = note; const DWORD sel = (nRow << 16) | m_dwCursor; pModDoc->SetModified(); @@ -4174,7 +4174,7 @@ // If record is enabled, create undo point. if(bRecordEnabled) - pModDoc->PrepareUndo(nPat, nChn, nRow, 1, 1); + pModDoc->PreparePatternUndo(nPat, nChn, nRow, 1, 1); // -- write note and instrument data. const bool isSplit = HandleSplit(p, note); @@ -4331,7 +4331,7 @@ const CHANNELINDEX nChn = GetChanFromCursor(m_dwCursor); UINT nPlayIns = 0; // Simply backup the whole row. - pModDoc->PrepareUndo(m_nPattern, nChn, m_nRow, pSndFile->GetNumChannels(), 1); + pModDoc->PreparePatternUndo(m_nPattern, nChn, m_nRow, pSndFile->GetNumChannels(), 1); PatternRow prowbase = pSndFile->Patterns[m_nPattern].GetRow(m_nRow); MODCOMMAND* p = &prowbase[nChn]; @@ -4825,7 +4825,7 @@ AppendMenu(hMenu, MF_STRING, ID_EDIT_PASTE, "Paste\t" + ih->GetKeyTextFromCommand(kcEditPaste)); AppendMenu(hMenu, MF_STRING, ID_EDIT_MIXPASTE, "Mix Paste\t" + ih->GetKeyTextFromCommand(kcEditMixPaste)); - DWORD greyed = pModDoc->CanUndo()?FALSE:MF_GRAYED; + DWORD greyed = pModDoc->CanPatternUndo()?FALSE:MF_GRAYED; if (!greyed || !(CMainFrame::m_dwPatternSetup&PATTERN_OLDCTXMENUSTYLE)) { AppendMenu(hMenu, MF_STRING|greyed, ID_EDIT_UNDO, "Undo\t" + ih->GetKeyTextFromCommand(kcEditUndo)); } Modified: trunk/OpenMPT/mptrack/View_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/mptrack/View_smp.cpp 2009-10-15 20:21:28 UTC (rev 399) @@ -178,8 +178,8 @@ } -BOOL CViewSample::SetCurrentSample(UINT nSmp) -//------------------------------------------- +BOOL CViewSample::SetCurrentSample(SAMPLEINDEX nSmp) +//-------------------------------------------------- { CModDoc *pModDoc = GetDocument(); CSoundFile *pSndFile; Modified: trunk/OpenMPT/mptrack/View_smp.h =================================================================== --- trunk/OpenMPT/mptrack/View_smp.h 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/mptrack/View_smp.h 2009-10-15 20:21:28 UTC (rev 399) @@ -15,7 +15,8 @@ CImageList m_bmpEnvBar; CRect m_rcClient; SIZE m_sizeTotal; - UINT m_nSample, m_nZoom, m_nScrollPos, m_nScrollFactor, m_nBtnMouseOver; + SAMPLEINDEX m_nSample; + UINT m_nZoom, m_nScrollPos, m_nScrollFactor, m_nBtnMouseOver; DWORD m_dwStatus, m_dwBeginSel, m_dwEndSel, m_dwBeginDrag, m_dwEndDrag; DWORD m_dwMenuParam; DWORD m_NcButtonState[SMP_LEFTBAR_BUTTONS]; @@ -28,7 +29,7 @@ public: void UpdateScrollSize(); - BOOL SetCurrentSample(UINT nSmp); + BOOL SetCurrentSample(SAMPLEINDEX nSmp); BOOL SetZoom(UINT nZoom); LONG SampleToScreen(LONG n) const; DWORD ScreenToSample(LONG x) const; Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2009-10-15 20:21:28 UTC (rev 399) @@ -727,19 +727,29 @@ // go through all sequences for(SEQUENCEINDEX nSeq = 0; nSeq < pSndFile->Order.GetNumSequences(); nSeq++) { - // TODO update sequence names if(pSndFile->Order.GetNumSequences() > 1) { // more than one sequence -> add folder CString sSeqName = pSndFile->Order.GetSequence(nSeq).m_sName; if(sSeqName.IsEmpty()) sSeqName.Format("Sequence %d", nSeq); + UINT state = (nSeq == pSndFile->Order.GetCurrentSequenceIndex()) ? TVIS_BOLD : 0; + if(pInfo->tiSequences[nSeq] == NULL) { pInfo->tiSequences[nSeq] = InsertItem(sSeqName, IMAGE_FOLDER, IMAGE_FOLDER, pInfo->hOrders, TVI_LAST); - } else - { + } + // Update bold item + strcpy(stmp, sSeqName); + tvi.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_STATE; + tvi.state = 0; + tvi.stateMask = TVIS_BOLD; + tvi.hItem = pInfo->tiSequences[nSeq]; + tvi.pszText = stmp; + tvi.cchTextMax = sizeof(stmp); + GetItem(&tvi); + if(tvi.state != state || tvi.pszText != sSeqName) + SetItem(pInfo->tiSequences[nSeq], TVIF_TEXT | TVIF_STATE, sSeqName, 0, 0, state, TVIS_BOLD, 0); - } hAncestorNode = pInfo->tiSequences[nSeq]; } @@ -2017,7 +2027,7 @@ void CModTree::OnUpdate(CModDoc *pModDoc, DWORD dwHint, CObject *pHint) //--------------------------------------------------------------------- { - dwHint &= (HINT_PATNAMES|HINT_SMPNAMES|HINT_INSNAMES|HINT_MODTYPE|HINT_MODGENERAL|HINT_MODSEQUENCE|HINT_MIXPLUGINS|HINT_MPTOPTIONS|HINT_MASK_ITEM); + dwHint &= (HINT_PATNAMES|HINT_SMPNAMES|HINT_INSNAMES|HINT_MODTYPE|HINT_MODGENERAL|HINT_MODSEQUENCE|HINT_MIXPLUGINS|HINT_MPTOPTIONS|HINT_MASK_ITEM|HINT_SEQNAMES); if ((pHint != this) && (dwHint & HINT_MASK_FLAGS)) { for (UINT i=0; i<MODTREE_MAX_DOCUMENTS; i++) Modified: trunk/OpenMPT/soundlib/Load_med.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_med.cpp 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/soundlib/Load_med.cpp 2009-10-15 20:21:28 UTC (rev 399) @@ -810,7 +810,7 @@ if ((!dwBlockArr) || (dwBlockArr > dwMemLength - 4*wNumBlocks)) return true; pdwTable = (LPDWORD)(lpStream + dwBlockArr); playtransp += (version == '3') ? 24 : 48; - for (UINT iBlk=0; iBlk<wNumBlocks; iBlk++) + for (PATTERNINDEX iBlk=0; iBlk<wNumBlocks; iBlk++) { UINT dwPos = BigEndian(pdwTable[iBlk]); if ((!dwPos) || (dwPos >= dwMemLength) || (dwPos >= dwMemLength - 8)) continue; Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-10-15 20:21:28 UTC (rev 399) @@ -1172,6 +1172,9 @@ bPorta = false; } + // Process Invert Loop (MOD Effect, called every row) + InvertLoop(&Chn[nChn]); + // Process special effects (note delay, pattern delay, pattern loop) if ((cmd == CMD_MODCMDEX) || (cmd == CMD_S3MCMDEX)) { @@ -1870,9 +1873,6 @@ break; } - // MOD Effect (called every row) - InvertLoop(&Chn[nChn]); - } // for(...) end // Navigation Effects @@ -2695,18 +2695,17 @@ //-------------------------------------------------- { // EFx implementation for MOD files (PT 1.1A and up: Invert Loop) - // This effect trashes samples. Thanks to bubsy for making this work. :) + // This effect trashes samples. Thanks to 8bitbubsy for making this work. :) if((m_nType & MOD_TYPE_MOD) == 0 || pChn->nEFxSpeed == 0) return; - pChn->nEFxDelay += ModEFxTable[pChn->nEFxSpeed & 0x0F]; - - if(pChn->nEFxDelay < 0x80) return; // only applied if the "delay" reaches 128 - pChn->nEFxDelay = 0; - // we obviously also need a sample for this MODSAMPLE *pModSample = pChn->pEFxSample; if(pModSample == nullptr || pModSample->pSample == nullptr || !(pModSample->uFlags & CHN_LOOP)) return; + pChn->nEFxDelay += ModEFxTable[pChn->nEFxSpeed & 0x0F]; + if((pChn->nEFxDelay & 0x80) == 0) return; // only applied if the "delay" reaches 128 + pChn->nEFxDelay = 0; + if (++pChn->nEFxOffset >= pModSample->nLoopEnd - pModSample->nLoopStart) pChn->nEFxOffset = 0; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-15 20:21:28 UTC (rev 399) @@ -3469,6 +3469,25 @@ } } // End if (oldTypeIsIT_MPT && newTypeIsS3M) + /////////////////////////////////// + // MOD <-> XM: Speed/Tempo update + if(oldTypeIsMOD && newTypeIsXM) + { + switch(m->command) + { + case CMD_SPEED: + m->param = min(m->param, 0x1F); + break; + } + } else if(oldTypeIsXM && newTypeIsMOD) + { + switch(m->command) + { + case CMD_TEMPO: + m->param = max(m->param, 0x21); + break; + } + } /////////////////////////////////////////////////////////////////////// Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-10-15 20:21:28 UTC (rev 399) @@ -113,7 +113,7 @@ unsigned char nPPC; //Pitch Centre? CHAR name[32]; - CHAR filename[12]; + CHAR filename[32]; BYTE nMixPlug; //rewbs.instroVSTi // -> CODE#0027 @@ -566,8 +566,9 @@ BYTE m_nTempoMode; // rewbs.betterBPM BYTE m_nMixLevels; UINT m_nMusicSpeed, m_nMusicTempo; - UINT m_nNextRow, m_nRow; - UINT m_nPattern,m_nCurrentPattern,m_nNextPattern,m_nRestartPos, m_nSeqOverride; + ROWINDEX m_nNextRow, m_nRow; + PATTERNINDEX m_nPattern; + ORDERINDEX m_nCurrentPattern, m_nNextPattern, m_nRestartPos, m_nSeqOverride; //NOTE: m_nCurrentPattern and m_nNextPattern refer to order index - not pattern index. bool m_bPatternTransitionOccurred; UINT m_nMasterVolume, m_nGlobalVolume, m_nSamplesToGlobalVolRampDest, Modified: trunk/OpenMPT/soundlib/pattern.cpp =================================================================== --- trunk/OpenMPT/soundlib/pattern.cpp 2009-10-13 20:20:48 UTC (rev 398) +++ trunk/OpenMPT/soundlib/pattern.cpp 2009-10-15 20:21:28 UTC (rev 399) @@ -132,7 +132,7 @@ if (!newPattern) return true; const UINT nPattern = m_rPatternContainer.GetIndex(this); - rModDoc.PrepareUndo(nPattern, 0,0, nChns, nRows); + rModDoc.PreparePatternUndo(nPattern, 0,0, nChns, nRows); oldPattern = m_ModCommands; for (UINT y=0; y<nRows; y++) { @@ -163,7 +163,7 @@ nRows = m_Rows; nChns = sndFile.m_nChannels; const UINT nPattern = m_rPatternContainer.GetIndex(this); - rModDoc.PrepareUndo(nPattern, 0,0, nChns, nRows); + rModDoc.PreparePatternUndo(nPattern, 0,0, nChns, nRows); nRows /= 2; for (UINT y=0; y<nRows; y++) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-10-18 16:54:29
|
Revision: 401 http://modplug.svn.sourceforge.net/modplug/?rev=401&view=rev Author: saga-games Date: 2009-10-18 16:54:18 +0000 (Sun, 18 Oct 2009) Log Message: ----------- [New] Treeview: Display playing samples / instruments (only those that are assigned to a sample). Can be enabled from setup screen. [Fix] Treeview: Broke when changing sequence count of a module from 1 to 2 [Fix] AMF Loader: Missing break command [Ref] More internal refactoring. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_gen.cpp trunk/OpenMPT/mptrack/Ctrl_ins.h trunk/OpenMPT/mptrack/Ctrl_pat.cpp trunk/OpenMPT/mptrack/Ctrl_pat.h trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Moptions.cpp trunk/OpenMPT/mptrack/PatternRandomizerGUI.cpp trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/mptrack/View_tre.h trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/Vstplug.h trunk/OpenMPT/mptrack/res/img_list.bmp trunk/OpenMPT/soundlib/LOAD_AMF.CPP trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Ctrl_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_gen.cpp 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/mptrack/Ctrl_gen.cpp 2009-10-18 16:54:18 UTC (rev 401) @@ -463,7 +463,7 @@ m_EditRestartPos.GetWindowText(s, sizeof(s)); if (s[0]) { - UINT n = atoi(s); + ORDERINDEX n = (ORDERINDEX)atoi(s); n = CLAMP(n, 0, m_pSndFile->Order.size()); for (ORDERINDEX i = 0; i <= n; i++) if (m_pSndFile->Order[i] == m_pSndFile->Order.GetInvalidPatIndex()) return; Modified: trunk/OpenMPT/mptrack/Ctrl_ins.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.h 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/mptrack/Ctrl_ins.h 2009-10-18 16:54:18 UTC (rev 401) @@ -71,7 +71,7 @@ CSliderCtrl m_SliderVolSwing, m_SliderPanSwing, m_SliderCutSwing, m_SliderResSwing, m_SliderCutOff, m_SliderResonance; CNoteMapWnd m_NoteMap; - UINT m_nInstrument; + INSTRUMENTINDEX m_nInstrument; // -> CODE#0027 // -> DESC="per-instrument volume ramping setup (refered as attack)" Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-10-18 16:54:18 UTC (rev 401) @@ -1166,7 +1166,7 @@ { m_pSndFile->Order.m_sName = str; m_pModDoc->SetModified(); - m_pModDoc->UpdateAllViews(NULL, HINT_SEQNAMES, this); + m_pModDoc->UpdateAllViews(NULL, (m_pSndFile->Order.GetCurrentSequenceIndex() << HINT_SHIFT_SEQUENCE) | HINT_SEQNAMES, this); } } } Modified: trunk/OpenMPT/mptrack/Ctrl_pat.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-10-18 16:54:18 UTC (rev 401) @@ -154,7 +154,8 @@ CPatEdit m_EditSpacing, m_EditPatName, m_EditOrderListMargins; CSpinButtonCtrl m_SpinInstrument, m_SpinSpacing, m_SpinOrderListMargins; CModControlBar m_ToolBar; - UINT m_nInstrument, m_nDetailLevel; + INSTRUMENTINDEX m_nInstrument; + UINT m_nDetailLevel; BOOL m_bRecord, m_bVUMeters, m_bPluginNames; // -> CODE#0012 // -> DESC="midi keyboard split" Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2009-10-18 16:54:18 UTC (rev 401) @@ -170,49 +170,39 @@ #define NUM_VUMETER_PENS 32 // Pattern Setup (contains also non-pattern related settings) -#define PATTERN_PLAYNEWNOTE 0x01 -#define PATTERN_LARGECOMMENTS 0x02 -#define PATTERN_STDHIGHLIGHT 0x04 -#define PATTERN_SMALLFONT 0x08 -#define PATTERN_CENTERROW 0x10 -#define PATTERN_WRAP 0x20 -#define PATTERN_EFFECTHILIGHT 0x40 -#define PATTERN_HEXDISPLAY 0x80 -#define PATTERN_FLATBUTTONS 0x100 -#define PATTERN_CREATEBACKUP 0x200 -#define PATTERN_SINGLEEXPAND 0x400 -#define PATTERN_AUTOSPACEBAR 0x800 -#define PATTERN_NOEXTRALOUD 0x1000 -#define PATTERN_DRAGNDROPEDIT 0x2000 -#define PATTERN_2NDHIGHLIGHT 0x4000 -#define PATTERN_MUTECHNMODE 0x8000 -#define PATTERN_SHOWPREVIOUS 0x10000 -#define PATTERN_CONTSCROLL 0x20000 -#define PATTERN_KBDNOTEOFF 0x40000 -#define PATTERN_FOLLOWSONGOFF 0x80000 //rewbs.noFollow +#define PATTERN_PLAYNEWNOTE 0x01 // play new notes while recording +#define PATTERN_LARGECOMMENTS 0x02 // use large font in comments +#define PATTERN_STDHIGHLIGHT 0x04 // enable primary highlight +#define PATTERN_SMALLFONT 0x08 // use small font in pattern editor +#define PATTERN_CENTERROW 0x10 // always center active row +#define PATTERN_WRAP 0x20 // wrap around cursor in editor +#define PATTERN_EFFECTHILIGHT 0x40 // effect syntax highlighting +#define PATTERN_HEXDISPLAY 0x80 // display row number in hex +#define PATTERN_FLATBUTTONS 0x100 // flat toolbar buttons +#define PATTERN_CREATEBACKUP 0x200 // create .bak files when saving +#define PATTERN_SINGLEEXPAND 0x400 // single click to expand tree +#define PATTERN_AUTOSPACEBAR 0x800 // space bar repeats previous action +#define PATTERN_NOEXTRALOUD 0x1000 // no loud samples in sample editor +#define PATTERN_DRAGNDROPEDIT 0x2000 // enable drag and drop editing +#define PATTERN_2NDHIGHLIGHT 0x4000 // activate secondary highlight +#define PATTERN_MUTECHNMODE 0x8000 // ignore muted channels +#define PATTERN_SHOWPREVIOUS 0x10000 // show prev/next patterns +#define PATTERN_CONTSCROLL 0x20000 // continous pattern scrolling +#define PATTERN_KBDNOTEOFF 0x40000 // Record note-off events +#define PATTERN_FOLLOWSONGOFF 0x80000 // follow song off by default +#define PATTERN_MIDIRECORD 0x100000 // MIDI Record on by default +//#define PATTERN_ALTERNTIVEBPMSPEED 0x200000 // deprecated +#define PATTERN_HILITETIMESIGS 0x400000 // highlight on song signature +#define PATTERN_OLDCTXMENUSTYLE 0x800000 // mpt 1.16 pattern context menu style +#define PATTERN_SYNCMUTE 0x1000000 // maintain sample sync on mute +#define PATTERN_AUTODELAY 0x2000000 // automatically insert delay commands in pattern when entering notes +#define PATTERN_NOTEFADE 0x4000000 // alt. note fade behaviour when entering notes +#define PATTERN_OVERFLOWPASTE 0x8000000 // continue paste in the next pattern instead of cutting off +#define PATTERN_POSITIONAWARETIMER 0x10000000 // try to set the timer in the statusbar when jumping around in modules +#define PATTERN_RESETCHANNELS 0x20000000 // reset channels when looping +#define PATTERN_LIVEUPDATETREE 0x40000000 // update active sample / instr icons in treeview -// -> CODE#0017 -// -> DESC="midi in record mode setup option" -#define PATTERN_MIDIRECORD 0x100000 -// -! BEHAVIOUR_CHANGE#0017 -// -> CODE#0022 -// -> DESC="alternative BPM/Speed interpretation method" -#define PATTERN_ALTERNTIVEBPMSPEED 0x200000 -// rewbs: this options is now available under song settings. It is therefore saved with the song. -// -! NEW_FEATURE#0022 - -#define PATTERN_HILITETIMESIGS 0x400000 - -#define PATTERN_OLDCTXMENUSTYLE 0x800000 -#define PATTERN_SYNCMUTE 0x1000000 -#define PATTERN_AUTODELAY 0x2000000 -#define PATTERN_NOTEFADE 0x4000000 -#define PATTERN_OVERFLOWPASTE 0x8000000 -#define PATTERN_POSITIONAWARETIMER 0x10000000 -#define PATTERN_RESETCHANNELS 0x20000000 - - // Keyboard Setup enum { KEYBOARD_CUSTOM=0, @@ -263,7 +253,9 @@ IMAGE_ASIO, IMAGE_GRAPH, IMAGE_SAMPLEMUTE, - IMAGE_INSTRMUTE + IMAGE_INSTRMUTE, + IMAGE_SAMPLEACTIVE, + IMAGE_INSTRACTIVE, }; ////////////////////////////////////////////////////////////////////////// Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-18 16:54:18 UTC (rev 401) @@ -199,7 +199,7 @@ BeginWaitCursor(); LPMIDILIBSTRUCT lpMidiLib = CTrackApp::GetMidiLibrary(); // Scan Instruments - if (lpMidiLib) for (UINT nIns=1; nIns<=m_SndFile.m_nInstruments; nIns++) if (m_SndFile.Instruments[nIns]) + if (lpMidiLib) for (INSTRUMENTINDEX nIns = 1; nIns <= m_SndFile.m_nInstruments; nIns++) if (m_SndFile.Instruments[nIns]) { LPCSTR pszMidiMapName; MODINSTRUMENT *pIns = m_SndFile.Instruments[nIns]; @@ -433,7 +433,7 @@ if(unsavedInstrument && ::MessageBox(NULL,"Do you want to save modified instruments ?",NULL,MB_ICONQUESTION | MB_YESNO | MB_APPLMODAL) == IDYES){ - for(UINT i = 0 ; i < m_SndFile.m_nInstruments ; i++){ + for(INSTRUMENTINDEX i = 0 ; i < m_SndFile.m_nInstruments ; i++){ if(m_SndFile.m_szInstrumentPath[i][0] != '\0'){ int size = strlen(m_SndFile.m_szInstrumentPath[i]); BOOL iti = _stricmp(&m_SndFile.m_szInstrumentPath[i][size-3],"iti") == 0; @@ -1707,13 +1707,13 @@ m_SndFile.m_nRow = nRow; } else { - for (UINT i=0; i<m_SndFile.Order.size(); i++) + for (ORDERINDEX nOrd = 0; nOrd < m_SndFile.Order.size(); nOrd++) { - if (m_SndFile.Order[i] == m_SndFile.Order.GetInvalidPatIndex()) break; - if (m_SndFile.Order[i] == nPat) + if (m_SndFile.Order[nOrd] == m_SndFile.Order.GetInvalidPatIndex()) break; + if (m_SndFile.Order[nOrd] == nPat) { - m_SndFile.m_nCurrentPattern = i; - m_SndFile.m_nNextPattern = i; + m_SndFile.m_nCurrentPattern = nOrd; + m_SndFile.m_nNextPattern = nOrd; m_SndFile.m_nNextRow = nNextRow; m_SndFile.m_nRow = nRow; break; Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-10-18 16:54:18 UTC (rev 401) @@ -70,6 +70,7 @@ #define HINT_BITS_SAMPLE 12 #define HINT_BITS_INST 8 #define HINT_BITS_CHNTAB 8 +#define HINT_BITS_SEQUENCE 6 //Defines bit shift values used for setting/retrieving the additional hint data to/from hint parameter. #define HINT_SHIFT_PAT (32 - HINT_BITS_PATTERN) @@ -77,6 +78,7 @@ #define HINT_SHIFT_SMP (32 - HINT_BITS_SAMPLE) #define HINT_SHIFT_INS (32 - HINT_BITS_INST) #define HINT_SHIFT_CHNTAB (32 - HINT_BITS_CHNTAB) +#define HINT_SHIFT_SEQUENCE (32 - HINT_BITS_SEQUENCE) //Check that hint bit counts are not too large given the number of hint flags. STATIC_ASSERT( ((-1 << HINT_SHIFT_PAT) & HINT_MASK_ITEM) == (-1 << HINT_SHIFT_PAT) ); @@ -84,6 +86,7 @@ STATIC_ASSERT( ((-1 << HINT_SHIFT_SMP) & HINT_MASK_ITEM) == (-1 << HINT_SHIFT_SMP) ); STATIC_ASSERT( ((-1 << HINT_SHIFT_INS) & HINT_MASK_ITEM) == (-1 << HINT_SHIFT_INS) ); STATIC_ASSERT( ((-1 << HINT_SHIFT_CHNTAB) & HINT_MASK_ITEM) == (-1 << HINT_SHIFT_CHNTAB) ); +STATIC_ASSERT( ((-1 << HINT_SHIFT_SEQUENCE) & HINT_MASK_ITEM) == (-1 << HINT_SHIFT_SEQUENCE) ); Modified: trunk/OpenMPT/mptrack/Moptions.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moptions.cpp 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/mptrack/Moptions.cpp 2009-10-18 16:54:18 UTC (rev 401) @@ -661,17 +661,8 @@ OPTGEN_SHOWPREVIOUS, OPTGEN_CONTSCROLL, OPTGEN_KBDNOTEOFF, - OPTGEN_FOLLOWSONGOFF, //rewbs.noFollow -// -> CODE#0017 -// -> DESC="midi in record mode setup option" + OPTGEN_FOLLOWSONGOFF, OPTGEN_MIDIRECORD, -// -! BEHAVIOUR_CHANGE#0017 - -// -> CODE#0022 -// -> DESC="alternative BPM/Speed interpretation method" -// OPTGEN_ALTERNTIVEBPMSPEED, -// rewbs: this options is now available under song settings. It is therefore saved with the song. -// -! NEW_FEATURE#0022 OPTGEN_PATTERNCTXMENUSTYLE, OPTGEN_SYNCMUTE, OPTGEN_AUTODELAY, @@ -679,6 +670,7 @@ OPTGEN_OVERFLOWPASTE, OPTGEN_POSITIONAWARETIMER, OPTGEN_RESETCHANNELS, + OPTGEN_LIVEUPDATETREE, OPTGEN_MAXOPTIONS }; @@ -699,18 +691,8 @@ {"Show Prev/Next patterns", "Displays grayed-out version of the previous/next patterns in the pattern editor. Does not work if \"always center active row\" is disabled."}, {"Continuous scroll", "Jumps to the next pattern when moving past the end of a pattern"}, {"Record note off", "Record note off when a key is released on the PC keyboard (Only works in instrument mode)."}, - {"Follow song off by default", "Ensure follow song is off when opening or starting a new song."}, //rewbs.noFollow -// -> CODE#0017 -// -> DESC="midi in record mode setup option" + {"Follow song off by default", "Ensure follow song is off when opening or starting a new song."}, {"Midi record", "Enable midi in record by default."}, -// -! BEHAVIOUR_CHANGE#0017 - -// -> CODE#0022 -// -> DESC="alternative BPM/Speed interpretation method" -// {"Alternative BPM/Speed", "Alternative BPM/Speed interpretation where speed represents the number of tempo ticks per pattern row."}, -// rewbs: this options is now available under song settings. It is therefore saved with the song. -// -! NEW_FEATURE#0022 - {"Old style pattern context menu", "Check this option to hide unavailable items in the pattern editor context menu. Uncheck to grey-out unavailable items instead."}, {"Maintain sample sync on mute", "Samples continue to be processed when channels are muted (like in IT2 and FT2)"}, {"Automatic delay commands", "Automatically insert appropriate note-delay commands when recording notes during live playback."}, @@ -718,6 +700,7 @@ {"Overflow paste mode", "Wrap pasted pattern data into next pattern. This is useful for creating echo channels."}, {"Position aware timer", "If enabled, timer will show the playback position time if possible instead of running timer."}, {"Reset channels on loop", "If enabled, channels will be reset to their initial state when song looping is enabled.\nNote: This does not affect manual song loops (i.e. triggered by pattern commands)"}, + {"Update sample status in tree", "If enabled, active samples and instruments will be indicated by a differnt icon in the treeview."} }; @@ -763,26 +746,16 @@ case OPTGEN_SHOWPREVIOUS: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_SHOWPREVIOUS); break; case OPTGEN_CONTSCROLL: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_CONTSCROLL); break; case OPTGEN_KBDNOTEOFF: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_KBDNOTEOFF); break; - case OPTGEN_FOLLOWSONGOFF: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_FOLLOWSONGOFF); break; //rewbs.noFollow - -// -> CODE#0017 -// -> DESC="midi in record mode setup option" + case OPTGEN_FOLLOWSONGOFF: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_FOLLOWSONGOFF); break; case OPTGEN_MIDIRECORD: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_MIDIRECORD); break; -// -! BEHAVIOUR_CHANGE#0017 - -// -> CODE#0022 -// -> DESC="alternative BPM/Speed interpretation method" -// case OPTGEN_ALTERNTIVEBPMSPEED: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_ALTERNTIVEBPMSPEED); break; -// rewbs: this options is now available under song settings. It is therefore saved with the song. -// -! NEW_FEATURE#0022 - case OPTGEN_PATTERNCTXMENUSTYLE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_OLDCTXMENUSTYLE); break; - case OPTGEN_SYNCMUTE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_SYNCMUTE); break; - + case OPTGEN_PATTERNCTXMENUSTYLE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_OLDCTXMENUSTYLE); break; + case OPTGEN_SYNCMUTE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_SYNCMUTE); break; case OPTGEN_AUTODELAY: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_AUTODELAY); break; case OPTGEN_PATNOTEFADE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_NOTEFADE); break; case OPTGEN_OVERFLOWPASTE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_OVERFLOWPASTE); break; case OPTGEN_POSITIONAWARETIMER: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_POSITIONAWARETIMER); break; - case OPTGEN_RESETCHANNELS: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_RESETCHANNELS); break; + case OPTGEN_RESETCHANNELS: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_RESETCHANNELS); break; + case OPTGEN_LIVEUPDATETREE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_LIVEUPDATETREE); break; } m_CheckList.SetCheck(i, (bCheck) ? TRUE : FALSE); } @@ -832,26 +805,16 @@ case OPTGEN_SHOWPREVIOUS: mask = PATTERN_SHOWPREVIOUS; break; case OPTGEN_CONTSCROLL: mask = PATTERN_CONTSCROLL; break; case OPTGEN_KBDNOTEOFF: mask = PATTERN_KBDNOTEOFF; break; - case OPTGEN_FOLLOWSONGOFF: mask = PATTERN_FOLLOWSONGOFF; break; //rewbs.noFollow - - -// -> CODE#0017 -// -> DESC="midi in record mode setup option" + case OPTGEN_FOLLOWSONGOFF: mask = PATTERN_FOLLOWSONGOFF; break; case OPTGEN_MIDIRECORD: mask = PATTERN_MIDIRECORD; break; -// -! BEHAVIOUR_CHANGE#0017 - -// -> CODE#0022 -// -> DESC="alternative BPM/Speed interpretation method" -// case OPTGEN_ALTERNTIVEBPMSPEED: mask = PATTERN_ALTERNTIVEBPMSPEED; break; -// rewbs: this options is now available under song settings. It is therefore saved with the song. -// -! NEW_FEATURE#0022 case OPTGEN_PATTERNCTXMENUSTYLE: mask = PATTERN_OLDCTXMENUSTYLE; break; - case OPTGEN_SYNCMUTE: mask = PATTERN_SYNCMUTE; break; - case OPTGEN_AUTODELAY: mask = PATTERN_AUTODELAY; break; - case OPTGEN_PATNOTEFADE: mask = PATTERN_NOTEFADE; break; - case OPTGEN_OVERFLOWPASTE: mask = PATTERN_OVERFLOWPASTE; break; - case OPTGEN_POSITIONAWARETIMER: mask = PATTERN_POSITIONAWARETIMER; break; - case OPTGEN_RESETCHANNELS: mask = PATTERN_RESETCHANNELS; break; + case OPTGEN_SYNCMUTE: mask = PATTERN_SYNCMUTE; break; + case OPTGEN_AUTODELAY: mask = PATTERN_AUTODELAY; break; + case OPTGEN_PATNOTEFADE: mask = PATTERN_NOTEFADE; break; + case OPTGEN_OVERFLOWPASTE: mask = PATTERN_OVERFLOWPASTE; break; + case OPTGEN_POSITIONAWARETIMER: mask = PATTERN_POSITIONAWARETIMER; break; + case OPTGEN_RESETCHANNELS: mask = PATTERN_RESETCHANNELS; break; + case OPTGEN_LIVEUPDATETREE: mask = PATTERN_LIVEUPDATETREE; break; } if (bCheck) CMainFrame::m_dwPatternSetup |= mask; else CMainFrame::m_dwPatternSetup &= ~mask; Modified: trunk/OpenMPT/mptrack/PatternRandomizerGUI.cpp =================================================================== --- trunk/OpenMPT/mptrack/PatternRandomizerGUI.cpp 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/mptrack/PatternRandomizerGUI.cpp 2009-10-18 16:54:18 UTC (rev 401) @@ -81,7 +81,7 @@ bool CPatternRandomizerGUI::isVisible() { //---------------------------------- - return (bool)IsWindowVisible(); + return IsWindowVisible() ? true : false; } Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2009-10-18 16:54:18 UTC (rev 401) @@ -699,22 +699,19 @@ { const DWORD nPat = (lHint >> HINT_SHIFT_PAT); - // only one seq remaining: update parent item || previously only one sequence + // (only one seq remaining || previously only one sequence): update parent item if((pInfo->tiSequences.size() > 1 && pSndFile->Order.GetNumSequences() == 1) || (pInfo->tiSequences.size() == 1 && pSndFile->Order.GetNumSequences() > 1)) { - if(pInfo->tiOrders.size() != pSndFile->Order.GetNumSequences()) + for(size_t nSeq = 0; nSeq < pInfo->tiOrders.size(); nSeq++) { - for(size_t nSeq = 0; nSeq < pInfo->tiOrders.size(); nSeq++) + for(size_t nOrd = 0; nOrd < pInfo->tiOrders[nSeq].size(); nOrd++) if (pInfo->tiOrders[nSeq][nOrd]) { - for(size_t nOrd = 0; nOrd < pInfo->tiOrders[nSeq].size(); nOrd++) if (pInfo->tiOrders[nSeq][nOrd]) - { - DeleteItem(pInfo->tiOrders[nSeq][nOrd]); pInfo->tiOrders[nSeq][nOrd] = NULL; - } - DeleteItem(pInfo->tiSequences[nSeq]); pInfo->tiSequences[nSeq] = NULL; + if(pInfo->tiOrders[nSeq][nOrd]) DeleteItem(pInfo->tiOrders[nSeq][nOrd]); pInfo->tiOrders[nSeq][nOrd] = NULL; } - pInfo->tiOrders.resize(pSndFile->Order.GetNumSequences()); - pInfo->tiSequences.resize(pSndFile->Order.GetNumSequences(), NULL); + if(pInfo->tiSequences[nSeq]) DeleteItem(pInfo->tiSequences[nSeq]); pInfo->tiSequences[nSeq] = NULL; } + pInfo->tiOrders.resize(pSndFile->Order.GetNumSequences()); + pInfo->tiSequences.resize(pSndFile->Order.GetNumSequences(), NULL); } // If there are too many sequences, delete them. @@ -734,8 +731,11 @@ HTREEITEM hAncestorNode = pInfo->hOrders; + SEQUENCEINDEX nSeqMin = 0, nSeqMax = pSndFile->Order.GetNumSequences() - 1; + SEQUENCEINDEX nHintParam = lHint >> HINT_SHIFT_SEQUENCE; + if ((hintFlagPart == HINT_SEQNAMES) && (nHintParam <= nSeqMax)) nSeqMin = nSeqMax = nHintParam; // go through all sequences - for(SEQUENCEINDEX nSeq = 0; nSeq < pSndFile->Order.GetNumSequences(); nSeq++) + for(SEQUENCEINDEX nSeq = nSeqMin; nSeq <= nSeqMax; nSeq++) { if(pSndFile->Order.GetNumSequences() > 1) { @@ -885,7 +885,8 @@ { bool bSamplePresent = (pSndFile->Samples[nSmp].pSample) ? true : false; int nImage = (bSamplePresent) ? IMAGE_SAMPLES : IMAGE_NOSAMPLE; - if(pInfo->pModDoc->IsSampleMuted(nSmp) && bSamplePresent) nImage = IMAGE_SAMPLEMUTE; + if(pInfo->bIsSamplePlaying[nSmp - 1] && bSamplePresent) nImage = IMAGE_SAMPLEACTIVE; + if(pInfo->pModDoc->IsSampleMuted(nSmp)) nImage = IMAGE_SAMPLEMUTE; wsprintf(s, "%3d: %s", nSmp, pSndFile->m_szNames[nSmp]); if (!pInfo->tiSamples[nSmp]) @@ -952,6 +953,7 @@ } int nImage = IMAGE_INSTRUMENTS; + if(pInfo->bIsInstrPlaying[nIns - 1]) nImage = IMAGE_INSTRACTIVE; if(pInfo->pModDoc->IsInstrumentMuted(nIns)) nImage = IMAGE_INSTRMUTE; if (!pInfo->tiInstruments[nIns]) @@ -2037,9 +2039,49 @@ DocInfo[nDocNdx]->nSeqSel = nNewSeq; UpdateView(nDocNdx, HINT_MODSEQUENCE); } + + // Update sample / instrument playing status icons (will only detect instruments with samples, though) + + if((CMainFrame::m_dwPatternSetup & PATTERN_LIVEUPDATETREE) == 0) return; + // TODO: Is there a way to find out if the treeview is actually visible? Or if the Sample and Instrument folders are collapsed? + /*static int nUpdateCount = 0; + nUpdateCount++; + if(nUpdateCount < 5) return; // don't update too often + nUpdateCount = 0;*/ + + memset(DocInfo[nDocNdx]->bIsSamplePlaying, false, MAX_SAMPLES * sizeof(bool)); + memset(DocInfo[nDocNdx]->bIsInstrPlaying, false, MAX_INSTRUMENTS * sizeof(bool)); + + CSoundFile *pSndFile = pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return; + + for(CHANNELINDEX nChn = 0; nChn < MAX_CHANNELS; nChn++) + { + if(pSndFile->Chn[nChn].nPos > 0) + { + for(SAMPLEINDEX nSmp = 1; nSmp <= pSndFile->m_nSamples; nSmp++) + { + if(pSndFile->Chn[nChn].pModSample == &pSndFile->Samples[nSmp]) + { + DocInfo[nDocNdx]->bIsSamplePlaying[nSmp - 1] = true; + break; + } + } + for(INSTRUMENTINDEX nIns = 1; nIns <= pSndFile->m_nInstruments; nIns++) + { + if(pSndFile->Chn[nChn].pModInstrument == pSndFile->Instruments[nIns]) + { + DocInfo[nDocNdx]->bIsInstrPlaying[nIns - 1] = true; + break; + } + } + } + } + UpdateView(nDocNdx, HINT_SAMPLEINFO | HINT_INSTRUMENT); } + ///////////////////////////////////////////////////////////////////////////// // CViewModTree message handlers Modified: trunk/OpenMPT/mptrack/View_tre.h =================================================================== --- trunk/OpenMPT/mptrack/View_tre.h 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/mptrack/View_tre.h 2009-10-18 16:54:18 UTC (rev 401) @@ -56,7 +56,8 @@ vector<vector<HTREEITEM> > tiOrders; vector<HTREEITEM> tiSequences; HTREEITEM tiEffects[MAX_MIXPLUGINS]; - + bool bIsSamplePlaying[MAX_SAMPLES]; + bool bIsInstrPlaying[MAX_INSTRUMENTS]; MODTREEDOCINFO(const CSoundFile* const pSndFile) { @@ -77,6 +78,8 @@ memset(tiSamples, 0, sizeof(tiSamples)); memset(tiInstruments, 0, sizeof(tiInstruments)); memset(tiEffects, 0, sizeof(tiEffects)); + memset(bIsSamplePlaying, false, MAX_SAMPLES * sizeof(bool)); + memset(bIsInstrPlaying, false, MAX_INSTRUMENTS * sizeof(bool)); } }; Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2009-10-18 16:54:18 UTC (rev 401) @@ -3148,17 +3148,18 @@ //end rewbs.VSTcompliance -BOOL CVstPlugin::isInstrument() // ericus 18/02/2005 +bool CVstPlugin::isInstrument() // ericus 18/02/2005 //----------------------------- { - if(m_pEffect) return ((m_pEffect->flags & effFlagsIsSynth) || (!m_pEffect->numInputs)); // rewbs.dryRatio - return FALSE; + if(m_pEffect) return ((m_pEffect->flags & effFlagsIsSynth) || (!m_pEffect->numInputs)) ? true : false; // rewbs.dryRatio + return false; } -BOOL CVstPlugin::CanRecieveMidiEvents() { -//--------------------------------------- +bool CVstPlugin::CanRecieveMidiEvents() +//------------------------------------- +{ CString s = "receiveVstMidiEvent"; - return (CVstPlugin::Dispatch(effCanDo, 0, 0, (char*)(LPCTSTR)s, 0)); + return (CVstPlugin::Dispatch(effCanDo, 0, 0, (char*)(LPCTSTR)s, 0)) ? true : false; } bool CVstPlugin::KeysRequired() Modified: trunk/OpenMPT/mptrack/Vstplug.h =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.h 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/mptrack/Vstplug.h 2009-10-18 16:54:18 UTC (rev 401) @@ -148,8 +148,8 @@ bool Bypass(); //rewbs.defaultPlugGUI bool IsBypassed(); //rewbs.defaultPlugGUI - BOOL isInstrument(); // ericus 18/02/2005 - BOOL CanRecieveMidiEvents(); + bool isInstrument(); // ericus 18/02/2005 + bool CanRecieveMidiEvents(); bool KeysRequired(); void GetOutputPlugList(CArray<CVstPlugin*,CVstPlugin*> &list); Modified: trunk/OpenMPT/mptrack/res/img_list.bmp =================================================================== (Binary files differ) Modified: trunk/OpenMPT/soundlib/LOAD_AMF.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-10-18 16:54:18 UTC (rev 401) @@ -152,6 +152,7 @@ case 0x17: param = (param+64)&0x7F; if (m->command) { if (!m->volcmd) { m->volcmd = VOLCMD_PANNING; m->vol = param/2; } command = 0; } else { command = CMD_PANNING8; } + break; // Unknown effects default: command = param = 0; } Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-18 16:54:18 UTC (rev 401) @@ -1112,7 +1112,7 @@ void CSoundFile::SetCurrentPos(UINT nPos) //--------------------------------------- { - UINT nPattern; + ORDERINDEX nPattern; BYTE resetMask = (!nPos) ? CHNRESET_SETPOS_FULL : CHNRESET_SETPOS_BASIC; for (CHANNELINDEX i=0; i<MAX_CHANNELS; i++) @@ -1178,13 +1178,13 @@ -void CSoundFile::SetCurrentOrder(UINT nPos) -//----------------------------------------- +void CSoundFile::SetCurrentOrder(ORDERINDEX nOrder) +//----------------------------------------------- { //while ((nPos < Order.size()) && (Order[nPos] == 0xFE)) nPos++; - while ((nPos < Order.size()) && (Order[nPos] == Order.GetIgnoreIndex())) nPos++; - if ((nPos >= Order.size()) || (Order[nPos] >= Patterns.Size())) return; - for (UINT j=0; j<MAX_CHANNELS; j++) + while ((nOrder < Order.size()) && (Order[nOrder] == Order.GetIgnoreIndex())) nOrder++; + if ((nOrder >= Order.size()) || (Order[nOrder] >= Patterns.Size())) return; + for (CHANNELINDEX j = 0; j < MAX_CHANNELS; j++) { Chn[j].nPeriod = 0; Chn[j].nNote = NOTE_NONE; @@ -1201,12 +1201,12 @@ } Chn[j].nTremorCount = 0; } - if (!nPos) + if (!nOrder) { SetCurrentPos(0); } else { - m_nNextPattern = nPos; + m_nNextPattern = nOrder; m_nRow = m_nNextRow = 0; m_nPattern = 0; m_nTickCount = m_nMusicSpeed; @@ -1304,8 +1304,8 @@ -void CSoundFile::LoopPattern(int nPat, int nRow) -//---------------------------------------------- +void CSoundFile::LoopPattern(PATTERNINDEX nPat, ROWINDEX nRow) +//------------------------------------------------------------ { if ((nPat < 0) || (nPat >= Patterns.Size()) || (!Patterns[nPat])) { @@ -1324,8 +1324,8 @@ } } //rewbs.playSongFromCursor -void CSoundFile::DontLoopPattern(int nPat, int nRow) -//---------------------------------------------- +void CSoundFile::DontLoopPattern(PATTERNINDEX nPat, ROWINDEX nRow) +//---------------------------------------------------------------- { if ((nPat < 0) || (nPat >= Patterns.Size()) || (!Patterns[nPat])) nPat = 0; if ((nRow < 0) || (nRow >= (int)PatternSize[nPat])) nRow = 0; Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-10-16 19:53:27 UTC (rev 400) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-10-18 16:54:18 UTC (rev 401) @@ -306,8 +306,8 @@ virtual bool IsResumed()=0; virtual void Resume()=0; virtual void Suspend()=0; - virtual BOOL isInstrument()=0; - virtual BOOL CanRecieveMidiEvents()=0; + virtual bool isInstrument()=0; + virtual bool CanRecieveMidiEvents()=0; virtual void SetDryRatio(UINT param)=0; }; @@ -643,9 +643,9 @@ double GetCurrentBPM() const; ORDERINDEX FindOrder(PATTERNINDEX nPat, UINT startFromOrder=0, bool direction = true); //rewbs.playSongFromCursor - void DontLoopPattern(int nPat, int nRow=0); //rewbs.playSongFromCursor + void DontLoopPattern(PATTERNINDEX nPat, ROWINDEX nRow = 0); //rewbs.playSongFromCursor void SetCurrentPos(UINT nPos); - void SetCurrentOrder(UINT nOrder); + void SetCurrentOrder(ORDERINDEX nOrder); void GetTitle(LPSTR s) const { lstrcpyn(s,m_szNames[0],32); } LPCSTR GetTitle() const { return m_szNames[0]; } CString GetSampleName(UINT nSample) const; @@ -667,7 +667,7 @@ void SetRepeatCount(int n) { m_nRepeatCount = n; } int GetRepeatCount() const { return m_nRepeatCount; } BOOL IsPaused() const { return (m_dwSongFlags & SONG_PAUSED) ? TRUE : FALSE; } - void LoopPattern(int nPat, int nRow=0); + void LoopPattern(PATTERNINDEX nPat, ROWINDEX nRow = 0); void CheckCPUUsage(UINT nCPU); BOOL SetPatternName(UINT nPat, LPCSTR lpszName); BOOL GetPatternName(UINT nPat, LPSTR lpszName, UINT cbSize=MAX_PATTERNNAME) const; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-10-23 23:12:16
|
Revision: 403 http://modplug.svn.sourceforge.net/modplug/?rev=403&view=rev Author: saga-games Date: 2009-10-23 23:12:00 +0000 (Fri, 23 Oct 2009) Log Message: ----------- [Fix] Pattern c&p: invalid commands are not pasted anymore [Fix] Mod conversion: "orderlist fixing" did not work as expected [Imp] Pattern c&p: convert pasted commands if necessary [Imp] Mod conversion: insert pattern break commands when resizing patterns to 64 rows that were smaller [Imp] Note Properties: Better explanation of "Invert Loop" parameter [Ref] Added "HasCommand" / "HasVolCommand" to the Mod Specifications Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Mptrack.h trunk/OpenMPT/mptrack/View_ins.h trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/soundlib/LOAD_AMF.CPP trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_mdl.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/mod_specifications.cpp trunk/OpenMPT/soundlib/mod_specifications.h trunk/OpenMPT/soundlib/modcommand.h trunk/OpenMPT/soundlib/pattern.cpp Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -2721,10 +2721,17 @@ strcat(s, " rows"); 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 + if(m_SndFile.m_nType & MOD_TYPE_MOD) // invert loop + { + if((param & 0x0F) == 0) + strcpy(s, "Stop"); + else + wsprintf(s, "Speed %d", param & 0x0F); + } + else // macro + { + wsprintf(s, "SF%X", param & 0x0F); + } break; default: break; Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -68,6 +68,8 @@ newTypeIsXM_IT_MPT = (newTypeIsXM || newTypeIsIT || newTypeIsMPT), newTypeIsIT_MPT = (newTypeIsIT || newTypeIsMPT); + const CModSpecifications& specs = m_SndFile.GetModSpecifications(nNewType); + if(oldTypeIsMPT) { if(::MessageBox(NULL, str_mptm_conversion_warning, 0, MB_YESNO) != IDYES) @@ -126,7 +128,12 @@ UINT i = 0; for (i=0; i<m_SndFile.Patterns.Size(); i++) if ((m_SndFile.Patterns[i]) && (m_SndFile.PatternSize[i] != 64)) { - m_SndFile.Patterns[i].Resize(64); + if(m_SndFile.PatternSize[i] < 64) + { + // try to save short patterns by inserting a pattern break. + m_SndFile.TryWriteEffect(i, m_SndFile.PatternSize[i] - 1, CMD_PATTERNBREAK, 0, false, CHANNELINDEX_INVALID, false, true); + } + m_SndFile.Patterns[i].Resize(64, false); if (b64 < 5) { wsprintf(s, "WARNING: Pattern %d resized to 64 rows\n", i); @@ -285,6 +292,27 @@ { AddToLog("WARNING: Samples above 31 will be lost when saving as MOD!\n"); } + + // Order list too long? -> remove unnecessary order items first. + if(m_SndFile.Order.GetLengthTailTrimmed() > specs.ordersMax) + { + for(ORDERINDEX nOrd = m_SndFile.Order.GetLengthTailTrimmed() - 1; nOrd > 0; nOrd--) + { + if(m_SndFile.Patterns.IsValidPat(m_SndFile.Order[nOrd]) == false) + { + for(ORDERINDEX nMoveOrd = nOrd; nMoveOrd < m_SndFile.Order.GetLengthTailTrimmed() - 1; nMoveOrd++) + { + m_SndFile.Order[nMoveOrd] = m_SndFile.Order[nMoveOrd + 1]; + } + m_SndFile.Order[m_SndFile.Order.GetLengthTailTrimmed() - 1] = m_SndFile.Order.GetInvalidPatIndex(); + } + } + if(m_SndFile.Order.GetLengthTailTrimmed() > specs.ordersMax) + { + AddToLog("WARNING: Order list has been trimmed!\n"); + } + } + BEGIN_CRITICAL(); m_SndFile.ChangeModTypeTo(nNewType); if (!newTypeIsXM_IT_MPT && (m_SndFile.m_dwSongFlags & SONG_LINEARSLIDES)) @@ -311,7 +339,6 @@ //end rewbs.cutomKeys // Check mod specifications - const CModSpecifications& specs = m_SndFile.GetModSpecifications(); m_SndFile.m_nDefaultTempo = CLAMP(m_SndFile.m_nDefaultTempo, specs.tempoMin, specs.tempoMax); m_SndFile.m_nDefaultSpeed = CLAMP(m_SndFile.m_nDefaultSpeed, specs.speedMin, specs.speedMax); @@ -325,26 +352,6 @@ if(bTrimmedEnvelopes == true) AddToLog("WARNING: Instrument envelopes have been shortened.\n"); - // Order list too long -> remove unnecessary order items first. - if(m_SndFile.Order.GetLengthTailTrimmed() > specs.ordersMax) - { - for(ORDERINDEX nOrd = m_SndFile.Order.GetLengthTailTrimmed() - 1; nOrd >= 0; nOrd--) - { - if(m_SndFile.Patterns.IsValidPat(m_SndFile.Order[nOrd]) == false) - { - for(ORDERINDEX nMoveOrd = nOrd; nMoveOrd < m_SndFile.Order.GetLengthTailTrimmed(); nMoveOrd++) - { - m_SndFile.Order[nMoveOrd] = m_SndFile.Order[nMoveOrd + 1]; - } - } - } - if(m_SndFile.Order.GetLengthTailTrimmed() > specs.ordersMax) - { - AddToLog("WARNING: Order list has been trimmed!"); - } - m_SndFile.Order.resize(specs.ordersMax); - } - SetModified(); ClearPatternUndo(); UpdateAllViews(NULL, HINT_MODTYPE | HINT_MODGENERAL); @@ -1122,13 +1129,14 @@ if ((hCpy) && ((p = (LPSTR)GlobalLock(hCpy)) != NULL)) { PreparePatternUndo(nPattern, 0, 0, m_SndFile.m_nChannels, m_SndFile.PatternSize[nPattern]); - BYTE spdmax = (m_SndFile.m_nType & MOD_TYPE_MOD) ? 0x20 : 0x1F; + TEMPO spdmax = m_SndFile.GetModSpecifications().speedMax; DWORD dwMemSize = GlobalSize(hCpy); MODCOMMAND *m = m_SndFile.Patterns[nPattern]; UINT nrow = dwBeginSel >> 16; UINT ncol = (dwBeginSel & 0xFFFF) >> 3; UINT col; - BOOL bS3M = FALSE, bOk = FALSE; + bool bS3MCommands = false, bOk = false; + MODTYPE origFormat = MOD_TYPE_MOD; UINT len = 0; MODCOMMAND origModCmd; @@ -1147,13 +1155,15 @@ if (!c) goto PasteDone; if ((c == 0x0D) && (len > 3)) { - //if ((p[len-3] == 'I') || (p[len-4] == 'S')) bS3M = TRUE; - // IT? S3M? MPT? - if ((p[len-3] == 'I') || (p[len-4] == 'S') || (p[len-3] == 'P')) bS3M = TRUE; + if(p[len - 3] == 'I') origFormat = MOD_TYPE_IT; + if(p[len - 3] == 'P') origFormat = MOD_TYPE_MPT; + if(p[len - 4] == 'S') origFormat = MOD_TYPE_S3M; + if(p[len - 3] == 'X') origFormat = MOD_TYPE_XM; break; } } - bOk = TRUE; + bS3MCommands = (origFormat & (MOD_TYPE_IT|MOD_TYPE_MPT|MOD_TYPE_S3M)) != 0 ? true : false; + bOk = true; while ((nrow < m_SndFile.PatternSize[nPattern]) && (len + 11 < dwMemSize)) { // Search for column separator @@ -1255,7 +1265,7 @@ m[col].command = 0; if (s[8] != '.') { - LPCSTR psc = (bS3M) ? gszS3mCommands : gszModCommands; + LPCSTR psc = (bS3MCommands) ? gszS3mCommands : gszModCommands; for (UINT i=1; i<MAX_EFFECTS; i++) { if ((s[8] == psc[i]) && (psc[i] != '?')) m[col].command = i; @@ -1283,7 +1293,7 @@ { case CMD_SPEED: case CMD_TEMPO: - if (!bS3M) m[col].command = (m[col].param <= spdmax) ? CMD_SPEED : CMD_TEMPO; + if (!bS3MCommands) m[col].command = (m[col].param <= spdmax) ? CMD_SPEED : CMD_TEMPO; else { if ((m[col].command == CMD_SPEED) && (m[col].param > spdmax)) m[col].param = CMD_TEMPO; else @@ -1297,12 +1307,15 @@ { case CMD_SPEED: case CMD_TEMPO: - if (!bS3M) m[col].command = (m[col].param <= spdmax) ? CMD_SPEED : CMD_TEMPO; + if (!bS3MCommands) m[col].command = (m[col].param <= spdmax) ? CMD_SPEED : CMD_TEMPO; break; } } } } + // convert some commands, if necessary. + if(origFormat != m_SndFile.m_nType) m_SndFile.ConvertCommand(&(m[col]), origFormat, m_SndFile.m_nType); + len += 12; col++; } Modified: trunk/OpenMPT/mptrack/Mptrack.h =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.h 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/mptrack/Mptrack.h 2009-10-23 23:12:00 UTC (rev 403) @@ -406,9 +406,6 @@ /////////////////////////////////////////////////// // Tables -#define MAX_EFFECTS 37 //rewbs.smoothVST & rewbs.velocity: increased from 32. Wonder what this will break... - //+1 for eric's multiplier -#define MAX_VOLCMDS 16 //rewbs.voloff & rewbs.velocity: increased from 14 extern const BYTE gEffectColors[MAX_EFFECTS]; extern const LPCSTR szNoteNames[12]; @@ -422,8 +419,8 @@ STATIC_ASSERT(ARRAYELEMCOUNT(szSpecialNoteShortDesc) == ARRAYELEMCOUNT(szSpecialNoteNames)); const LPCSTR szHexChar = "0123456789ABCDEF"; -const LPCSTR gszModCommands = " 0123456789ABCDRFFTE???GHK?YXPLZ\\:#"; //rewbs.smoothVST: added last \ (written as \\); rewbs.velocity: added last : -const LPCSTR gszS3mCommands = " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z\\:#"; //rewbs.smoothVST: added last \ (written as \\); rewbs.velocity: added last : +const LPCSTR gszModCommands = " 0123456789ABCDRFFTE???GHK?YXPLZ\\:#??"; //rewbs.smoothVST: added last \ (written as \\); rewbs.velocity: added last : +const LPCSTR gszS3mCommands = " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z\\:#??"; //rewbs.smoothVST: added last \ (written as \\); rewbs.velocity: added last : const LPCSTR gszVolCommands = " vpcdabuhlrgfe:o"; //rewbs.velocity: added last : ; rewbs.volOff added last o // Defined in load_mid.cpp Modified: trunk/OpenMPT/mptrack/View_ins.h =================================================================== --- trunk/OpenMPT/mptrack/View_ins.h 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/mptrack/View_ins.h 2009-10-23 23:12:00 UTC (rev 403) @@ -17,7 +17,8 @@ POINT m_ptMenu; RECT m_rcClient; bool m_baPlayingNote[128]; //rewbs.instViewNNA - UINT m_nInstrument, m_nEnv, m_nDragItem, m_nBtnMouseOver, m_nPlayingChannel; + INSTRUMENTINDEX m_nInstrument; + UINT m_nEnv, m_nDragItem, m_nBtnMouseOver, m_nPlayingChannel; DWORD m_dwStatus; DWORD m_NcButtonState[ENV_LEFTBAR_BUTTONS]; DWORD m_dwNotifyPos[MAX_CHANNELS]; Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -3827,8 +3827,7 @@ if ((pSndFile->m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM)) && ((p->command == CMD_SPEED) || (p->command == CMD_TEMPO))) { - UINT maxspd = (pSndFile->m_nType & MOD_TYPE_XM) ? 0x1F : 0x20; - p->command = (p->param <= maxspd) ? CMD_SPEED : CMD_TEMPO; + p->command = (p->param <= pSndFile->GetModSpecifications().speedMax) ? CMD_SPEED : CMD_TEMPO; } } @@ -3886,8 +3885,7 @@ if ((pSndFile->m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM)) && ((p->command == CMD_SPEED) || (p->command == CMD_TEMPO))) { - UINT maxspd = (pSndFile->m_nType & MOD_TYPE_XM) ? 0x1F : 0x20; - p->command = (p->param <= maxspd) ? CMD_SPEED : CMD_TEMPO; + p->command = (p->param <= pSndFile->GetModSpecifications().speedMax) ? CMD_SPEED : CMD_TEMPO; } } Modified: trunk/OpenMPT/soundlib/LOAD_AMF.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-10-23 23:12:00 UTC (rev 403) @@ -311,7 +311,7 @@ for (UINT iOrd=0; iOrd < pfh->numorders; iOrd++) { Order[iOrd] = iOrd; - Patterns[iOrd].Resize(64); + Patterns[iOrd].Resize(64, false); if (pfh->version >= 14) { Patterns[iOrd].Resize(LittleEndianW(*(USHORT *)(lpStream+dwMemPos))); Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -664,7 +664,7 @@ ASSERT_CAN_READ(4); memcpy(&id,lpStream+streamPos,sizeof(DWORD)); if(id > MAX_PATTERN_ROWS) return false; - Patterns[npat].Resize(id); + Patterns[npat].Resize(id, false); streamPos += sizeof(DWORD); // Try to allocate & read only sized patterns Modified: trunk/OpenMPT/soundlib/Load_mdl.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -291,7 +291,7 @@ } else { pdata = (const WORD *)(lpStream + dwPos); - Patterns[i].Resize(64); + Patterns[i].Resize(64, false); if (m_nChannels < 32) m_nChannels = 32; dwPos += 2*32; ch = 32; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -3733,4 +3733,11 @@ if(!CSoundFile::GetModSpecifications(nNewType).HasNote(m->note)) m->note = NOTE_NONE; + + // ensure the commands really exist in this format + if(CSoundFile::GetModSpecifications(nNewType).HasCommand(m->command) == false) + m->command = CMD_NONE; + if(CSoundFile::GetModSpecifications(nNewType).HasVolCommand(m->volcmd) == false) + m->volcmd = CMD_NONE; + } \ No newline at end of file Modified: trunk/OpenMPT/soundlib/mod_specifications.cpp =================================================================== --- trunk/OpenMPT/soundlib/mod_specifications.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/mod_specifications.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -21,4 +21,20 @@ return false; } +bool CModSpecifications::HasVolCommand(MODCOMMAND::VOLCMD volcmd) const +//--------------------------------------------------------------------- +{ + if(volcmd >= MAX_VOLCMDS) return false; + if(volcommands[volcmd] == '?') return false; + return true; +} +bool CModSpecifications::HasCommand(MODCOMMAND::COMMAND cmd) const +//---------------------------------------------------------------- +{ + if(cmd >= MAX_EFFECTS) return false; + if(commands[cmd] == '?') return false; + return true; +} + + Modified: trunk/OpenMPT/soundlib/mod_specifications.h =================================================================== --- trunk/OpenMPT/soundlib/mod_specifications.h 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/mod_specifications.h 2009-10-23 23:12:00 UTC (rev 403) @@ -12,6 +12,8 @@ { // Return true if format supports given note. bool HasNote(MODCOMMAND::NOTE note) const; + bool HasVolCommand(MODCOMMAND::VOLCMD volcmd) const; + bool HasCommand(MODCOMMAND::COMMAND cmd) const; //NOTE: If changing order, update all initializations below. char fileExtension[6]; // File extension without dot. @@ -37,6 +39,8 @@ UINT speedMax; // Maximum ticks per frame bool hasComments; // True if format has a comments field UINT envelopePointsMax; // Maximum number of points of each envelope + char commands[MAX_EFFECTS + 1]; // An array holding all commands this format supports; commands that are not supported are marked with "?" + char volcommands[MAX_VOLCMDS + 1]; // dito, but for volume column }; @@ -73,6 +77,8 @@ 255, //Max Speed true, //Has song comments 240, //Envelope point count + " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z\\:#", // Supported Effects + " vpcdabuhlrgfe:o", // Supported Volume Column commands }; @@ -104,6 +110,8 @@ 31, //Max Speed false, //No song comments 0, //No instrument envelopes + " 0123456789ABCD?FF?E???????????????", // Supported Effects + " ???????????????", // Supported Volume Column commands }; // MOD with MPT extensions. @@ -133,6 +141,8 @@ 31, //Max Speed false, //No song comments 0, //No instrument envelopes + " 0123456789ABCD?FF?E???????????????", // Supported Effects + " ???????????????", // Supported Volume Column commands }; const CModSpecifications xm = @@ -161,6 +171,8 @@ 31, //Max Speed false, //No song comments 12, //Envelope point count + " 0123456789ABCDRFFTE???GHK?YXPLZ\\:#", // Supported Effects + " vpcdabuhlrg????", // Supported Volume Column commands }; // XM with MPT extensions @@ -190,6 +202,8 @@ 31, //Max Speed true, //Has song comments 12, //Envelope point count + " 0123456789ABCDRFFTE???GHK?YXPLZ\\:#", // Supported Effects + " vpcdabuhlrgfe:o", // Supported Volume Column commands }; const CModSpecifications s3m = @@ -217,6 +231,8 @@ 255, //Max Speed false, //No song comments 0, //No instrument envelopes + " JFEGHLKRXODB?CQATI?SMNVW?U????????", // Supported Effects + " vp?????????????", // Supported Volume Column commands }; // S3M with MPT extensions @@ -246,6 +262,8 @@ 255, //Max Speed false, //No song comments 0, //No instrument envelopes + " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z\\:#", // Supported Effects + " vp?????????????", // Supported Volume Column commands }; const CModSpecifications it = @@ -274,6 +292,8 @@ 255, //Max Speed true, //Has song comments 25, //Envelope point count + " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z???", // Supported Effects + " vpcdab?h??gfe??", // Supported Volume Column commands }; const CModSpecifications itEx = @@ -302,6 +322,8 @@ 255, //Max Speed true, //Has song comments 25, //Envelope point count + " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z\\:#", // Supported Effects + " vpcdab?h??gfe:o", // Supported Volume Column commands }; } //namespace ModSpecs Modified: trunk/OpenMPT/soundlib/modcommand.h =================================================================== --- trunk/OpenMPT/soundlib/modcommand.h 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/modcommand.h 2009-10-23 23:12:00 UTC (rev 403) @@ -90,6 +90,7 @@ #define VOLCMD_PORTADOWN 13 #define VOLCMD_VELOCITY 14 //rewbs.velocity #define VOLCMD_OFFSET 15 //rewbs.volOff +#define MAX_VOLCMDS 16 // Effect column commands @@ -130,6 +131,7 @@ #define CMD_XPARAM 34 // -> CODE#0010 -> DESC="add extended parameter mechanism to pattern effects" -! NEW_FEATURE#0010 #define CMD_NOTESLIDEUP 35 // IMF Gxy #define CMD_NOTESLIDEDOWN 36 // IMF Hxy +#define MAX_EFFECTS 37 #endif Modified: trunk/OpenMPT/soundlib/pattern.cpp =================================================================== --- trunk/OpenMPT/soundlib/pattern.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/pattern.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -18,7 +18,7 @@ bool CPattern::Resize(const ROWINDEX newRowCount, const bool showDataLossWarning) -//------------------------------------------- +//------------------------------------------------------------------------------- { if(m_ModCommands == NULL) { @@ -69,7 +69,7 @@ { END_CRITICAL(); rModDoc.EndWaitCursor(); - if (CMainFrame::GetMainFrame()->MessageBox("Data at the end of the pattern will be lost.\nDo you want to continue", + if (CMainFrame::GetMainFrame()->MessageBox("Data at the end of the pattern will be lost.\nDo you want to continue?", "Shrink Pattern", MB_YESNO|MB_ICONQUESTION) == IDYES) bOk = TRUE; rModDoc.BeginWaitCursor(); BEGIN_CRITICAL(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-10-25 22:17:22
|
Revision: 406 http://modplug.svn.sourceforge.net/modplug/?rev=406&view=rev Author: relabsoluness Date: 2009-10-25 22:17:12 +0000 (Sun, 25 Oct 2009) Log Message: ----------- [New] Sequence editor: Can now copy/cut/paste order selections. [Fix] Autosave: 'Modified since last autosave'-flag wasn't updated when document was set modified using ThreadSafeSetModified. [Mod] VC2003 build: Added command line optimization options to zlib project. [Ref] Minor cleanup. Modified Paths: -------------- trunk/OpenMPT/mptrack/CreditStatic.cpp trunk/OpenMPT/mptrack/Ctrl_pat.h trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/soundlib/ModSequence.cpp trunk/OpenMPT/soundlib/ModSequence.h trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/zlib/contrib/vstudio/vc7/zlibstat.vcproj Modified: trunk/OpenMPT/mptrack/CreditStatic.cpp =================================================================== --- trunk/OpenMPT/mptrack/CreditStatic.cpp 2009-10-24 19:05:56 UTC (rev 405) +++ trunk/OpenMPT/mptrack/CreditStatic.cpp 2009-10-25 22:17:12 UTC (rev 406) @@ -226,6 +226,7 @@ BOOL CCreditStatic::OnEraseBkgnd(CDC* pDC) { + UNREFERENCED_PARAMETER(pDC); return TRUE; // return CStatic::OnEraseBkgnd(pDC); @@ -539,8 +540,8 @@ CFont* pOldFont = NULL; BOOL bSuccess = FALSE; - BOOL bUnderline; - BOOL bItalic; + BYTE bUnderline; + BYTE bItalic; int rmcode = 0; if (!m_szWork.IsEmpty()) { @@ -668,7 +669,7 @@ } CRect r(m_ClientRect); r.top = r.bottom-m_nClip; - int x = memDC.DrawText((const char *)m_szWork,m_szWork.GetLength()-rmcode,&r,DT_TOP|DT_CENTER| + memDC.DrawText((const char *)m_szWork,m_szWork.GetLength()-rmcode,&r,DT_TOP|DT_CENTER| DT_NOPREFIX | DT_SINGLELINE); m_bDrawText=FALSE; } @@ -737,8 +738,8 @@ BOOL bSuccess = FALSE; BOOL bIsBitmap = FALSE; - BOOL bUnderline; - BOOL bItalic; + BYTE bUnderline; + BYTE bItalic; int rmcode = 0; CBitmap bitmap; @@ -839,7 +840,7 @@ CSize size; if(m_szWork.GetLength()-rmcode != 0) { - int x = memDC.DrawText((const char *)m_szWork,m_szWork.GetLength()-rmcode,&r,DT_TOP|DT_CENTER| + memDC.DrawText((const char *)m_szWork,m_szWork.GetLength()-rmcode,&r,DT_TOP|DT_CENTER| DT_NOPREFIX | DT_SINGLELINE); size = memDC.GetTextExtent((LPCTSTR)m_szWork,m_szWork.GetLength()-rmcode); } @@ -923,7 +924,7 @@ LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; pLP->palVersion = 0x300; - pLP->palNumEntries = nColors; + pLP->palNumEntries = (WORD)nColors; for( int i=0; i < nColors; i++) { Modified: trunk/OpenMPT/mptrack/Ctrl_pat.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-10-24 19:05:56 UTC (rev 405) +++ trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-10-25 22:17:12 UTC (rev 406) @@ -9,6 +9,7 @@ { ORDERINDEX nOrdLo; ORDERINDEX nOrdHi; + ORDERINDEX GetSelCount() const {return nOrdHi - nOrdLo + 1;} }; //=========================== @@ -84,7 +85,11 @@ // Set given sqeuence and update orderlist display. void SelectSequence(const SEQUENCEINDEX nSeq); -public: + // Clipboard. + void OnEditCopy(); + void OnEditCut(); + void OnEditPaste(); + //{{AFX_VIRTUAL(COrderList) virtual BOOL PreTranslateMessage(MSG *pMsg); virtual void UpdateView(DWORD dwHintMask=0, CObject *pObj=NULL); @@ -119,6 +124,7 @@ afx_msg LRESULT OnDragonDropping(WPARAM bDoDrop, LPARAM lParam); afx_msg LRESULT OnHelpHitTest(WPARAM, LPARAM lParam); afx_msg void OnSelectSequence(UINT nid); + afx_msg LRESULT OnCustomKeyMsg(WPARAM, LPARAM); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-10-24 19:05:56 UTC (rev 405) +++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-10-25 22:17:12 UTC (rev 406) @@ -57,6 +57,7 @@ ON_COMMAND_RANGE(ID_SEQUENCE_ITEM, ID_SEQUENCE_ITEM + MAX_SEQUENCES + 1, OnSelectSequence) ON_MESSAGE(WM_MOD_DRAGONDROPPING, OnDragonDropping) ON_MESSAGE(WM_HELPHITTEST, OnHelpHitTest) + ON_MESSAGE(WM_MOD_KEYCOMMAND, OnCustomKeyMsg) //}}AFX_MSG_MAP END_MESSAGE_MAP() @@ -455,6 +456,169 @@ } +static const char szClipboardOrdersHdr[] = "OpenMPT %3s\x0D\x0A"; +static const char szClipboardOrdCountFieldHdr[] = "OrdNum: %u\x0D\x0A"; +static const char szClipboardOrdersFieldHdr[] = "OrdLst: "; + + +void COrderList::OnEditCut() +//-------------------------- +{ + OnEditCopy(); + OnDeleteOrder(); +} + + +void COrderList::OnEditPaste() +//---------------------------- +{ + CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); + CSoundFile* pSf = m_pModDoc->GetSoundFile(); + if (!pMainFrm) + return; + BeginWaitCursor(); + if (pMainFrm->OpenClipboard()) + { + HGLOBAL hCpy = ::GetClipboardData(CF_TEXT); + LPCSTR p; + + if ((hCpy) && ((p = (LPCSTR)GlobalLock(hCpy)) != NULL)) + { + const DWORD dwMemSize = GlobalSize(hCpy); + + if (dwMemSize > sizeof(szClipboardOrdersHdr) && + memcmp(p, "OpenMPT ", 8) == 0 && + memcmp(p + 11, "\x0D\x0A", 2) == 0) + { + char buf[8]; + p += sizeof(szClipboardOrdersHdr) - 1; + std::istrstream iStrm(p, dwMemSize - sizeof(szClipboardOrdersHdr) + 1); + ORDERINDEX nCount = 0; + std::vector<PATTERNINDEX> vecPat; + while (iStrm.get(buf, sizeof(buf), '\n')) + { + if (memcmp(buf, "OrdNum:", 8) == 0) // Read expected order count. + iStrm >> nCount; + else if (memcmp(buf, "OrdLst:", 8) != 0) + { // Unrecognized data -> skip line. + iStrm.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); + continue; + } + else // Read orders. + { + LimitMax(nCount, pSf->GetModSpecifications().ordersMax); + vecPat.reserve(nCount); + char bufItem[16]; + while (iStrm.peek() >= 32 && iStrm.getline(bufItem, sizeof(bufItem), ' ')) + { + if (vecPat.size() >= pSf->GetModSpecifications().ordersMax) + break; + if (!(isdigit(bufItem[0]) || bufItem[0] == '+' || bufItem[0] == '-')) + continue; + PATTERNINDEX nPat = pSf->Order.GetInvalidPatIndex(); + if (bufItem[0] == '+') + nPat = pSf->Order.GetIgnoreIndex(); + else if (isdigit(bufItem[0])) + { + nPat = ConvertStrTo<PATTERNINDEX>(bufItem); + if (nPat >= pSf->GetModSpecifications().patternsMax) + nPat = pSf->Order.GetInvalidPatIndex(); + } + vecPat.push_back(nPat); + } + nCount = pSf->Order.Insert(m_nScrollPos, (ORDERINDEX)vecPat.size()); + for (ORDERINDEX nOrd = 0; nOrd < nCount; nOrd++) + pSf->Order[m_nScrollPos + nOrd] = vecPat[nOrd]; + } + m_pModDoc->SetModified(); + m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, NULL); + } + } + GlobalUnlock(hCpy); + } + CloseClipboard(); + } + EndWaitCursor(); +} + + +void COrderList::OnEditCopy() +//--------------------------- +{ + CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); + if ((!pMainFrm)) return; + + const ORD_SELECTION ordsel = GetCurSel(false); + + DWORD dwMemSize; + HGLOBAL hCpy; + + BeginWaitCursor(); + dwMemSize = sizeof(szClipboardOrdersHdr) + sizeof(szClipboardOrdersFieldHdr) + sizeof(szClipboardOrdCountFieldHdr); + dwMemSize += ordsel.GetSelCount() * 6 + 8; + if ((pMainFrm->OpenClipboard()) && ((hCpy = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, dwMemSize))!=NULL)) + { + LPCSTR pszFormatName; + EmptyClipboard(); + switch(m_pModDoc->GetSoundFile()->GetType()) + { + case MOD_TYPE_S3M: pszFormatName = "S3M"; break; + case MOD_TYPE_XM: pszFormatName = "XM"; break; + case MOD_TYPE_IT: pszFormatName = "IT"; break; + case MOD_TYPE_MPT: pszFormatName = "MPT"; break; + default: pszFormatName = "MOD"; break; + } + LPSTR p = (LPSTR)GlobalLock(hCpy); + if (p) + { + const ModSequence& seq = m_pModDoc->GetSoundFile()->Order; + wsprintf(p, szClipboardOrdersHdr, pszFormatName); + p += strlen(p); + wsprintf(p, szClipboardOrdCountFieldHdr, ordsel.GetSelCount()); + strcat(p, szClipboardOrdersFieldHdr); + p += strlen(p); + for(ORDERINDEX i = ordsel.nOrdLo; i <= ordsel.nOrdHi; i++) + { + std::string str; + if (seq[i] == seq.GetInvalidPatIndex()) + str = "-"; + else if (seq[i] == seq.GetIgnoreIndex()) + str = "+"; + else + str = Stringify(seq[i]); + memcpy(p, str.c_str(), str.size()); + p += str.size(); + *p++ = ' '; + } + *p++ = 0x0D; + *p++ = 0x0A; + *p = 0; + } + GlobalUnlock(hCpy); + SetClipboardData(CF_TEXT, (HANDLE) hCpy); + CloseClipboard(); + } + EndWaitCursor(); +} + + +LRESULT COrderList::OnCustomKeyMsg(WPARAM wParam, LPARAM) +//------------------------------------------------------- +{ + if (wParam == kcNull) + return 0; + + switch(wParam) + { + case kcEditCopy: OnEditCopy(); return wParam; + case kcEditCut: OnEditCut(); return wParam; + case kcEditPaste: OnEditPaste(); return wParam; + } + + return 0; +} + + void COrderList::UpdateView(DWORD dwHintMask, CObject *pObj) //---------------------------------------------------------- { @@ -604,6 +768,7 @@ CWnd::OnSetFocus(pWnd); InvalidateSelection(); UpdateInfoText(); + CMainFrame::GetMainFrame()->m_pOrderlistHasFocus = this; } @@ -613,6 +778,7 @@ CWnd::OnKillFocus(pWnd); InvalidateSelection(); m_bShift = FALSE; + CMainFrame::GetMainFrame()->m_pOrderlistHasFocus = nullptr; } @@ -998,10 +1164,8 @@ // remove selection m_nScrollPos2nd = ORDERINDEX_INVALID; - for(int i = 0; i <= (selection.nOrdHi - selection.nOrdLo); i++) - { - m_pModDoc->RemoveOrder(pSndFile->Order.GetCurrentSequenceIndex(), selection.nOrdLo); - } + pSndFile->Order.Remove(selection.nOrdLo, selection.nOrdHi); + InvalidateRect(NULL, FALSE); m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this); Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2009-10-24 19:05:56 UTC (rev 405) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2009-10-25 22:17:12 UTC (rev 406) @@ -289,6 +289,7 @@ { m_bModTreeHasFocus = false; //rewbs.customKeys m_pNoteMapHasFocus = NULL; //rewbs.customKeys + m_pOrderlistHasFocus = nullptr; m_bOptionsLocked = false; //rewbs.customKeys m_pJustModifiedDoc = NULL; @@ -2523,7 +2524,7 @@ pModDoc->m_bModifiedChanged=false; }*/ if (m_pJustModifiedDoc) { - m_pJustModifiedDoc->SetModifiedFlag(true); + m_pJustModifiedDoc->SetModified(true); m_pJustModifiedDoc = NULL; } @@ -2720,7 +2721,7 @@ // case ID_NETLINK_UT: pszURL = "http://www.united-trackers.org"; break; // case ID_NETLINK_OSMUSIC: pszURL = "http://www.osmusic.net/"; break; // case ID_NETLINK_HANDBOOK: pszURL = "http://www.modplug.com/mods/handbook/handbook.htm"; break; - case ID_NETLINK_MPTFR: pszURL = "http://mpt.new.fr/"; break; +// case ID_NETLINK_MPTFR: pszURL = "http://mpt.new.fr/"; break; case ID_NETLINK_FORUMS: pszURL = "http://www.lpchip.com/modplug"; break; case ID_NETLINK_PLUGINS: pszURL = "http://www.kvraudio.com"; break; case ID_NETLINK_MODARCHIVE: pszURL = "http://modarchive.org/"; break; @@ -2828,6 +2829,8 @@ return m_wndTree.PostMessageToModTree(WM_MOD_KEYCOMMAND, wParam, lParam); if (m_pNoteMapHasFocus) return m_pNoteMapHasFocus->PostMessage(WM_MOD_KEYCOMMAND, wParam, lParam); + if (m_pOrderlistHasFocus) + return m_pOrderlistHasFocus->PostMessage(WM_MOD_KEYCOMMAND, wParam, lParam); //Else send it to the active view CView* pView = GetActiveView(); Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2009-10-24 19:05:56 UTC (rev 405) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2009-10-25 22:17:12 UTC (rev 406) @@ -544,6 +544,7 @@ static CInputHandler* GetInputHandler() { return m_InputHandler; } //rewbs.customKeys bool m_bModTreeHasFocus; //rewbs.customKeys CWnd *m_pNoteMapHasFocus; //rewbs.customKeys + CWnd* m_pOrderlistHasFocus; long GetSampleRate(); //rewbs.VSTTimeInfo long GetTotalSampleCount(); //rewbs.VSTTimeInfo double GetApproxBPM(); //rewbs.VSTTimeInfo Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-24 19:05:56 UTC (rev 405) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-25 22:17:12 UTC (rev 406) @@ -149,7 +149,7 @@ 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); + m_SndFile.Order.resize(min(MAX_ORDERS, m_SndFile.GetModSpecifications().ordersMax)); theApp.GetDefaultMidiMacro(&m_SndFile.m_MidiCfg); ReinitRecordState(); @@ -1105,22 +1105,22 @@ return true; } -bool CModDoc::IsChannelRecord1(CHANNELINDEX channel) -//-------------------------------------------------- + +bool CModDoc::IsChannelRecord1(CHANNELINDEX channel) const +//-------------------------------------------------------- { - UINT m = 1 << (channel&7); - return (MultiRecordMask[channel>>3] & m) ? true : false; + return m_bsMultiRecordMask[channel]; } -bool CModDoc::IsChannelRecord2(CHANNELINDEX channel) -//-------------------------------------------------- + +bool CModDoc::IsChannelRecord2(CHANNELINDEX channel) const +//-------------------------------------------------------- { - UINT m = 1 << (channel&7); - return (MultiSplitRecordMask[channel>>3] & m) ? true : false; + return m_bsMultiSplitRecordMask[channel]; } -BYTE CModDoc::IsChannelRecord(CHANNELINDEX channel) -//------------------------------------------------- +BYTE CModDoc::IsChannelRecord(CHANNELINDEX channel) const +//------------------------------------------------------- { if(IsChannelRecord1(channel)) return 1; if(IsChannelRecord2(channel)) return 2; @@ -1130,38 +1130,46 @@ void CModDoc::Record1Channel(CHANNELINDEX channel, bool select) //------------------------------------------------------------- { - UINT m = 1 << (channel&7); - - if(!select){ - if(MultiRecordMask[channel>>3] & m) MultiRecordMask[channel>>3] ^= m; - if(MultiSplitRecordMask[channel>>3] & m) MultiSplitRecordMask[channel>>3] ^= m; + if (!select) + { + m_bsMultiRecordMask.reset(channel); + m_bsMultiSplitRecordMask.reset(channel); } - else{ - MultiRecordMask[channel>>3] ^= m; - if(MultiSplitRecordMask[channel>>3] & m) MultiSplitRecordMask[channel>>3] ^= m; + else + { + m_bsMultiRecordMask.flip(channel); + m_bsMultiSplitRecordMask.reset(channel); } } void CModDoc::Record2Channel(CHANNELINDEX channel, bool select) //------------------------------------------------------------- { - UINT m = 1 << (channel&7); - - if(!select){ - if(MultiRecordMask[channel>>3] & m) MultiRecordMask[channel>>3] ^= m; - if(MultiSplitRecordMask[channel>>3] & m) MultiSplitRecordMask[channel>>3] ^= m; + if (!select) + { + m_bsMultiRecordMask.reset(channel); + m_bsMultiSplitRecordMask.reset(channel); } - else{ - MultiSplitRecordMask[channel>>3] ^= m; - if(MultiRecordMask[channel>>3] & m) MultiRecordMask[channel>>3] ^= m; + else + { + m_bsMultiSplitRecordMask.flip(channel); + m_bsMultiRecordMask.reset(channel); } } void CModDoc::ReinitRecordState(bool unselect) //-------------------------------------------- { - memset(MultiRecordMask, unselect ? 0 : 0xff, sizeof(MultiRecordMask)); - memset(MultiSplitRecordMask, unselect ? 0 : 0xff, sizeof(MultiSplitRecordMask)); + if (unselect) + { + m_bsMultiRecordMask.reset(); + m_bsMultiSplitRecordMask.reset(); + } + else + { + m_bsMultiRecordMask.set(); + m_bsMultiSplitRecordMask.set(); + } } // -! NEW_FEATURE#0015 Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-10-24 19:05:56 UTC (rev 405) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-10-25 22:17:12 UTC (rev 406) @@ -38,7 +38,7 @@ #define HINT_SPEEDCHANGE 0x40000 //rewbs.envRowGrid #define HINT_SEQNAMES 0x80000 #define HINT_MAXHINTFLAG HINT_SEQNAMES -//Bits 0-18 are reserved. +//Bits 0-19 are reserved. #define HINT_MASK_FLAGS (2*HINT_MAXHINTFLAG - 1) //When applied to hint parameter, should give the flag part. #define HINT_MASK_ITEM (~HINT_MASK_FLAGS) //To nullify update hintbits from hint parameter. #define HintFlagPart(x) ((x) & HINT_MASK_FLAGS) @@ -136,8 +136,8 @@ // -> CODE#0015 // -> DESC="channels management dlg" - BYTE MultiRecordMask[(MAX_CHANNELS+7)/8]; - BYTE MultiSplitRecordMask[(MAX_CHANNELS+7)/8]; + std::bitset<MAX_BASECHANNELS> m_bsMultiRecordMask; + std::bitset<MAX_BASECHANNELS> m_bsMultiSplitRecordMask; // -! NEW_FEATURE#0015 protected: // create from serialization only @@ -227,9 +227,9 @@ // -> DESC="channels management dlg" bool NoFxChannel(CHANNELINDEX nChn, bool bNoFx, bool updateMix = true); bool IsChannelNoFx(CHANNELINDEX nChn) const; - bool IsChannelRecord1(CHANNELINDEX channel); - bool IsChannelRecord2(CHANNELINDEX channel); - BYTE IsChannelRecord(CHANNELINDEX channel); + bool IsChannelRecord1(CHANNELINDEX channel) const; + bool IsChannelRecord2(CHANNELINDEX channel) const; + BYTE IsChannelRecord(CHANNELINDEX channel) const; void Record1Channel(CHANNELINDEX channel, bool select = true); void Record2Channel(CHANNELINDEX channel, bool select = true); void ReinitRecordState(bool unselect = true); Modified: trunk/OpenMPT/soundlib/ModSequence.cpp =================================================================== --- trunk/OpenMPT/soundlib/ModSequence.cpp 2009-10-24 19:05:56 UTC (rev 405) +++ trunk/OpenMPT/soundlib/ModSequence.cpp 2009-10-25 22:17:12 UTC (rev 406) @@ -137,6 +137,47 @@ } +void ModSequence::Remove(ORDERINDEX nPosBegin, ORDERINDEX nPosEnd) +//---------------------------------------------------------------- +{ + const ORDERINDEX nLengthTt = GetLengthTailTrimmed(); + if (nPosEnd < nPosBegin || nPosEnd >= nLengthTt) + return; + const ORDERINDEX nMoveCount = nLengthTt - (nPosEnd + 1); + // Move orders left. + if (nMoveCount > 0) + memmove(m_pArray + nPosBegin, m_pArray + nPosEnd + 1, sizeof(PATTERNINDEX) * nMoveCount); + // Clear tail orders. + std::fill(m_pArray + nPosBegin + nMoveCount, m_pArray + nLengthTt, GetInvalidPatIndex()); +} + + +ORDERINDEX ModSequence::Insert(ORDERINDEX nPos, ORDERINDEX nCount, PATTERNINDEX nFill) +//------------------------------------------------------------------------------------ +{ + if (nPos >= m_pSndFile->GetModSpecifications().ordersMax || nCount == 0) + return (nCount = 0); + const ORDERINDEX nLengthTt = GetLengthTailTrimmed(); + // Limit number of orders to be inserted. + LimitMax(nCount, ORDERINDEX(m_pSndFile->GetModSpecifications().ordersMax - nPos)); + // Calculate new length. + const ORDERINDEX nNewLength = min(nLengthTt + nCount, m_pSndFile->GetModSpecifications().ordersMax); + // Resize if needed. + if (nNewLength > GetLength()) + resize(nNewLength); + // Calculate how many orders would need to be moved(nNeededSpace) and how many can actually + // be moved(nFreeSpace). + const ORDERINDEX nNeededSpace = nLengthTt - nPos; + const ORDERINDEX nFreeSpace = GetLength() - (nPos + nCount); + // Move orders nCount steps right starting from nPos. + if (nPos < nLengthTt) + memmove(m_pArray + nPos + nCount, m_pArray + nPos, min(nFreeSpace, nNeededSpace) * sizeof(PATTERNINDEX)); + // Set nFill to new orders. + std::fill(begin() + nPos, begin() + nPos + nCount, nFill); + return nCount; +} + + void ModSequence::Append(PATTERNINDEX nPat) //----------------------------------------- { @@ -209,8 +250,9 @@ //---------------------------------------------------------------- { if (nSeq == GetCurrentSequenceIndex()) - CopyCacheToStorage(); - return m_Sequences[nSeq]; + return *this; + else + return m_Sequences[nSeq]; } Modified: trunk/OpenMPT/soundlib/ModSequence.h =================================================================== --- trunk/OpenMPT/soundlib/ModSequence.h 2009-10-24 19:05:56 UTC (rev 405) +++ trunk/OpenMPT/soundlib/ModSequence.h 2009-10-25 22:17:12 UTC (rev 406) @@ -37,6 +37,16 @@ void Append() {Append(GetInvalidPatIndex());} // Appends InvalidPatIndex. void Append(PATTERNINDEX nPat); // Appends given patindex. + // Inserts nCount orders starting from nPos using nFill as the pattern index for all inserted orders. + // Sequence will automatically grow if needed and if it can't grow enough, some tail + // orders will be discarded. + // Return: Number of orders inserted. + ORDERINDEX Insert(ORDERINDEX nPos, ORDERINDEX nCount) {return Insert(nPos, nCount, GetInvalidPatIndex());} + ORDERINDEX Insert(ORDERINDEX nPos, ORDERINDEX nCount, PATTERNINDEX nFill); + + // Removes orders from range [nPosBegin, nPosEnd]. + void Remove(ORDERINDEX nPosBegin, ORDERINDEX nPosEnd); + void clear(); void resize(ORDERINDEX nNewSize) {resize(nNewSize, GetInvalidPatIndex());} void resize(ORDERINDEX nNewSize, PATTERNINDEX nFill); Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-10-24 19:05:56 UTC (rev 405) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-10-25 22:17:12 UTC (rev 406) @@ -727,12 +727,12 @@ void WriteInstrumentPropertyForAllInstruments(__int32 code, __int16 size, FILE* f, MODINSTRUMENT* instruments[], UINT nInstruments); void SaveExtendedInstrumentProperties(MODINSTRUMENT *instruments[], UINT nInstruments, FILE* f); void SaveExtendedSongProperties(FILE* f); - void LoadExtendedSongProperties(const MODTYPE modtype, LPCBYTE ptr, const LPCBYTE startpos, const size_t seachlimit, bool* pInterpretMptMade = false); + void LoadExtendedSongProperties(const MODTYPE modtype, LPCBYTE ptr, const LPCBYTE startpos, const size_t seachlimit, bool* pInterpretMptMade = nullptr); // Reads extended instrument properties(XM/IT/MPTM). // If no errors occur and song extension tag is found, returns pointer to the beginning // of the tag, else returns NULL. - LPCBYTE LoadExtendedInstrumentProperties(const LPCBYTE pStart, const LPCBYTE pEnd, bool* pInterpretMptMade = false); + LPCBYTE LoadExtendedInstrumentProperties(const LPCBYTE pStart, const LPCBYTE pEnd, bool* pInterpretMptMade = nullptr); #endif // MODPLUG_NO_FILESAVE // MOD Convert function Modified: trunk/OpenMPT/zlib/contrib/vstudio/vc7/zlibstat.vcproj =================================================================== --- trunk/OpenMPT/zlib/contrib/vstudio/vc7/zlibstat.vcproj 2009-10-24 19:05:56 UTC (rev 405) +++ trunk/OpenMPT/zlib/contrib/vstudio/vc7/zlibstat.vcproj 2009-10-25 22:17:12 UTC (rev 406) @@ -68,6 +68,7 @@ ATLMinimizesCRunTimeLibraryUsage="FALSE"> <Tool Name="VCCLCompilerTool" + AdditionalOptions="/O2 /Ob1" InlineFunctionExpansion="1" AdditionalIncludeDirectories="..\..\..;..\..\masmx86" PreprocessorDefinitions="WIN32;ZLIB_WINAPI" @@ -116,6 +117,7 @@ ATLMinimizesCRunTimeLibraryUsage="FALSE"> <Tool Name="VCCLCompilerTool" + AdditionalOptions="/O2 /Ob1" InlineFunctionExpansion="1" AdditionalIncludeDirectories="..\..\..;..\..\masmx86" PreprocessorDefinitions="WIN32;ZLIB_WINAPI;ASMV;ASMINF" @@ -165,6 +167,7 @@ ATLMinimizesCRunTimeLibraryUsage="FALSE"> <Tool Name="VCCLCompilerTool" + AdditionalOptions="/O2 /Ob1" InlineFunctionExpansion="1" AdditionalIncludeDirectories="..\..\..;..\..\masmx86" PreprocessorDefinitions="WIN32;ZLIB_WINAPI" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-10-30 22:47:59
|
Revision: 407 http://modplug.svn.sourceforge.net/modplug/?rev=407&view=rev Author: saga-games Date: 2009-10-30 22:47:43 +0000 (Fri, 30 Oct 2009) Log Message: ----------- [Fix] VST: When moving around plugins, param control notes are now also updated. [Fix] Mod Conversion: Remove sample vibrato and sustain loops for MOD/S3M [Fix] Mod Conversion: When converting to .MOD, order list won't be too long anymore. [Fix] IT Compatiblity Export: Don't store "extended filter range" flag [Ref] Small code cleanup Modified Paths: -------------- trunk/OpenMPT/mptrack/KeyConfigDlg.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/MoveFXSlotDialog.h trunk/OpenMPT/mptrack/View_gen.cpp trunk/OpenMPT/mptrack/View_gen.h trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_s3m.cpp trunk/OpenMPT/soundlib/Load_stm.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/ModSequence.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/modsmp_ctrl.cpp trunk/OpenMPT/soundlib/modsmp_ctrl.h Modified: trunk/OpenMPT/mptrack/KeyConfigDlg.cpp =================================================================== --- trunk/OpenMPT/mptrack/KeyConfigDlg.cpp 2009-10-25 22:17:12 UTC (rev 406) +++ trunk/OpenMPT/mptrack/KeyConfigDlg.cpp 2009-10-30 22:47:43 UTC (rev 407) @@ -376,7 +376,6 @@ //---------------------------------------- { CommandID nCmd = (CommandID)m_lbnCommandKeys.GetItemData( m_lbnCommandKeys.GetCurSel() ); - int nCat = m_cmbCategory.GetItemData( m_cmbCategory.GetCurSel() ); CString str; //Separator @@ -407,7 +406,6 @@ m_bKeyUp.EnableWindow(TRUE); m_nCurHotKey = nCmd; - BOOL bEnable = FALSE; char s[20]; m_cmbKeyChoice.ResetContent(); Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-25 22:17:12 UTC (rev 406) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-30 22:47:43 UTC (rev 407) @@ -166,7 +166,7 @@ ///////////////////////////// // Converting pattern data - for (UINT nPat = 0; nPat < m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat]) + for (PATTERNINDEX nPat = 0; nPat < m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat]) { MODCOMMAND *m = m_SndFile.Patterns[nPat]; @@ -222,30 +222,46 @@ // Converting instrument / sample / etc. data - // Convert MOD/XM to S3M/IT/MPT - if (oldTypeIsMOD_XM && newTypeIsS3M_IT_MPT) + // Do some sample conversion + for (SAMPLEINDEX nSmp = 1; nSmp <= m_SndFile.m_nSamples; nSmp++) { - for (SAMPLEINDEX i=1; i<=m_SndFile.m_nSamples; i++) + // No Sustain loops for MOD/S3M + if(newTypeIsMOD || newTypeIsS3M) { - m_SndFile.Samples[i].nC5Speed = CSoundFile::TransposeToFrequency(m_SndFile.Samples[i].RelativeTone, m_SndFile.Samples[i].nFineTune); - m_SndFile.Samples[i].RelativeTone = 0; - m_SndFile.Samples[i].nFineTune = 0; + m_SndFile.Samples[nSmp].nSustainStart = m_SndFile.Samples[nSmp].nSustainEnd = 0; } - if (oldTypeIsXM && newTypeIsIT_MPT) m_SndFile.m_dwSongFlags |= SONG_ITCOMPATMODE; - } else - // Convert S3M/IT/MPT to XM - if (oldTypeIsS3M_IT_MPT && newTypeIsXM) - { - for (SAMPLEINDEX i=1; i<=m_SndFile.m_nSamples; i++) + // Transpose to Frequency (MOD/XM to S3M/IT/MPT) + if (oldTypeIsMOD_XM && newTypeIsS3M_IT_MPT) { - CSoundFile::FrequencyToTranspose(&m_SndFile.Samples[i]); - if (!(m_SndFile.Samples[i].uFlags & CHN_PANNING)) m_SndFile.Samples[i].nPan = 128; + m_SndFile.Samples[nSmp].nC5Speed = CSoundFile::TransposeToFrequency(m_SndFile.Samples[nSmp].RelativeTone, m_SndFile.Samples[nSmp].nFineTune); + m_SndFile.Samples[nSmp].RelativeTone = 0; + m_SndFile.Samples[nSmp].nFineTune = 0; } + + // Frequency to Transpose (S3M/IT/MPT to MOD/XM) + if (oldTypeIsS3M_IT_MPT && newTypeIsXM) + { + CSoundFile::FrequencyToTranspose(&m_SndFile.Samples[nSmp]); + if (!(m_SndFile.Samples[nSmp].uFlags & CHN_PANNING)) m_SndFile.Samples[nSmp].nPan = 128; + } + } + + // No Vibrato for MOD/S3M + if(newTypeIsMOD || newTypeIsS3M) + { + ctrlSmp::ResetSamples(m_SndFile, ctrlSmp::SmpResetVibrato); + } + + if (oldTypeIsXM && newTypeIsIT_MPT) m_SndFile.m_dwSongFlags |= SONG_ITCOMPATMODE; + + // Convert IT/MPT to XM (instruments) + if (oldTypeIsIT_MPT && newTypeIsXM) + { bool bBrokenNoteMap = false, bBrokenSustainLoop = false; - for (INSTRUMENTINDEX j = 1; j <= m_SndFile.m_nInstruments; j++) + for(INSTRUMENTINDEX nIns = 1; nIns <= m_SndFile.m_nInstruments; nIns++) { - MODINSTRUMENT *pIns = m_SndFile.Instruments[j]; + MODINSTRUMENT *pIns = m_SndFile.Instruments[nIns]; if (pIns) { for (UINT k = 0; k < NOTE_MAX; k++) @@ -285,12 +301,12 @@ m_SndFile.m_nSamplePreAmp = 48; m_SndFile.m_nVSTiVolume = 48; AddToLog("WARNING: Default speed, tempo and global volume will be lost.\n"); - } - // Too many samples? - if (newTypeIsMOD && (m_SndFile.m_nSamples > 31)) - { - AddToLog("WARNING: Samples above 31 will be lost when saving as MOD!\n"); + // Too many samples? + if(m_SndFile.m_nSamples > 31) + { + AddToLog("WARNING: Samples above 31 will be lost when saving as MOD!\n"); + } } // Order list too long? -> remove unnecessary order items first. Modified: trunk/OpenMPT/mptrack/MoveFXSlotDialog.h =================================================================== --- trunk/OpenMPT/mptrack/MoveFXSlotDialog.h 2009-10-25 22:17:12 UTC (rev 406) +++ trunk/OpenMPT/mptrack/MoveFXSlotDialog.h 2009-10-30 22:47:43 UTC (rev 407) @@ -11,7 +11,7 @@ CMoveFXSlotDialog(CWnd* pParent = NULL); // standard constructor virtual ~CMoveFXSlotDialog(); void SetupMove(UINT currentSlot, CArray<UINT, UINT> &emptySlots); - UINT m_nToSlot; + PLUGINDEX m_nToSlot; Modified: trunk/OpenMPT/mptrack/View_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_gen.cpp 2009-10-25 22:17:12 UTC (rev 406) +++ trunk/OpenMPT/mptrack/View_gen.cpp 2009-10-30 22:47:43 UTC (rev 407) @@ -1314,8 +1314,8 @@ } -bool CViewGlobals::MovePlug(UINT src, UINT dest) -//---------------------------------------------- +bool CViewGlobals::MovePlug(PLUGINDEX src, PLUGINDEX dest) +//-------------------------------------------------------- { //AfxMessageBox("Moving %d to %d", src, dest); CModDoc *pModDoc = GetDocument(); @@ -1363,6 +1363,17 @@ } } + // Update patterns (param control notes) + for (PATTERNINDEX nPat = 0; nPat < pSndFile->Patterns.Size(); nPat++) if (pSndFile->Patterns[nPat]) + { + MODCOMMAND *m = pSndFile->Patterns[nPat]; + for (UINT len = pSndFile->PatternSize[nPat] * pSndFile->m_nChannels; len; m++, len--) + { + if((m->note == NOTE_PC || m->note == NOTE_PCS) && m->instr == src + 1) + m->instr = dest + 1; + } + } + END_CRITICAL(); pModDoc->SetModified(); @@ -1405,7 +1416,7 @@ //possible mem leak here... } - for (int nSlot=MAX_MIXPLUGINS-1; nSlot>(int)m_nCurrentPlugin; nSlot--) { + for (PLUGINDEX nSlot = MAX_MIXPLUGINS-1; nSlot > (PLUGINDEX)m_nCurrentPlugin; nSlot--) { if (pSndFile->m_MixPlugins[nSlot-1].pMixPlugin) { MovePlug(nSlot-1, nSlot); } Modified: trunk/OpenMPT/mptrack/View_gen.h =================================================================== --- trunk/OpenMPT/mptrack/View_gen.h 2009-10-25 22:17:12 UTC (rev 406) +++ trunk/OpenMPT/mptrack/View_gen.h 2009-10-30 22:47:43 UTC (rev 407) @@ -29,7 +29,8 @@ CSpinButtonCtrl m_spinVolume[4], m_spinPan[4]; CButton m_BtnSelect, m_BtnEdit; int m_nActiveTab, m_nLockCount; - UINT m_nCurrentPlugin, m_nCurrentParam; + PLUGINDEX m_nCurrentPlugin; + UINT m_nCurrentParam; // -> CODE#0002 // -> DESC="VST plugins presets" UINT m_nCurrentPreset; @@ -56,7 +57,7 @@ BOOL IsLocked() const { return (m_nLockCount > 0); } int GetDlgItemIntEx(UINT nID); void BuildEmptySlotList(CArray<UINT, UINT> &emptySlots); - bool MovePlug(UINT src, UINT dest); + bool MovePlug(PLUGINDEX src, PLUGINDEX dest); public: //{{AFX_VIRTUAL(CViewGlobals) Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-10-25 22:17:12 UTC (rev 406) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-10-30 22:47:43 UTC (rev 407) @@ -2499,7 +2499,7 @@ 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; + //if (m_dwSongFlags & SONG_EXFILTERRANGE) header.flags |= 0x1000; header.globalvol = m_nDefaultGlobalVolume >> 1; header.mv = CLAMP(m_nSamplePreAmp, 0, 128); header.speed = m_nDefaultSpeed; Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-10-25 22:17:12 UTC (rev 406) +++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-10-30 22:47:43 UTC (rev 407) @@ -542,8 +542,8 @@ header[0x22] = nbi & 0xFF; header[0x23] = nbi >> 8; nbp = 0; - for (i=0; Patterns[i]; i++) { nbp = i+1; if (nbp >= MAX_PATTERNS) break; } - for (i=0; i<MAX_ORDERS; i++) if ((Order[i] < MAX_PATTERNS) && (Order[i] >= nbp)) nbp = Order[i] + 1; + for (i = 0; Patterns[i]; i++) { nbp = i+1; if (nbp >= MAX_PATTERNS) break; } + for (ORDERINDEX nOrd = 0; nOrd < Order.GetLengthTailTrimmed(); nOrd++) if ((Order[nOrd] < MAX_PATTERNS) && (Order[nOrd] >= nbp)) nbp = Order[nOrd] + 1; header[0x24] = nbp & 0xFF; header[0x25] = nbp >> 8; if (m_dwSongFlags & SONG_FASTVOLSLIDES) header[0x26] |= 0x40; Modified: trunk/OpenMPT/soundlib/Load_stm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_stm.cpp 2009-10-25 22:17:12 UTC (rev 406) +++ trunk/OpenMPT/soundlib/Load_stm.cpp 2009-10-30 22:47:43 UTC (rev 407) @@ -111,7 +111,7 @@ if ((pIns->nLoopEnd > pIns->nLoopStart) && (pIns->nLoopEnd != 0xFFFF)) pIns->uFlags |= CHN_LOOP; } dwMemPos = sizeof(STMHEADER); - for (UINT nOrd=0; nOrd<MAX_ORDERS; nOrd++) if (Order[nOrd] >= 99) Order[nOrd] = 0xFF; + for (UINT nOrd = 0; nOrd < 128; nOrd++) if (Order[nOrd] >= 99) Order[nOrd] = Order.GetInvalidPatIndex(); UINT nPatterns = phdr->numpat; for (UINT nPat=0; nPat<nPatterns; nPat++) { Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-10-25 22:17:12 UTC (rev 406) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-10-30 22:47:43 UTC (rev 407) @@ -759,13 +759,6 @@ xmheader.channels = LittleEndianW(xmheader.channels); xmheader.patterns = 0; - /*for (i=0; i<MAX_ORDERS; i++) { - header.norder++; - if ((Order[i] >= header.patterns) && (Order[i] < MAX_PATTERNS)) header.patterns = Order[i]+1; - }*/ - if(Order.GetLength() < MAX_ORDERS) - Order.resize(MAX_ORDERS); - WORD nOrders = Order.GetLengthTailTrimmed(), nPatterns = 0; xmheader.orders = LittleEndianW(nOrders); xmheader.size = LittleEndian(xmheader.size + nOrders); @@ -783,7 +776,7 @@ xmheader.instruments = LittleEndianW(m_nSamples); xmheader.flags = (m_dwSongFlags & SONG_LINEARSLIDES) ? 0x01 : 0x00; - if (m_dwSongFlags & SONG_EXFILTERRANGE) xmheader.flags |= 0x1000; + if ((m_dwSongFlags & SONG_EXFILTERRANGE) && !bCompatibilityExport) xmheader.flags |= 0x1000; xmheader.flags = LittleEndianW(xmheader.flags); if(bCompatibilityExport) Modified: trunk/OpenMPT/soundlib/ModSequence.cpp =================================================================== --- trunk/OpenMPT/soundlib/ModSequence.cpp 2009-10-25 22:17:12 UTC (rev 406) +++ trunk/OpenMPT/soundlib/ModSequence.cpp 2009-10-30 22:47:43 UTC (rev 407) @@ -71,15 +71,13 @@ m_nInvalidIndex = GetInvalidPatIndex(m_pSndFile->GetType()); m_nIgnoreIndex = GetIgnoreIndex(m_pSndFile->GetType()); - //Resize orderlist if needed. Because old orderlist had MAX_ORDERS(256) elements, not making it - //smaller than that even if the modtype doesn't support that many orders. + //Resize orderlist if needed. if (specs.ordersMax < GetLength()) { - resize(max(MAX_ORDERS, specs.ordersMax)); - std::fill(begin() + specs.ordersMax, end(), GetInvalidPatIndex()); + resize(specs.ordersMax); + /*resize(max(MAX_ORDERS, specs.ordersMax)); + std::fill(begin() + specs.ordersMax, end(), GetInvalidPatIndex());*/ } - if (GetLength() < MAX_ORDERS) - resize(MAX_ORDERS, GetInvalidPatIndex(oldtype)); //Replace items used to denote end of song/skip order. Replace(GetInvalidPatIndex(oldtype), GetInvalidPatIndex()); Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-10-25 22:17:12 UTC (rev 406) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-10-30 22:47:43 UTC (rev 407) @@ -265,7 +265,7 @@ UINT nPan; UINT nVolume; DWORD dwFlags; - UINT nMixPlugin; + PLUGINDEX nMixPlugin; CHAR szName[MAX_CHANNELNAME]; }; Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.cpp =================================================================== --- trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2009-10-25 22:17:12 UTC (rev 406) +++ trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2009-10-30 22:47:43 UTC (rev 407) @@ -215,6 +215,12 @@ rSndFile.Samples[i].nVibType = 0; rSndFile.Samples[i].uFlags &= ~CHN_PANNING; break; + case SmpResetVibrato: + rSndFile.Samples[i].nVibDepth = 0; + rSndFile.Samples[i].nVibRate = 0; + rSndFile.Samples[i].nVibSweep = 0; + rSndFile.Samples[i].nVibType = 0; + break; default: break; } Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.h =================================================================== --- trunk/OpenMPT/soundlib/modsmp_ctrl.h 2009-10-25 22:17:12 UTC (rev 406) +++ trunk/OpenMPT/soundlib/modsmp_ctrl.h 2009-10-30 22:47:43 UTC (rev 407) @@ -15,7 +15,8 @@ enum ResetFlag { SmpResetCompo = 1, - SmpResetInit = 2, + SmpResetInit, + SmpResetVibrato, }; // Insert silence to given location. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-11-01 13:53:27
|
Revision: 408 http://modplug.svn.sourceforge.net/modplug/?rev=408&view=rev Author: saga-games Date: 2009-11-01 13:53:08 +0000 (Sun, 01 Nov 2009) Log Message: ----------- [New] Sample editor: Sample Undo. 100 steps per sample (independent), undo buffer is cut off at a tenth of physical memory (that would be 400 MB for a system with 4 GB of RAM). Cutoff size can be specified by setting UndoBufferSize (in Megabytes) in section [Sample Editor] of mptrack.ini. [Mod] Sample editor: Removed time stretcher's / pitch shifter's preview function as it's unnecessary now. [Imp] Sample editor: When sample is 8-bit, it will automatically be converted to 16-bit when applying time stretching / pitch shifting. [Imp] Comments tab: If sample size is < 1 KB, amount of bytes is shown instead of "0 KB" [Fix] Sample editor: Insert Silence: Loop points were not updated when adding silence at the beginning of the sample [Fix] IT Loader: Use correct header size (1.xx or 2.xx header) for comparison when checking instrument headers [Ref] Pattern undo uses vectors now. [Ref] Added GetBytesPerSample() in MODSAMPLE to get the bytes per sampling point (Basically a shorter version of GetElementarySampleSize() * GetNumChannels()) [Ref] More refactoring especially in the sample editor code to make undo more easy. Modified Paths: -------------- trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/mptrack/Ctrl_pat.cpp trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/Ctrl_smp.h trunk/OpenMPT/mptrack/EffectVis.cpp trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/mptrack/View_smp.h trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/dlg_misc.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/view_com.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_mod.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/modsmp_ctrl.cpp trunk/OpenMPT/soundlib/modsmp_ctrl.h trunk/OpenMPT/soundlib/pattern.cpp Added Paths: ----------- trunk/OpenMPT/mptrack/Undo.cpp trunk/OpenMPT/mptrack/Undo.h Modified: trunk/OpenMPT/mptrack/CleanupSong.cpp =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp 2009-10-30 22:47:43 UTC (rev 407) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp 2009-11-01 13:53:08 UTC (rev 408) @@ -441,7 +441,7 @@ EndWaitCursor(); if ((nPatRemoved) || (bReordered)) { - m_pModDoc->ClearPatternUndo(); + m_pModDoc->GetPatternUndo()->ClearUndo(); if (nPatRemoved) { wsprintf(s, "%d pattern%s removed.\n", nPatRemoved, (nPatRemoved == 1) ? "" : "s"); @@ -535,6 +535,7 @@ if ((j == pSndFile->m_nSamples) && (j > 1)) pSndFile->m_nSamples--; END_CRITICAL(); nRemoved++; + m_pModDoc->GetSampleUndo()->ClearUndo(j); } } wsprintf(s, "%d unused sample%s removed\n" ,nRemoved, (nRemoved == 1) ? "" : "s"); @@ -573,7 +574,11 @@ && (pSndFile->Samples[nSmp].nLength > pSndFile->Samples[nSmp].nLoopEnd + 2)) { UINT lmax = pSndFile->Samples[nSmp].nLoopEnd + 2; - if ((lmax < pSndFile->Samples[nSmp].nLength) && (lmax >= 16)) pSndFile->Samples[nSmp].nLength = lmax; + if ((lmax < pSndFile->Samples[nSmp].nLength) && (lmax >= 2)) + { + m_pModDoc->GetSampleUndo()->PrepareUndo(nSmp, sundo_delete, lmax, pSndFile->Samples[nSmp].nLength); + ctrlSmp::ResizeSample(pSndFile->Samples[nSmp], lmax, pSndFile); + } } } wsprintf(s, "%d sample loop%s optimized\n" ,nLoopOpt, (nLoopOpt == 1) ? "" : "s"); @@ -651,6 +656,9 @@ } } + // Too lazy to fix sample undo... + m_pModDoc->GetSampleUndo()->ClearUndo(); + pSndFile->m_nSamples -= nRemap; return true; @@ -927,7 +935,8 @@ if (pSndFile->m_nSamples == 0) return false; for (SAMPLEINDEX nSmp = 1; nSmp <= pSndFile->m_nSamples; nSmp++) { - if (pSndFile->Samples[nSmp].pSample) + m_pModDoc->GetSampleUndo()->PrepareUndo(nSmp, sundo_delete, 0, pSndFile->Samples[nSmp].nLength); + if(pSndFile->Samples[nSmp].pSample) { BEGIN_CRITICAL(); pSndFile->DestroySample(nSmp); @@ -962,6 +971,8 @@ } } + if(removeSamples == -1) m_pModDoc->GetSampleUndo()->ClearUndo(); + for (INSTRUMENTINDEX i = 1; i <= pSndFile->m_nInstruments; i++) { pSndFile->DestroyInstrument(i, removeSamples); Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-10-30 22:47:43 UTC (rev 407) +++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-11-01 13:53:08 UTC (rev 408) @@ -377,7 +377,7 @@ } if (dwHintMask & (HINT_MODTYPE|HINT_UNDO)) { - m_ToolBar.EnableButton(ID_EDIT_UNDO, m_pModDoc->CanPatternUndo()); + m_ToolBar.EnableButton(ID_EDIT_UNDO, m_pModDoc->GetPatternUndo()->CanUndo()); } } Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-10-30 22:47:43 UTC (rev 407) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-11-01 13:53:08 UTC (rev 408) @@ -74,8 +74,6 @@ ON_COMMAND(ID_NEXTINSTRUMENT, OnNextInstrument) ON_COMMAND(IDC_BUTTON1, OnPitchShiftTimeStretch) ON_COMMAND(IDC_BUTTON2, OnEstimateSampleSize) - ON_COMMAND(IDC_BUTTON3, OnPitchShiftTimeStretchAccept) - ON_COMMAND(IDC_BUTTON4, OnPitchShiftTimeStretchCancel) ON_COMMAND(IDC_CHECK3, OnEnableStretchToSize) ON_EN_CHANGE(IDC_SAMPLE_NAME, OnNameChanged) ON_EN_CHANGE(IDC_SAMPLE_FILENAME, OnFileNameChanged) @@ -159,8 +157,6 @@ { m_nSample = 1; m_nLockCount = 1; - pSampleUndoBuffer = NULL; - UndoBufferSize = 0; } @@ -168,9 +164,6 @@ CCtrlSamples::~CCtrlSamples() //--------------------------- { - if(pSampleUndoBuffer) CSoundFile::FreeSample(pSampleUndoBuffer); - pSampleUndoBuffer = NULL; - UndoBufferSize = 0; } @@ -261,18 +254,13 @@ GetDlgItem(IDC_BUTTON1)->ShowWindow(SW_SHOW); // PitchShiftTimeStretch GetDlgItem(IDC_BUTTON2)->ShowWindow(SW_SHOW); // EstimateSampleSize - GetDlgItem(IDC_BUTTON3)->ShowWindow(SW_SHOW); // PitchShiftTimeStretchAccept - GetDlgItem(IDC_BUTTON4)->ShowWindow(SW_SHOW); // PitchShiftTimeStretchCancel - GetDlgItem(IDC_CHECK2)->ShowWindow(SW_SHOW); // Preview mode GetDlgItem(IDC_CHECK3)->ShowWindow(SW_SHOW); // EnableStretchToSize GetDlgItem(IDC_EDIT6)->ShowWindow(SW_SHOW); // GetDlgItem(IDC_GROUPBOX_PITCH_TIME)->ShowWindow(SW_SHOW); // GetDlgItem(IDC_TEXT_PITCH)->ShowWindow(SW_SHOW); // GetDlgItem(IDC_TEXT_QUALITY)->ShowWindow(SW_SHOW); // GetDlgItem(IDC_TEXT_FFT)->ShowWindow(SW_SHOW); // - GetDlgItem(IDC_TEXT_PREVIEW)->ShowWindow(SW_SHOW); // GetDlgItem(IDC_GROUPBOX_PITCH_TIME)->ShowWindow(SW_SHOW); // - GetDlgItem(IDC_TEXT_PERCENT)->ShowWindow(SW_SHOW); // CHAR str[16]; @@ -315,10 +303,6 @@ combo->SetCurSel(3); } - //Disable preview buttons - ((CButton *)GetDlgItem(IDC_BUTTON3))->ShowWindow(SW_HIDE); - ((CButton *)GetDlgItem(IDC_BUTTON4))->ShowWindow(SW_HIDE); - // Stretch ratio SetDlgItemInt(IDC_EDIT6,100,FALSE); @@ -348,8 +332,6 @@ if (pSndFile->m_nSamples < 1) pSndFile->m_nSamples = 1; if ((nSmp < 1) || (nSmp > pSndFile->m_nSamples)) return FALSE; - if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); - LockControls(); if (m_nSample != nSmp) { @@ -713,8 +695,6 @@ DWORD len; BOOL bOk; - if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); - BeginWaitCursor(); if ((!lpszFileName) || (!f.Open(lpszFileName))) { @@ -727,6 +707,9 @@ lpFile = f.Lock(len); if (!lpFile) goto OpenError; BEGIN_CRITICAL(); + + m_pModDoc->GetSampleUndo()->PrepareUndo(m_nSample, sundo_replace); + if (m_pSndFile->ReadSampleFromFile(m_nSample, lpFile, len)) { bOk = TRUE; @@ -779,6 +762,9 @@ bOk = TRUE; } END_CRITICAL(); + } else + { + m_pModDoc->GetSampleUndo()->RemoveLastUndoStep(m_nSample); } } f.Unlock(); @@ -830,10 +816,9 @@ { if ((!pSndFile) || (!nSample) || (nSample > pSndFile->m_nSamples)) return FALSE; - if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); - BeginWaitCursor(); BEGIN_CRITICAL(); + m_pModDoc->GetSampleUndo()->PrepareUndo(m_nSample, sundo_replace); m_pSndFile->DestroySample(m_nSample); m_pSndFile->ReadSampleFromSong(m_nSample, pSndFile, nSample); MODSAMPLE *pSmp = &m_pSndFile->Samples[m_nSample]; @@ -859,8 +844,6 @@ { if ((!IsLocked()) && (m_pSndFile)) { - if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); - UINT n = GetDlgItemInt(IDC_EDIT_SAMPLE); if ((n > 0) && (n <= m_pSndFile->m_nSamples) && (n != m_nSample)) { @@ -899,8 +882,6 @@ LONG smp = m_pModDoc->InsertSample(TRUE); if (smp != SAMPLEINDEX_INVALID) { - if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); - CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); SetCurrentSample(smp); // 05/01/05 : ericus replaced "m_nSample << 24" by "m_nSample << 20" : 4000 samples -> 12bits [see Moddoc.h] @@ -1156,6 +1137,9 @@ iEnd = pSmp->nLength; } } + + m_pModDoc->GetSampleUndo()->PrepareUndo(iSmp, sundo_update, iStart, iEnd); + if (pSmp->uFlags & CHN_STEREO) { iStart *= 2; iEnd *= 2; } if (pSmp->uFlags & CHN_16BIT) @@ -1218,31 +1202,23 @@ void CCtrlSamples::ApplyAmplify(LONG lAmp, bool bFadeIn, bool bFadeOut) //----------------------------------------------------------------------- { - SAMPLEVIEWSTATE viewstate; - DWORD dwStart, dwEnd; MODSAMPLE *pSmp; - memset(&viewstate, 0, sizeof(viewstate)); - SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate); if ((!m_pModDoc) || (!m_pSndFile) || (!m_pSndFile->Samples[m_nSample].pSample)) return; BeginWaitCursor(); pSmp = &m_pSndFile->Samples[m_nSample]; - dwStart = viewstate.dwBeginSel; - dwEnd = viewstate.dwEndSel; - if (dwEnd > pSmp->nLength) dwEnd = pSmp->nLength; - if (dwStart > dwEnd) dwStart = dwEnd; - if (dwStart >= dwEnd) - { - dwStart = 0; - dwEnd = pSmp->nLength; - } - if (pSmp->uFlags & CHN_STEREO) { dwStart *= 2; dwEnd *= 2; } - UINT len = dwEnd - dwStart; + + SELECTIONPOINTS selection = GetSelectionPoints(); + + m_pModDoc->GetSampleUndo()->PrepareUndo(m_nSample, sundo_update, selection.nStart, selection.nEnd); + + if (pSmp->uFlags & CHN_STEREO) { selection.nStart *= 2; selection.nEnd *= 2; } + UINT len = selection.nEnd - selection.nStart; if ((bFadeIn) && (bFadeOut)) lAmp *= 4; if (pSmp->uFlags & CHN_16BIT) { - signed short *p = ((signed short *)pSmp->pSample) + dwStart; + signed short *p = ((signed short *)pSmp->pSample) + selection.nStart; for (UINT i=0; i<len; i++) { @@ -1255,7 +1231,7 @@ } } else { - signed char *p = ((signed char *)pSmp->pSample) + dwStart; + signed char *p = ((signed char *)pSmp->pSample) + selection.nStart; for (UINT i=0; i<len; i++) { @@ -1282,12 +1258,8 @@ if(!m_pModDoc || !m_pSndFile) return; - SAMPLEVIEWSTATE viewstate; UINT iMinSample = m_nSample, iMaxSample = m_nSample; - memset(&viewstate, 0, sizeof(viewstate)); - SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate); - //Shift -> Process all samples if(CMainFrame::GetInputHandler()->ShiftPressed()) { @@ -1317,9 +1289,13 @@ } else { - iStart = viewstate.dwBeginSel; - iEnd = viewstate.dwEndSel; + SELECTIONPOINTS selection = GetSelectionPoints(); + iStart = selection.nStart; + iEnd = selection.nEnd; } + + m_pModDoc->GetSampleUndo()->PrepareUndo(iSmp, sundo_update, iStart, iEnd); + const float fOffset = ctrlSmp::RemoveDCOffset(m_pSndFile->Samples[iSmp], iStart, iEnd, m_pSndFile->GetType(), m_pSndFile); if(fOffset == 0.0f) // No offset removed. @@ -1379,24 +1355,25 @@ void CCtrlSamples::OnUpsample() //----------------------------- { - SAMPLEVIEWSTATE viewstate; MODSAMPLE *pSmp; DWORD dwStart, dwEnd, dwNewLen; UINT smplsize, newsmplsize; PVOID pOriginal, pNewSample; - SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate); if ((!m_pSndFile) || (!m_pSndFile->Samples[m_nSample].pSample)) return; BeginWaitCursor(); pSmp = &m_pSndFile->Samples[m_nSample]; - dwStart = viewstate.dwBeginSel; - dwEnd = viewstate.dwEndSel; + SELECTIONPOINTS selection = GetSelectionPoints(); + + dwStart = selection.nStart; + dwEnd = selection.nEnd; if (dwEnd > pSmp->nLength) dwEnd = pSmp->nLength; if (dwStart >= dwEnd) { dwStart = 0; dwEnd = pSmp->nLength; } + smplsize = (pSmp->uFlags & CHN_16BIT) ? 2 : 1; if (pSmp->uFlags & CHN_STEREO) smplsize *= 2; newsmplsize = (pSmp->uFlags & CHN_STEREO) ? 4 : 2; @@ -1406,6 +1383,8 @@ if (dwNewLen+4 <= MAX_SAMPLE_LENGTH) pNewSample = CSoundFile::AllocateSample((dwNewLen+4)*newsmplsize); if (pNewSample) { + m_pModDoc->GetSampleUndo()->PrepareUndo(m_nSample, sundo_replace); + UINT nCh = (pSmp->uFlags & CHN_STEREO) ? 2 : 1; for (UINT iCh=0; iCh<nCh; iCh++) { @@ -1495,10 +1474,7 @@ m_pSndFile->Chn[iFix].dwFlags |= CHN_16BIT; } } - pSmp->uFlags |= CHN_16BIT; - pSmp->pSample = (LPSTR)pNewSample; - pSmp->nLength = dwNewLen; - if (viewstate.dwEndSel <= viewstate.dwBeginSel) + if (selection.bSelected == false) { if(!(m_pSndFile->m_nType & MOD_TYPE_MOD)) { @@ -1506,11 +1482,19 @@ if (pSmp->RelativeTone < 84) pSmp->RelativeTone += 12; } } + pSmp->uFlags |= CHN_16BIT; + pSmp->pSample = (LPSTR)pNewSample; + pSmp->nLength = dwNewLen; + CSoundFile::FreeSample(pOriginal); END_CRITICAL(); m_pModDoc->AdjustEndOfSample(m_nSample); - if (viewstate.dwEndSel > viewstate.dwBeginSel) + if (selection.bSelected == true) { + SAMPLEVIEWSTATE viewstate; + memset(&viewstate, 0, sizeof(viewstate)); + SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate); + viewstate.dwBeginSel = dwStart; viewstate.dwEndSel = dwEnd + (dwEnd-dwStart); SendViewMessage(VIEWMSG_LOADSTATE, (LPARAM)&viewstate); @@ -1527,18 +1511,18 @@ void CCtrlSamples::OnDownsample() //------------------------------- { - SAMPLEVIEWSTATE viewstate; MODSAMPLE *pSmp; DWORD dwStart, dwEnd, dwRemove, dwNewLen; UINT smplsize; PVOID pOriginal, pNewSample; - SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate); if ((!m_pSndFile) || (!m_pSndFile->Samples[m_nSample].pSample)) return; BeginWaitCursor(); pSmp = &m_pSndFile->Samples[m_nSample]; - dwStart = viewstate.dwBeginSel; - dwEnd = viewstate.dwEndSel; + SELECTIONPOINTS selection = GetSelectionPoints(); + + dwStart = selection.nStart; + dwEnd = selection.nEnd; if (dwEnd > pSmp->nLength) dwEnd = pSmp->nLength; if (dwStart >= dwEnd) { @@ -1555,6 +1539,9 @@ if ((dwNewLen > 32) && (dwRemove)) pNewSample = CSoundFile::AllocateSample((dwNewLen+4)*smplsize); if (pNewSample) { + + m_pModDoc->GetSampleUndo()->PrepareUndo(m_nSample, sundo_replace); + UINT nCh = (pSmp->uFlags & CHN_STEREO) ? 2 : 1; for (UINT iCh=0; iCh<nCh; iCh++) { @@ -1624,7 +1611,7 @@ m_pSndFile->Chn[iFix].nLength = 0; } } - if (viewstate.dwEndSel <= viewstate.dwBeginSel) + if (selection.bSelected == false) { if(!(m_pSndFile->m_nType & MOD_TYPE_MOD)) { @@ -1637,8 +1624,12 @@ CSoundFile::FreeSample(pOriginal); END_CRITICAL(); m_pModDoc->AdjustEndOfSample(m_nSample); - if (viewstate.dwEndSel > viewstate.dwBeginSel) + if (selection.bSelected == true) { + SAMPLEVIEWSTATE viewstate; + memset(&viewstate, 0, sizeof(viewstate)); + SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate); + viewstate.dwBeginSel = dwStart; viewstate.dwEndSel = dwStart + dwRemove; SendViewMessage(VIEWMSG_LOADSTATE, (LPARAM)&viewstate); @@ -1682,40 +1673,21 @@ //---------------------------------------- { // Enable time-stretching / disable unused pitch-shifting UI elements - if(IsDlgButtonChecked(IDC_CHECK3)){ - ((CComboBox *)GetDlgItem(IDC_COMBO4))->EnableWindow(FALSE); - ((CEdit *)GetDlgItem(IDC_EDIT6))->EnableWindow(TRUE); - ((CButton *)GetDlgItem(IDC_BUTTON2))->EnableWindow(TRUE); //rewbs.timeStretchMods - GetDlgItem(IDC_TEXT_QUALITY)->ShowWindow(SW_HIDE); - GetDlgItem(IDC_COMBO5)->ShowWindow(SW_HIDE); - GetDlgItem(IDC_TEXT_FFT)->ShowWindow(SW_HIDE); - GetDlgItem(IDC_COMBO6)->ShowWindow(SW_HIDE); - GetDlgItem(IDC_TEXT_PITCH)->ShowWindow(SW_HIDE); - GetDlgItem(IDC_COMBO4)->ShowWindow(SW_HIDE); - //if(CMainFrame::gbShowHackControls == true) - //{ - GetDlgItem(IDC_TEXT_STRETCHPARAMS)->ShowWindow(SW_SHOW); - GetDlgItem(IDC_EDIT_STRETCHPARAMS)->ShowWindow(SW_SHOW); - //} - SetDlgItemText(IDC_BUTTON1, "Time Stretch"); - UpdateTimeStretchParameterString(); - } - // Enable pitch-shifting / disable unused time-stretching UI elements - else{ - ReadTimeStretchParameters(); - GetDlgItem(IDC_TEXT_QUALITY)->ShowWindow(SW_SHOW); - GetDlgItem(IDC_COMBO5)->ShowWindow(SW_SHOW); - GetDlgItem(IDC_TEXT_FFT)->ShowWindow(SW_SHOW); - GetDlgItem(IDC_COMBO6)->ShowWindow(SW_SHOW); - ((CComboBox *)GetDlgItem(IDC_COMBO4))->EnableWindow(TRUE); - ((CEdit *)GetDlgItem(IDC_EDIT6))->EnableWindow(FALSE); - ((CButton *)GetDlgItem(IDC_BUTTON2))->EnableWindow(FALSE); //rewbs.timeStretchMods - GetDlgItem(IDC_TEXT_STRETCHPARAMS)->ShowWindow(SW_HIDE); - GetDlgItem(IDC_EDIT_STRETCHPARAMS)->ShowWindow(SW_HIDE); - GetDlgItem(IDC_TEXT_PITCH)->ShowWindow(SW_SHOW); - GetDlgItem(IDC_COMBO4)->ShowWindow(SW_SHOW); - SetDlgItemText(IDC_BUTTON1, "Pitch Shift"); - } + bool bTimeStretch = IsDlgButtonChecked(IDC_CHECK3) ? true : false; + if(!bTimeStretch) ReadTimeStretchParameters(); + ((CComboBox *)GetDlgItem(IDC_COMBO4))->EnableWindow(bTimeStretch ? false : true); + ((CEdit *)GetDlgItem(IDC_EDIT6))->EnableWindow(bTimeStretch ? true : false); + ((CButton *)GetDlgItem(IDC_BUTTON2))->EnableWindow(bTimeStretch ? true : false); //rewbs.timeStretchMods + GetDlgItem(IDC_TEXT_QUALITY)->ShowWindow(bTimeStretch ? SW_HIDE : SW_SHOW); + GetDlgItem(IDC_COMBO5)->ShowWindow(bTimeStretch ? SW_HIDE : SW_SHOW); + GetDlgItem(IDC_TEXT_FFT)->ShowWindow(bTimeStretch ? SW_HIDE : SW_SHOW); + GetDlgItem(IDC_COMBO6)->ShowWindow(bTimeStretch ? SW_HIDE : SW_SHOW); + GetDlgItem(IDC_TEXT_STRETCHPARAMS)->ShowWindow(bTimeStretch ? SW_SHOW : SW_HIDE); + GetDlgItem(IDC_EDIT_STRETCHPARAMS)->ShowWindow(bTimeStretch ? SW_SHOW : SW_HIDE); + GetDlgItem(IDC_TEXT_PITCH)->ShowWindow(bTimeStretch ? SW_HIDE : SW_SHOW); + GetDlgItem(IDC_COMBO4)->ShowWindow(bTimeStretch ? SW_HIDE : SW_SHOW); + SetDlgItemText(IDC_BUTTON1, "Time Stretch"); + if(bTimeStretch) UpdateTimeStretchParameterString(); } void CCtrlSamples::OnEstimateSampleSize() @@ -1758,25 +1730,6 @@ MODSAMPLE *pSmp = &m_pSndFile->Samples[m_nSample]; if(!pSmp || pSmp->nLength == 0) goto error; - // Preview management - if(IsDlgButtonChecked(IDC_CHECK2)){ - // Free previous undo buffer - if(pSampleUndoBuffer) CSoundFile::FreeSample(pSampleUndoBuffer); - // Allocate sample undo buffer - BYTE smpsize = (pSmp->uFlags & CHN_16BIT) ? 2 : 1; - UINT nChn = (pSmp->uFlags & CHN_STEREO) ? 2 : 1; - UndoBufferSize = pSmp->nLength * nChn * smpsize; - pSampleUndoBuffer = CSoundFile::AllocateSample(UndoBufferSize); - // Not enough memory... - if(pSampleUndoBuffer == NULL){ - UndoBufferSize = 0; - errorcode = 3; - goto error; - } - // Copy sample to sample undo buffer - memcpy(pSampleUndoBuffer,pSmp->pSample,UndoBufferSize); - } - // Time stretching if(IsDlgButtonChecked(IDC_CHECK3)){ //rewbs.timeStretchMods @@ -1811,24 +1764,6 @@ errorcode = PitchShift(pitch); } - // Preview management - if(errorcode == 0 && IsDlgButtonChecked(IDC_CHECK2)){ - ((CButton *)GetDlgItem(IDC_BUTTON1))->ShowWindow(SW_HIDE); - ((CButton *)GetDlgItem(IDC_BUTTON3))->ShowWindow(SW_SHOW); - ((CButton *)GetDlgItem(IDC_BUTTON4))->ShowWindow(SW_SHOW); - SetDlgItemText(IDC_STATIC1,"Preview..."); - - //rewbs.timeStretchMods - //Disable all pitch shift / timestrech buttons until accepted or restored: - GetDlgItem(IDC_COMBO5)->EnableWindow(FALSE); - GetDlgItem(IDC_COMBO6)->EnableWindow(FALSE); - GetDlgItem(IDC_CHECK3)->EnableWindow(FALSE); - GetDlgItem(IDC_COMBO4)->EnableWindow(FALSE); - GetDlgItem(IDC_EDIT6)->EnableWindow(FALSE); - GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE); - //end rewbs.timeStretchMods - } - // Error management error: @@ -1841,8 +1776,6 @@ break; case 3 : wsprintf(str,"Not enough memory..."); break; - case 4 : wsprintf(str, "Action can be applied only to 16-bit samples."); - break; case 5 : wsprintf(str, "Too low sample rate"); break; case 6 : wsprintf(str, "Too short sample"); @@ -1858,85 +1791,7 @@ m_pModDoc->SetModified(); } -void CCtrlSamples::OnPitchShiftTimeStretchAccept() -//------------------------------------------------ -{ - // Free sample undo buffer - if(pSampleUndoBuffer) CSoundFile::FreeSample(pSampleUndoBuffer); - pSampleUndoBuffer = NULL; - UndoBufferSize = 0; - // Restore UI buttons - ((CButton *)GetDlgItem(IDC_BUTTON1))->ShowWindow(SW_SHOW); - ((CButton *)GetDlgItem(IDC_BUTTON3))->ShowWindow(SW_HIDE); - ((CButton *)GetDlgItem(IDC_BUTTON4))->ShowWindow(SW_HIDE); - SetDlgItemText(IDC_STATIC1,""); - //rewbs.timeStretchMods - //Disable all pitch shift / timestrech buttons until accepted or restored: - GetDlgItem(IDC_COMBO5)->EnableWindow(TRUE); - GetDlgItem(IDC_COMBO6)->EnableWindow(TRUE); - GetDlgItem(IDC_CHECK3)->EnableWindow(TRUE); - if (IsDlgButtonChecked(IDC_CHECK3)) - { - GetDlgItem(IDC_EDIT6)->EnableWindow(TRUE); - GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE); - } - else - { - GetDlgItem(IDC_COMBO4)->EnableWindow(TRUE); - } - //end rewbs.timeStretchMods -} - -void CCtrlSamples::OnPitchShiftTimeStretchCancel() -{ - if((!m_pSndFile) || (!m_pSndFile->Samples[m_nSample].pSample)) return; - MODSAMPLE *pSmp = &m_pSndFile->Samples[m_nSample]; - if(!pSmp) return; - - // Save processed sample buffer pointer - PVOID oldbuffer = pSmp->pSample; - BYTE smpsize = (pSmp->uFlags & CHN_16BIT) ? 2 : 1; - UINT nChn = (pSmp->uFlags & CHN_STEREO) ? 2 : 1; - - // Restore undo buffer pointer & update song data - BEGIN_CRITICAL(); - for(UINT i=0 ; i < MAX_CHANNELS ; i++){ - if((PVOID)m_pSndFile->Chn[i].pSample == oldbuffer){ - m_pSndFile->Chn[i].pSample = (LPSTR)pSampleUndoBuffer; - m_pSndFile->Chn[i].pCurrentSample = (LPSTR)pSampleUndoBuffer; - m_pSndFile->Chn[i].nLength = 0; - } - } - pSmp->pSample = (LPSTR)pSampleUndoBuffer; - pSmp->nLength = UndoBufferSize / (smpsize * nChn); - - //rewbs.timeStretchMods - // Restore loop points, if they were time stretched: - // Note: m_dTimeStretchRatio will not have changed since we disable - // GUI controls until preview is accepted/restored. - if(IsDlgButtonChecked(IDC_CHECK3)) { - pSmp->nLoopStart /= m_dTimeStretchRatio/100.0; - pSmp->nLoopEnd /= m_dTimeStretchRatio/100.0; - pSmp->nSustainStart /= m_dTimeStretchRatio/100.0; - pSmp->nSustainEnd /= m_dTimeStretchRatio/100.0; - } - //end rewbs.timeStretchMods - - END_CRITICAL(); - - // Set processed sample buffer pointer as undo sample buffer pointer - pSampleUndoBuffer = oldbuffer; - - // Free sample undo buffer & restore UI buttons - OnPitchShiftTimeStretchAccept(); - - // Update sample view - m_pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA | HINT_SAMPLEINFO, NULL); // !!!! see CODE#0006, update#3 - m_pModDoc->SetModified(); -} - - int CCtrlSamples::TimeStretch(double ratio) //----------------------------------------- { @@ -1958,11 +1813,6 @@ } - // Stretching is implemented only for 16-bit samples. Return with - // error if trying to use wtih non 16-bit samples. - if(pSmp->GetElementarySampleSize() != 2) - return 4; - // SoundTouch(1.3.1) seems to crash with short samples. Don't know what // the actual limit or whether it depends on sample rate, // but simply set some semiarbitrary threshold here. @@ -1989,14 +1839,21 @@ } // Get number of channels & sample size - const BYTE smpsize = pSmp->GetElementarySampleSize(); + BYTE smpsize = pSmp->GetElementarySampleSize(); const UINT nChn = pSmp->GetNumChannels(); + // Stretching is implemented only for 16-bit samples. + if(smpsize != 2) + { + // This has to be converted to 16-bit first. + OnUpsample(); + smpsize = pSmp->GetElementarySampleSize(); + } + // Allocate new sample. Returned sample may not be exactly the size what ratio would suggest // so allocate a bit more(1.03*). const DWORD nNewSampleLength = (DWORD)(1.03 * ratio * (double)pSmp->nLength); //const DWORD nNewSampleLength = (DWORD)(0.5 + ratio * (double)pSmp->nLength); - PVOID pSample = pSmp->pSample; PVOID pNewSample = CSoundFile::AllocateSample(nNewSampleLength * nChn * smpsize); if(pNewSample == NULL) { @@ -2112,19 +1969,9 @@ ASSERT(nNewSampleLength >= nLengthCounter); + m_pModDoc->GetSampleUndo()->PrepareUndo(m_nSample, sundo_replace); // Swap sample buffer pointer to new buffer, update song + sample data & free old sample buffer - BEGIN_CRITICAL(); - for(UINT i=0 ; i < MAX_CHANNELS ; i++){ - if((PVOID)m_pSndFile->Chn[i].pSample == pSample){ - m_pSndFile->Chn[i].pSample = (LPSTR)pNewSample; - m_pSndFile->Chn[i].pCurrentSample = (LPSTR)pNewSample; - m_pSndFile->Chn[i].nLength = 0; - } - } - pSmp->pSample = (LPSTR)pNewSample; - CSoundFile::FreeSample(pSample); - pSmp->nLength = min(nLengthCounter, nNewSampleLength); - END_CRITICAL(); + ctrlSmp::ReplaceSample(*pSmp, (LPSTR)pNewSample, min(nLengthCounter, nNewSampleLength), m_pSndFile); // Free progress bar brushes DeleteObject((HBRUSH)green); @@ -2151,14 +1998,9 @@ MODSAMPLE *pSmp = &m_pSndFile->Samples[m_nSample]; if(!pSmp) return 2; - // PitchShift seems to work only with 16-bit samples. Return with - // error if trying to use non 16-bit samples. - if(pSmp->GetElementarySampleSize() != 2) - return 4; - // Get number of channels & sample size - BYTE smpsize = (pSmp->uFlags & CHN_16BIT) ? 2 : 1; - UINT nChn = (pSmp->uFlags & CHN_STEREO) ? 2 : 1; + BYTE smpsize = pSmp->GetElementarySampleSize(); + UINT nChn = pSmp->GetNumChannels(); // Get selected oversampling - quality - (also refered as FFT overlapping) factor CComboBox *combo = (CComboBox *)GetDlgItem(IDC_COMBO5); @@ -2199,10 +2041,21 @@ BeginWaitCursor(); SetDlgItemText(IDC_STATIC1,"Pitch shifting..."); + + // PitchShift seems to work only with 16-bit samples. + if(smpsize != 2) + { + // This has to be converted to 16-bit first. + OnUpsample(); + smpsize = pSmp->GetElementarySampleSize(); + } + // Allocate working buffers float * buffer = new float[MAX_BUFFER_LENGTH + fft]; float * outbuf = new float[MAX_BUFFER_LENGTH + fft]; + m_pModDoc->GetSampleUndo()->PrepareUndo(m_nSample, sundo_replace); + // Process each channel separately for(UINT i = 0 ; i < nChn ; i++){ @@ -2316,73 +2169,18 @@ void CCtrlSamples::OnReverse() //---------------------------- { - SAMPLEVIEWSTATE viewstate; - MODSAMPLE *pSmp; - DWORD dwBeginSel, dwEndSel; - LPVOID pSample; - UINT rlen, smplsize; - - memset(&viewstate, 0, sizeof(viewstate)); - SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate); - if ((!m_pSndFile) || (!m_pSndFile->Samples[m_nSample].pSample)) return; - BeginWaitCursor(); - dwBeginSel = viewstate.dwBeginSel; - dwEndSel = viewstate.dwEndSel; - pSmp = &m_pSndFile->Samples[m_nSample]; - rlen = pSmp->nLength; - pSample = pSmp->pSample; - smplsize = (pSmp->uFlags & CHN_16BIT) ? 2 : 1; - if (pSmp->uFlags & CHN_STEREO) smplsize *= 2; - if ((dwEndSel > dwBeginSel) && (dwEndSel <= rlen)) - { - rlen = dwEndSel - dwBeginSel; - pSample = ((LPBYTE)pSmp->pSample) + dwBeginSel * smplsize; - } - if (rlen >= 2) - { - - if (smplsize == 4) - { - UINT len = rlen / 2; - UINT max = rlen - 1; - int *p = (int *)pSample; + MODSAMPLE *pSmp = &m_pSndFile->Samples[m_nSample]; - for (UINT i=0; i<len; i++) - { - int tmp = p[max-i]; - p[max-i] = p[i]; - p[i] = tmp; - } - } else - if (smplsize == 2) - { - UINT len = rlen / 2; - UINT max = rlen - 1; - signed short *p = (signed short *)pSample; + SELECTIONPOINTS selection = GetSelectionPoints(); - for (UINT i=0; i<len; i++) - { - signed short tmp = p[max-i]; - p[max-i] = p[i]; - p[i] = tmp; - } - } else - { - UINT len = rlen / 2; - UINT max = rlen - 1; - signed char *p = (signed char *)pSample; - - for (UINT i=0; i<len; i++) - { - signed char tmp = p[max-i]; - p[max-i] = p[i]; - p[i] = tmp; - } - } - m_pModDoc->AdjustEndOfSample(m_nSample); - // 05/01/05 : ericus replaced "m_nSample << 24" by "m_nSample << 20" : 4000 samples -> 12bits [see Moddoc.h] + m_pModDoc->GetSampleUndo()->PrepareUndo(m_nSample, sundo_reverse, selection.nStart, selection.nEnd); + if(ctrlSmp::ReverseSample(pSmp, selection.nStart, selection.nEnd, m_pSndFile) == true) + { m_pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, NULL); m_pModDoc->SetModified(); + } else + { + m_pModDoc->GetSampleUndo()->RemoveLastUndoStep(m_nSample); } EndWaitCursor(); SwitchToView(); @@ -2390,22 +2188,31 @@ void CCtrlSamples::OnInvert() -//-------------------------------- +//--------------------------- { - ApplyAmplify(-100); + MODSAMPLE *pSmp = &m_pSndFile->Samples[m_nSample]; + + SELECTIONPOINTS selection = GetSelectionPoints(); + + m_pModDoc->GetSampleUndo()->PrepareUndo(m_nSample, sundo_invert, selection.nStart, selection.nEnd); + if(ctrlSmp::InvertSample(pSmp, selection.nStart, selection.nEnd, m_pSndFile) == true) + { + m_pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, NULL); + m_pModDoc->SetModified(); + } else + { + m_pModDoc->GetSampleUndo()->RemoveLastUndoStep(m_nSample); + } + EndWaitCursor(); + SwitchToView(); } void CCtrlSamples::OnSignUnSign() //------------------------------- { - // purpose: sign/unsign a sample ("distortion") - SAMPLEVIEWSTATE viewstate; - DWORD dwStart, dwEnd; MODSAMPLE *pSmp; - memset(&viewstate, 0, sizeof(viewstate)); - SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate); if ((!m_pModDoc) || (!m_pSndFile) || (!m_pSndFile->Samples[m_nSample].pSample)) return; if(m_pModDoc->IsNotePlaying(0, m_nSample, 0) == TRUE) @@ -2413,29 +2220,17 @@ BeginWaitCursor(); pSmp = &m_pSndFile->Samples[m_nSample]; - dwStart = viewstate.dwBeginSel; - dwEnd = viewstate.dwEndSel; - if (dwEnd > pSmp->nLength) dwEnd = pSmp->nLength; - if (dwStart > dwEnd) dwStart = dwEnd; - if (dwStart >= dwEnd) + SELECTIONPOINTS selection = GetSelectionPoints(); + + m_pModDoc->GetSampleUndo()->PrepareUndo(m_nSample, sundo_unsign, selection.nStart, selection.nEnd); + if(ctrlSmp::UnsignSample(pSmp, selection.nStart, selection.nEnd, m_pSndFile) == true) { - dwStart = 0; - dwEnd = pSmp->nLength; - } - if (pSmp->uFlags & CHN_STEREO) { dwStart *= 2; dwEnd *= 2; } - UINT len = dwEnd - dwStart; - if (pSmp->uFlags & CHN_16BIT) + m_pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, NULL); + m_pModDoc->SetModified(); + } else { - signed short *p = ((signed short *)pSmp->pSample) + dwStart; - for (UINT i=0; i<len; ++i) p[i] += 0x8000; //unsign - } else { - signed char *p = ((signed char *)pSmp->pSample) + dwStart; - for (UINT i=0; i<len; ++i) p[i] += 0x80; //unsign + m_pModDoc->GetSampleUndo()->RemoveLastUndoStep(m_nSample); } - - m_pModDoc->AdjustEndOfSample(m_nSample); - m_pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, NULL); - m_pModDoc->SetModified(); EndWaitCursor(); SwitchToView(); } @@ -2444,55 +2239,54 @@ void CCtrlSamples::OnSilence() //---------------------------- { - SAMPLEVIEWSTATE viewstate; MODSAMPLE *pSmp; - DWORD dwBeginSel, dwEndSel; - memset(&viewstate, 0, sizeof(viewstate)); - SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate); if ((!m_pSndFile) || (!m_pSndFile->Samples[m_nSample].pSample)) return; BeginWaitCursor(); - dwBeginSel = viewstate.dwBeginSel; - dwEndSel = viewstate.dwEndSel; - pSmp = &m_pSndFile->Samples[m_nSample]; - if (dwEndSel > pSmp->nLength) dwEndSel = pSmp->nLength; - if (dwEndSel > dwBeginSel+1) + SELECTIONPOINTS selection = GetSelectionPoints(); + + // never apply silence to a sample that has no selection + if(selection.bSelected == true) { - int len = dwEndSel - dwBeginSel; + pSmp = &m_pSndFile->Samples[m_nSample]; + m_pModDoc->GetSampleUndo()->PrepareUndo(m_nSample, sundo_update, selection.nStart, selection.nEnd); + + int len = selection.nEnd - selection.nStart; if (pSmp->uFlags & CHN_STEREO) { int smplsize = (pSmp->uFlags & CHN_16BIT) ? 4 : 2; - signed char *p = ((signed char *)pSmp->pSample) + dwBeginSel*smplsize; + signed char *p = ((signed char *)pSmp->pSample) + selection.nStart * smplsize; memset(p, 0, len*smplsize); } else - if (pSmp->uFlags & CHN_16BIT) - { - short int *p = ((short int *)pSmp->pSample) + dwBeginSel; - int dest = (dwEndSel < pSmp->nLength) ? p[len-1] : 0; - int base = (dwBeginSel) ? p[0] : 0; - int delta = dest - base; - for (int i=0; i<len; i++) + if (pSmp->uFlags & CHN_16BIT) { - int n = base + (int)(((LONGLONG)delta * (LONGLONG)i) / (len-1)); - p[i] = (signed short)n; - } - } else - { - signed char *p = ((signed char *)pSmp->pSample) + dwBeginSel; - int dest = (dwEndSel < pSmp->nLength) ? p[len-1] : 0; - int base = (dwBeginSel) ? p[0] : 0; - int delta = dest - base; - for (int i=0; i<len; i++) + short int *p = ((short int *)pSmp->pSample) + selection.nStart; + int dest = (selection.nEnd < pSmp->nLength) ? p[len-1] : 0; + int base = (selection.nStart) ? p[0] : 0; + int delta = dest - base; + for (int i=0; i<len; i++) + { + int n = base + (int)(((LONGLONG)delta * (LONGLONG)i) / (len-1)); + p[i] = (signed short)n; + } + } else { - int n = base + (delta * i) / (len-1); - p[i] = (signed char)n; + signed char *p = ((signed char *)pSmp->pSample) + selection.nStart; + int dest = (selection.nEnd < pSmp->nLength) ? p[len-1] : 0; + int base = (selection.nStart) ? p[0] : 0; + int delta = dest - base; + for (int i=0; i<len; i++) + { + int n = base + (delta * i) / (len-1); + p[i] = (signed char)n; + } } - } - m_pModDoc->AdjustEndOfSample(m_nSample); - // 05/01/05 : ericus replaced "m_nSample << 24" by "m_nSample << 20" : 4000 samples -> 12bits [see Moddoc.h] - m_pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, NULL); - m_pModDoc->SetModified(); + m_pModDoc->AdjustEndOfSample(m_nSample); + // 05/01/05 : ericus replaced "m_nSample << 24" by "m_nSample << 20" : 4000 samples -> 12bits [see Moddoc.h] + m_pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, NULL); + m_pModDoc->SetModified(); } + EndWaitCursor(); SwitchToView(); } @@ -3207,3 +3001,31 @@ return 0; } //end rewbs.customKeys + + +// Return currently selected part of the sample. +// The whole sample size will be returned if no part of the sample is selected. +// However, point.bSelected indicates whether a sample selection exists or not. +SELECTIONPOINTS CCtrlSamples::GetSelectionPoints() +//------------------------------------------------ +{ + SELECTIONPOINTS points; + SAMPLEVIEWSTATE viewstate; + MODSAMPLE *pSmp = &m_pSndFile->Samples[m_nSample]; + + memset(&viewstate, 0, sizeof(viewstate)); + SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate); + points.nStart = viewstate.dwBeginSel; + points.nEnd = viewstate.dwEndSel; + if(points.nEnd > pSmp->nLength) points.nEnd = pSmp->nLength; + if(points.nStart > points.nEnd) points.nStart = points.nEnd; + points.bSelected = true; + if(points.nStart >= points.nEnd) + { + points.nStart = 0; + points.nEnd = pSmp->nLength; + points.bSelected = false; + } + return points; +} + Modified: trunk/OpenMPT/mptrack/Ctrl_smp.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.h 2009-10-30 22:47:43 UTC (rev 407) +++ trunk/OpenMPT/mptrack/Ctrl_smp.h 2009-11-01 13:53:08 UTC (rev 408) @@ -2,6 +2,13 @@ #define _CONTROL_SAMPLES_H_ +struct SELECTIONPOINTS +{ + UINT nStart; + UINT nEnd; + bool bSelected; // does sample selection exist or not? +}; + //======================================= class CCtrlSamples: public CModControlDlg //======================================= @@ -27,8 +34,6 @@ enum {nDefaultStretchChunkSize = 8192}; CComboBox m_ComboPitch, m_ComboQuality, m_ComboFFT; - PVOID pSampleUndoBuffer; - UINT UndoBufferSize; int PitchShift(float pitch); int TimeStretch(double ratio); @@ -38,6 +43,7 @@ // Applies amplification to sample. Negative values // can be used to invert phase. void ApplyAmplify(LONG nAmp, bool bFadeIn = false, bool bFadeOut = false); + SELECTIONPOINTS GetSelectionPoints(); public: CCtrlSamples(); @@ -104,8 +110,6 @@ afx_msg void OnPitchShiftTimeStretch(); afx_msg void OnEnableStretchToSize(); afx_msg void OnEstimateSampleSize(); - afx_msg void OnPitchShiftTimeStretchAccept(); - afx_msg void OnPitchShiftTimeStretchCancel(); //}}AFX_MSG DECLARE_MESSAGE_MAP() Modified: trunk/OpenMPT/mptrack/EffectVis.cpp =================================================================== --- trunk/OpenMPT/mptrack/EffectVis.cpp 2009-10-30 22:47:43 UTC (rev 407) +++ trunk/OpenMPT/mptrack/EffectVis.cpp 2009-11-01 13:53:08 UTC (rev 408) @@ -578,7 +578,7 @@ rect.SetRect(x-NODEHALF, y-NODEHALF, x+NODEHALF+1, y+NODEHALF+1); if (rect.PtInRect(point)) { - m_pModDoc->PreparePatternUndo(m_nPattern, m_nChan, row, m_nChan+1, row+1); + m_pModDoc->GetPatternUndo()->PrepareUndo(m_nPattern, m_nChan, row, m_nChan+1, row+1); m_nDragItem = row; } } @@ -669,7 +669,7 @@ SetFocus(); SetCapture(); - m_pModDoc->PreparePatternUndo(m_nPattern, m_nChan, m_startRow, m_nChan+1, m_endRow); + m_pModDoc->GetPatternUndo()->PrepareUndo(m_nPattern, m_nChan, m_startRow, m_nChan+1, m_endRow); m_dwStatus |= FXVSTATUS_LDRAGGING; } Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2009-10-30 22:47:43 UTC (rev 407) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2009-11-01 13:53:08 UTC (rev 408) @@ -204,6 +204,7 @@ | PATTERN_SHOWPREVIOUS | PATTERN_CONTSCROLL | PATTERN_SYNCMUTE | PATTERN_AUTODELAY | PATTERN_NOTEFADE; DWORD CMainFrame::m_nRowSpacing = 16; DWORD CMainFrame::m_nRowSpacing2 = 4; +UINT CMainFrame::m_nSampleUndoMaxBuffer = 100; // GDI HICON CMainFrame::m_hIcon = NULL; @@ -443,6 +444,8 @@ CSoundFile::s_DefaultPlugVolumeHandling = static_cast<uint8>(GetPrivateProfileInt("Misc", "DefaultPlugVolumeHandling", PLUGIN_VOLUMEHANDLING_IGNORE, iniFile)); if(CSoundFile::s_DefaultPlugVolumeHandling > 2) CSoundFile::s_DefaultPlugVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE; + m_nSampleUndoMaxBuffer = GetPrivateProfileLong("Sample Editor" , "UndoBufferSize", m_nSampleUndoMaxBuffer, iniFile) << 20; + TCHAR szPath[_MAX_PATH] = ""; GetPrivateProfileString("Paths", "Songs_Directory", GetDefaultDirectory(DIR_MODS), szPath, INIBUFFERSIZE, iniFile); SetDefaultDirectory(szPath, DIR_MODS); Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2009-10-30 22:47:43 UTC (rev 407) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2009-11-01 13:53:08 UTC (rev 408) @@ -406,6 +406,9 @@ static BOOL gbPatternVUMeters, gbPatternPluginNames, gbPatternRecord; static DWORD m_dwPatternSetup, m_dwMidiSetup, m_nRowSpacing, m_nRowSpacing2, m_nKeyboardCfg, gnHotKeyMask; static bool m_bHideUnavailableCtxMenuItems; + // Sample Editor Setup + static UINT m_nSampleUndoMaxBuffer; + // GDI static HICON m_hIcon; static HFONT m_hGUIFont, m_hFixedFont, m_hLargeFixedFont; Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-30 22:47:43 UTC (rev 407) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-11-01 13:53:08 UTC (rev 408) @@ -95,7 +95,10 @@ m_bPaused = TRUE; m_lpszLog = NULL; m_hWndFollow = NULL; - memset(PatternUndo, 0, sizeof(PatternUndo)); + + m_PatternUndo.SetParent(this); + m_SampleUndo.SetParent(this); + #ifdef _DEBUG MODCHANNEL *p = m_SndFile.Chn; if (((DWORD)p) & 7) Log("MODCHANNEL is not aligned (0x%08X)\n", p); @@ -113,7 +116,6 @@ CModDoc::~CModDoc() //----------------- { - ClearPatternUndo(); ClearLog(); } @@ -149,7 +151,7 @@ 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(min(MAX_ORDERS, m_SndFile.GetModSpecifications().ordersMax)); + m_SndFile.Order.resize(m_SndFile.GetModSpecifications().ordersMax); theApp.GetDefaultMidiMacro(&m_SndFile.m_MidiCfg); ReinitRecordState(); Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-10-30 22:47:43 UTC (rev 407) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-11-01 13:53:08 UTC (rev 408) @@ -11,9 +11,9 @@ #include "sndfile.h" #include "misc_util.h" +#include "Undo.h" - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Bit Mask for updating view (hints of what changed) @@ -89,20 +89,6 @@ STATIC_ASSERT( ((-1 << HINT_SHIFT_SEQUENCE) & HINT_MASK_ITEM) == (-1 << HINT_SHIFT_SEQUENCE) ); - -// Undo -#define MAX_UNDO_LEVEL 100 - -// Pattern Undo -typedef struct PATTERNUNDOBUFFER -{ - UINT pattern, patternsize; - UINT column, row; - UINT cx, cy; - MODCOMMAND *pbuffer; -} PATTERNUNDOBUFFER, *PPATTERNUNDOBUFFER; - - //parametered macro presets: enum { @@ -128,7 +114,6 @@ BOOL m_bPaused; HWND m_hWndFollow; DWORD m_dwNotifyType; - PATTERNUNDOBUFFER PatternUndo[MAX_UNDO_LEVEL]; bool bModifiedAutosave; // Modified since last autosave? @@ -140,6 +125,9 @@ std::bitset<MAX_BASECHANNELS> m_bsMultiSplitRecordMask; // -! NEW_FEATURE#0015 + CPatternUndo m_PatternUndo; + CSampleUndo m_SampleUndo; + protected: // create from serialization only CModDoc(); DECLARE_SERIAL(CModDoc) @@ -189,6 +177,10 @@ static int GetZxxType(const CHAR (&szMidiZXXExt)[128 * 32]); static void CreateZxxFromType(CHAR (&szMidiZXXExt)[128 * 32], int iZxxType); void SongProperties(); + + CPatternUndo *GetPatternUndo() { return &m_PatternUndo; } + CSampleUndo *GetSampleUndo() { return &m_SampleUndo; } + // operations public: BOOL ChangeModType(MODTYPE wType); @@ -243,15 +235,14 @@ bool MoveOrder(ORDERINDEX nSourceNdx, ORDERINDEX nDestNdx, bool bUpdate = true, bool bCopy = false, SEQUENCEINDEX nSourceSeq = SEQUENCEINDEX_INVALID, SEQUENCEINDEX nDestSeq = SEQUENCEINDEX_INVALID); BOOL ExpandPattern(PATTERNINDEX nPattern); BOOL ShrinkPattern(PATTERNINDEX nPattern); + + // Copy&Paste BOOL CopyPattern(PATTERNINDEX nPattern, DWORD dwBeginSel, DWORD dwEndSel); BOOL PastePattern(PATTERNINDEX nPattern, DWORD dwBeginSel, BOOL mix, BOOL ITStyleMix=FALSE); //rewbs.mixpaste BOOL CopyEnvelope(UINT nIns, UINT nEnv); BOOL PasteEnvelope(UINT nIns, UINT nEnv); - BOOL ClearPatternUndo(); - BOOL PreparePatternUndo(UINT pattern, UINT x, UINT y, UINT cx, UINT cy); - UINT DoPatternUndo(); - BOOL CanPatternUndo(); + LRESULT ActivateView(UINT nIdView, DWORD dwParam); void UpdateAllViews(CView *pSender, LPARAM lHint=0L, CObject *pHint=NULL); HWND GetEditPosition(ROWINDEX &row, PATTERNINDEX &pat, ORDERINDEX &ord); //rewbs.customKeys Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-30 22:47:43 UTC (rev 407) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-11-01 13:53:08 UTC (rev 408) @@ -369,7 +369,8 @@ AddToLog("WARNING: Instrument envelopes have been shortened.\n"); SetModified(); - ClearPatternUndo(); + GetPatternUndo()->ClearUndo(); + GetSampleUndo()->ClearUndo(); UpdateAllViews(NULL, HINT_MODTYPE | HINT_MODGENERAL); EndWaitCursor(); return TRUE; @@ -470,7 +471,7 @@ EndWaitCursor(); } SetModified(); - ClearPatternUndo(); + GetPatternUndo()->ClearUndo(); UpdateAllViews(NULL, HINT_MODTYPE); return TRUE; } @@ -543,7 +544,7 @@ END_CRITICAL(); EndWaitCursor(); SetModified(); - ClearPatternUndo(); + GetPatternUndo()->ClearUndo(); UpdateAllViews(NULL, HINT_MODTYPE); return FALSE; } @@ -1144,7 +1145,7 @@ if ((hCpy) && ((p = (LPSTR)GlobalLock(hCpy)) != NULL)) { - PreparePatternUndo(nPattern, 0, 0, m_SndFile.m_nChannels, m_SndFile.PatternSize[nPattern]); + GetPatternUndo()->PrepareUndo(nPattern, 0, 0, m_SndFile.m_nChannels, m_SndFile.PatternSize[nPattern]); TEMPO spdmax = m_SndFile.GetModSpecifications().speedMax; DWORD dwMemSize = GlobalSize(hCpy); MODCOMMAND *m = m_SndFile.Patterns[nPattern]; @@ -1350,7 +1351,7 @@ nPattern = m_SndFile.Order[oNextOrder]; if(m_SndFile.Patterns.IsValidPat(nPattern) == false) goto PasteDone; m = m_SndFile.Patterns[nPattern]; - PreparePatternUndo(nPattern, 0,0, m_SndFile.m_nChannels, m_SndFile.PatternSize[nPattern]); + GetPatternUndo()->PrepareUndo(nPattern, 0,0, m_SndFile.m_nChannels, m_SndFile.PatternSize[nPattern]); oCurrentOrder = oNextOrder; } } @@ -1559,126 +1560,6 @@ } -///////////////////////////////////////////////////////////////////////////////////////// -// Pattern Undo Functions - -BOOL CModDoc::ClearPatternUndo() -//------------------------------ -{ - for (UINT i=0; i<MAX_UNDO_LEVEL; i++) - { - if (PatternUndo[i].pbuffer) delete[] PatternUndo[i].pbuffer; - PatternUndo[i].cx = 0; - PatternUndo[i].cy = 0; - PatternUndo[i].pbuffer = NULL; - } - return TRUE; -} - - -BOOL CModDoc::CanPatternUndo() -//---------------------------- -{ - return (PatternUndo[0].pbuffer) ? TRUE : FALSE; -} - - -BOOL CModDoc::PreparePatternUndo(UINT pattern, UINT x, UINT y, UINT cx, UINT cy) -//------------------------------------------------------------------------------ -{ - MODCOMMAND *pUndo, *pPattern; - UINT nRows; - BOOL bUpdate; - - if ((pattern >= m_SndFile.Patterns.Size()) || (!m_SndFile.Patterns[pattern])) return FALSE; - nRows = m_SndFile.PatternSize[pattern]; - pPattern = m_SndFile.Patterns[pattern]; - if ((y >= nRows) || (cx < 1) || (cy < 1) || (x >= m_SndFile.m_nChannels)) return FALSE; - if (y+cy >= nRows) cy = nRows-y; - if (x+cx >= m_SndFile.m_nChannels) cx = m_SndFile.m_nChannels - x; - BeginWaitCursor(); - pUndo = new MODCOMMAND[cx*cy]; - if (!pUndo) - { - EndWaitCursor(); - return FALSE; - } - bUpdate = (PatternUndo[0].pbuffer) ? FALSE : TRUE; - if (PatternUndo[MAX_UNDO_LEVEL-1].pbuffer) - { - delete[] PatternUndo[MAX_UNDO_LEVEL-1].pbuffer; - PatternUndo[MAX_UNDO_LEVEL-1].pbuffer = NULL; - } - for (UINT i=MAX_UNDO_LEVEL-1; i>=1; i--) - { - PatternUndo[i] = PatternUndo[i-1]; - } - PatternUndo[0].pattern = pattern; - PatternUndo[0].patternsize = m_SndFile.PatternSize[pattern]; - PatternUndo[0].column = x; - PatternUndo[0].row = y; - PatternUndo[0].cx = cx; - PatternUndo[0].cy = cy; - PatternUndo[0].pbuffer = pUndo; - pPattern += x + y*m_SndFile.m_nChannels; - for (UINT iy=0; iy<cy; iy++) - { - memcpy(pUndo, pPattern, cx*sizeof(MODCOMMAND)); - pUndo += cx; - pPattern += m_SndFile.m_nChannels; - } - EndWaitCursor(); - if (bUpdate) UpdateAllViews(NULL, HINT_UNDO); - return TRUE; -} - - -UINT CModDoc::DoPatternUndo() -//--------------------------- -{ - MODCOMMAND *pUndo, *pPattern; - UINT nPattern, nRows; - - if ((!PatternUndo[0].pbuffer) || (PatternUndo[0].pattern >= m_SndFile.Patterns.Size())) return (UINT)-1; - nPattern = PatternUndo[0].pattern; - nRows = PatternUndo[0].patternsize; - if (PatternUndo[0].column + PatternUndo[0].cx <= m_SndFile.m_nChannels) - { - if ((!m_SndFile.Patterns[nPattern]) || (m_SndFile.PatternSize[nPattern] < nRows)) - { - MODCOMMAND *newPattern = CSoundFile::AllocatePattern(nRows, m_SndFile.m_nChannels); - MODCOMMAND *oldPattern = m_SndFile.Patterns[nPattern]; - if (!newPattern) return (UINT)-1; - const ROWINDEX nOldRowCount = m_SndFile.Patterns[nPattern].GetNumRows(); - m_SndFile.Patterns[nPattern].SetData(newPattern, nRows); - if (oldPattern) - { - memcpy(newPattern, oldPattern, m_SndFile.m_nChannels*nOldRowCount*sizeof(MODCOMMAND)); - CSoundFile::FreePattern(oldPattern); - } - } - pUndo = PatternUndo[0].pbuffer; - pPattern = m_SndFile.Patterns[nPattern]; - if (!m_SndFile.Patterns[nPattern]) return (UINT)-1; - pPattern += PatternUndo[0].column + (PatternUndo[0].row * m_SndFile.m_nChannels); - for (UINT iy=0; iy<PatternUndo[0].cy; iy++) - { - memcpy(pPattern, pUndo, PatternUndo[0].cx * sizeof(MODCOMMAND)); - pPattern += m_SndFile.m_nChannels; - pUndo += PatternUndo[0].cx; - } - } - delete[] PatternUndo[0].pbuffer; - for (UINT i=0; i<MAX_UNDO_LEVEL-1; i++) - { - PatternUndo[i] = PatternUndo[i+1]; - } - PatternUndo[MAX_UNDO_LEVEL-1].pbuffer = NULL; - if (!PatternUndo[0].pbuffer) UpdateAllViews(NULL, HINT_UNDO); - return nPattern; -} - - void CModDoc::CheckUnusedChannels(BOOL mask[MAX_CHANNELS], CHANNELINDEX maxRemoveCount) //-------------------------------------------------------- { Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2009-10-30 22:47:43 UTC (rev 407) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2009-11-01 13:53:08 UTC (rev 408) @@ -828,6 +828,9 @@ // Allow allocations of at least 16MB if (gMemStatus.dwTotalPhys < 16*1024*1024) gMemStatus.dwTotalPhys = 16*1024*1024; + CMainFrame::m_nSampleUndoMaxBuffer = gMemStatus.dwTotalPhys / 10; // set sample undo buffer size + if(CMainFrame::m_nSampleUndoMaxBuffer < 1) CMainFrame::m_nSampleUndoMaxBuffer = 1; + ASSERT(NULL == m_pDocManager); m_pDocManager = new CModDocManager(); Added: trunk/OpenMPT/mptrack/Undo.cpp =================================================================== --- trunk/OpenMPT/mptrack/Undo.cpp (rev 0) +++ trunk/OpenMPT/mptrack/Undo.cpp 2009-11-01 13:53:08 UTC (rev 408) @@ -0,0 +1,460 @@ +/* + * Undo.cpp + * -------- + * Purpose: Undo functions for pattern and sample editor + * Notes : (currently none) + * Authors: Olivier Lapicque + * OpenMPT Devs + */ + + +#include "stdafx.h" +#include "moddoc.h" +#include "MainFrm.h" +#include "modsmp_ctrl.h" +#include "Undo.h" + + +///////////////////////////////////////////////////////////////////////////////////////// +// Pattern Undo Functions + + +// Remove all undo steps. +void CPatternUndo::ClearUndo() +//---------------------------- +{ + while(UndoBuffer.size() > 0) + { + DeleteUndoStep(0); + } +} + + +// Create undo point. +bool CPatternUndo::PrepareUndo(PATTERNINDEX pattern, UINT x, UINT y, UINT cx, UINT cy) +//------------------------------------------------------------------------------------ +{ + if(m_pModDoc == nullptr) return false; + CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return false; + + PATTERNUNDOBUFFER sUndo; + MODCOMMAND *pUndoData, *pPattern; + UINT nRows; + + if (!pSndFile->Patterns.IsValidPat(pattern)) return false; + nRows = pSndFile->PatternSize[pattern]; + pPattern = pSndFile->Patterns[pattern]; + if ((y >= nRows) || (cx < 1) || (cy < 1) || (x >= pSndFile->m_nChannels)) return false; + if (y + cy >= nRows) cy = nRows - y; + if (x + cx >= pSndFile->m_nChannels) cx = pSndFile->m_nChannels - x; + + pUndoData = new MODCOMMAND[cx * cy]; + if (!pUndoData) return false; + + const bool bUpdate = !CanUndo(); // update undo status? + + // Remove an undo step if there are too many. + while(UndoBuffer.size() >= MAX_UNDO_LEVEL) + { + DeleteUndoStep(0); + } + + sUndo.pattern = pattern; + sUndo.patternsize = pSndFile->PatternSize[pattern]; + sUndo.column = x; + sUndo.row = y; + sUndo.cx = cx; + sUndo.cy = cy; + sUndo.pbuffer = pUndoData; + pPattern += x + y * pSndFile->m_nChannels; + for (UINT iy = 0; iy < cy; iy++) + { + memcpy(pUndoData, pPattern, cx * sizeof(MODCOMMAND)); + pUndoData += cx; + pPattern += pSndFile->m_nChannels; + } + + UndoBuffer.push_back(sUndo); + + if (bUpdate) m_pModDoc->UpdateAllViews(NULL, HINT_UNDO); + return true; +} + + +// Restore an undo point. Returns which pattern has been modified. +PATTERNINDEX CPatternUndo::Undo() +//------------------------------- +{ + if(m_pModDoc == nullptr) return PATTERNINDEX_INVALID; + CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return PATTERNINDEX_INVALID; + + MODCOMMAND *pUndoData, *pPattern; + PATTERNINDEX nPattern; + ROWINDEX nRows; + + if (CanUndo() == false) return PATTERNINDEX_INVALID; + + // If the most recent undo step is invalid, trash it. + while(UndoBuffer.back().pattern >= pSndFile->Patterns.Size()) + { + RemoveLastUndoStep(); + } + + // Select most recent undo slot + const PATTERNUNDOBUFFER *pUndo = &UndoBuffer.back(); + + nPattern = pUndo->pattern; + nRows = pUndo->patternsize; + if(pUndo->column + pUndo->cx <= pSndFile->m_nChannels) + { + if((!pSndFile->Patterns[nPattern]) || (pSndFile->PatternSize[nPattern] < nRows)) + { + MODCOMMAND *newPattern = CSoundFile::AllocatePattern(nRows, pSndFile->m_nChannels); + MODCOMMAND *oldPattern = pSndFile->Patterns[nPattern]; + if (!newPattern) return PATTERNINDEX_INVALID; + const ROWINDEX nOldRowCount = pSndFile->Patterns[nPattern].GetNumRows(); + pSndFile->Patterns[nPattern].SetData(newPattern, nRows); + if(oldPattern) + { + memcpy(newPattern, oldPattern, pSndFile->m_nChannels * nOldRowCount * sizeof(MODCOMMAND)); + CSoundFile::FreePattern(oldPattern); + } + } + pUndoData = pUndo->pbuffer; + pPattern = pSndFile->Patterns[nPattern]; + if (!pSndFile->Patterns[nPattern]) return PATTERNINDEX_INVALID; + pPattern += pUndo->column + (pUndo->row * pSndFile->m_nChannels); + for(UINT iy = 0; iy < pUndo->cy; iy++) + { + memcpy(pPattern, pUndoData, pUndo->cx * sizeof(MODCOMMAND)); + pPattern += pSndFile->m_nChannels; + pUndoData += pUndo->cx; + } + } + + RemoveLastUndoStep(); + + if (CanUndo() == false) m_pModDoc->UpdateAllViews(NULL, HINT_UNDO); + return nPattern; +} + + +// Check if an undo buffer actually exists. +bool CPatternUndo::CanUndo() +//-------------------------- +{ + return (UndoBuffer.size() > 0) ? true : false; +} + + +// Delete a given undo step. +void CPatternUndo::DeleteUndoStep(UINT nStep) +//------------------------------------------- +{ + if(nStep >= UndoBuffer.size()) return; + if (UndoBuffer[nStep].pbuffer) delete[] UndoBuffer[nStep].pbuffer; + UndoBuffer.erase(UndoBuffer.begin() + nStep); +} + + +// Public helper function to remove the most recent undo point. +void CPatternUndo::RemoveLastUndoStep() +//------------------------------------- +{ + if(CanUndo() == false) return; + DeleteUndoStep(UndoBuffer.size() - 1); +} + + +///////////////////////////////////////////////////////////////////////////////////////// +// Sample Undo Functions + + +// Remove all undo steps for all samples. +void CSampleUndo::ClearUndo() +//--------------------------- +{ + for(SAMPLEINDEX nSmp = 1; nSmp <= MAX_SAMPLES; nSmp++) + { + ClearUndo(nSmp); + } + UndoBuffer.clear(); +} + + +// Remove all undo steps of a given sample. +void CSampleUndo::ClearUndo(const SAMPLEINDEX nSmp) +//------------------------------------------------- +{ + if(!SampleBufferExists(nSmp, false)) return; + + while(UndoBuffer[nSmp - 1].size() > 0) + { + DeleteUndoStep(nSmp, 0); + } +} + + +// Create undo point for given sample. +// The main program has to tell what kind of changes are going to be made to the sample. +// That way, a lot of RAM can be saved, because some actions don't even require an undo sample buffer. +bool CSampleUndo::PrepareUndo(const SAMPLEINDEX nSmp, sampleUndoTypes nChangeType, UINT nChangeStart, UINT nChangeEnd) +//-------------------------------------------------------------------------------------------------------------------- +{ + if(m_pModDoc == nullptr || !SampleBufferExists(nSmp)) return false; + + CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return false; + + // Remove an undo step if there are too many. + while(UndoBuffer[nSmp - 1].size() >= MAX_UNDO_LEVEL) + { + DeleteUndoStep(nSmp, 0); + } + + // Restrict amount of memory that's being used + RestrictBufferSize(); + + // Create new undo slot + SAMPLEUNDOBUFFER sUndo; + + // Save old sample header + memcpy(&sUndo.OldSample, &pSndFile->Samples[nSmp], sizeof(MODSAMPLE)); + sUndo.nChangeType = nChangeType; + + if(nChangeType == sundo_replace) + { + // ensure that size information is correct here. + nChangeStart = 0; + nChangeEnd = pSndFile->Samples[nSmp].nLength; + } else if(nChangeType == sundo_none) + { + // we do nothing... + nChangeStart = nChangeEnd = 0; + } + + sUndo.nChangeStart = nChangeStart; + sUndo.nChangeEnd = nChangeEnd; + sUndo.SamplePtr = nullptr; + + switch(nChangeType) + { + case sundo_none: // we are done, no sample changes here. + case sundo_invert: // no action necessary, since those effects can be applied again to be undone. + case sundo_reverse: // dito + case sundo_unsign: // dito + case sundo_insert: // no action necessary, we already have stored the variables that are necessary. + break; + + case sundo_update: + case sundo_delete: + case sundo_replace: + { + UINT nBytesPerSample = pSndFile->Samples[nSmp].GetBytesPerSample(); + UINT nChangeLen = nChangeEnd - nChangeStart; + + sUndo.SamplePtr = pSndFile->AllocateSample(nChangeLen * nBytesPerSample + 4 * nBytesPerSample); + if(sUndo.SamplePtr == nullptr) return false; + memcpy(sUndo.SamplePtr, pSndFile->Samples[nSmp].pSample + nChangeStart * nBytesPerSample, nChangeLen * nBytesPerSample); + +#ifdef DEBUG + char s[64]; + const UINT nSize = (GetUndoBufferCapacity() + nChangeLen * nBytesPerSample) >> 10; + wsprintf(s, "Sample undo buffer size is now %u.%u MB\n", nSize >> 10, (nSize & 1023) * 100 / 1024); + Log(s); +#endif + + } + break; + + default: + ASSERT(false); // whoops, what's this? someone forgot to implement it, some code is obviously missing here! + return false; + } + + UndoBuffer[nSmp - 1].push_back(sUndo); + + m_pModDoc->UpdateAllViews(NULL, HINT_UNDO); + + return true; +} + + +// Restore undo point for given sample +bool CSampleUndo::Undo(const SAMPLEINDEX nSmp) +//-------------------------------------------- +{ + if(m_pModDoc == nullptr || CanUndo(nSmp) == false) return false; + + CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return false; + + // Select most recent undo slot + SAMPLEUNDOBUFFER *pUndo = &UndoBuffer[nSmp - 1].back(); + + LPSTR pCurrentSample = pSndFile->Samples[nSmp].pSample; + LPSTR pNewSample = nullptr; // a new sample is possibly going to be allocated, depending on what's going to be undone. + + UINT nBytesPerSample = pUndo->OldSample.GetBytesPerSample(); + UINT nChangeLen = pUndo->nChangeEnd - pUndo->nChangeStart; + + switch(pUndo->nChangeType) + { + case sundo_none: + break; + + case sundo_invert: + // invert again + ctrlSmp::InvertSample(&pSndFile->Samples[nSmp], pUndo->nChangeStart, pUndo->nChangeEnd, pSndFile); + break; + + case sundo_reverse: + // reverse again + ctrlSmp::ReverseSample(&pSndFile->Samples[nSmp], pUndo->nChangeStart, pUndo->nChangeEnd, pSndFile); + break; + + case sundo_unsign: + // unsign again + ctrlSmp::UnsignSample(&pSndFile->Samples[nSmp], pUndo->nChangeStart, pUndo->nChangeEnd, pSndFile); + break; + + case sundo_insert: + // delete inserted data + ASSERT(nChangeLen == pSndFile->Samples[nSmp].nLength - pUndo->OldSample.nLength); + memcpy(pCurrentSample + pUndo->nChangeStart * nBytesPerSample, pCurrentSample + pUndo->nChangeEnd * nBytesPerSample, (pSndFile->Samples[nSmp].nLength - pUndo->nChangeEnd) * nBytesPerSample); + // also clean the sample end + memset(pCurrentSample + pUndo->OldSample.nLength * nBytesPerSample, 0, (pSndFile->Samples[nSmp].nLength - pUndo->OldSample.nLength) * nBytesPerSample); + break; + + case sundo_update: + // simply replace what has been updated. + if(pSndFile->Samples[nSmp].nLength < pUndo->nChangeEnd) return false; + memcpy(pCurrentSample + pUndo->nChangeStart * nBytesPerSample, pUndo->SamplePtr, nChangeLen * nBytesPerSample); + break; + + case sundo_delete: + // insert deleted data + pNewSample = pSndFile->AllocateSamp... [truncated message content] |
From: <rel...@us...> - 2009-11-02 21:54:46
|
Revision: 410 http://modplug.svn.sourceforge.net/modplug/?rev=410&view=rev Author: relabsoluness Date: 2009-11-02 21:54:36 +0000 (Mon, 02 Nov 2009) Log Message: ----------- [Fix] Instrument tab: OnMouseMove could cause a crash when moving cursor on Pitch/Filter envelope when not having any instruments. [Ref] Changes to param control note update done on reordering plugs (see rev. 407) [Ref] Minor tweaking (cleaned compiler warnings etc.). Modified Paths: -------------- trunk/OpenMPT/mptrack/Childfrm.h trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/View_gen.cpp trunk/OpenMPT/mptrack/View_gen.h trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/mptrack/View_ins.h trunk/OpenMPT/soundlib/ModSequence.h trunk/OpenMPT/soundlib/modcommand.h trunk/OpenMPT/soundlib/patternContainer.h Modified: trunk/OpenMPT/mptrack/Childfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Childfrm.h 2009-11-01 16:27:14 UTC (rev 409) +++ trunk/OpenMPT/mptrack/Childfrm.h 2009-11-02 21:54:36 UTC (rev 410) @@ -17,7 +17,7 @@ typedef struct _GENERALVIEWSTATE { DWORD cbStruct; - DWORD nPlugin; + PLUGINDEX nPlugin; DWORD nParam; DWORD nTab; } GENERALVIEWSTATE; Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-11-01 16:27:14 UTC (rev 409) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-11-02 21:54:36 UTC (rev 410) @@ -151,7 +151,7 @@ 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); + m_SndFile.Order.resize(min(ModSequenceSet::s_nCacheSize, m_SndFile.GetModSpecifications().ordersMax)); theApp.GetDefaultMidiMacro(&m_SndFile.m_MidiCfg); ReinitRecordState(); @@ -281,7 +281,7 @@ if (f.Open(pszMidiMapName, CFile::modeRead)) { - DWORD len = f.GetLength(); + DWORD len = static_cast<DWORD>(f.GetLength()); LPBYTE lpFile; if ((len) && ((lpFile = (LPBYTE)GlobalAllocPtr(GHND, len)) != NULL)) { @@ -831,7 +831,7 @@ pChn->nResonance = 0; pChn->nVolume = 256; pChn->nMasterChn = 0; //remove NNA association - pChn->nNewNote = note; + pChn->nNewNote = static_cast<BYTE>(note); if (nins) { //Set instrument m_SndFile.resetEnvelopes(pChn); @@ -1043,7 +1043,7 @@ //mute any NNA'd channels for (UINT i=m_SndFile.m_nChannels; i<MAX_CHANNELS; i++) { - if (m_SndFile.Chn[i].nMasterChn == nChn+1) { + if (m_SndFile.Chn[i].nMasterChn == nChn + 1u) { if (doMute) { m_SndFile.Chn[i].dwFlags |= muteType; } else { @@ -1432,7 +1432,7 @@ } CDoWaveConvert dwcdlg(&m_SndFile, s, &wsdlg.WaveFormat.Format, wsdlg.m_bNormalize, pMainFrm); - dwcdlg.m_dwFileLimit = wsdlg.m_dwFileLimit; + dwcdlg.m_dwFileLimit = static_cast<DWORD>(wsdlg.m_dwFileLimit); dwcdlg.m_bGivePlugsIdleTime = wsdlg.m_bGivePlugsIdleTime; dwcdlg.m_dwSongLimit = wsdlg.m_dwSongLimit; dwcdlg.m_nMaxPatterns = (wsdlg.m_bSelectPlay) ? wsdlg.m_nMaxOrder - wsdlg.m_nMinOrder + 1 : 0; @@ -2220,7 +2220,7 @@ } } if (gFXInfo[ndx].dwFlags) { - if (refParam > gFXInfo[ndx].dwFlags) { + if (refParam > static_cast<int>(gFXInfo[ndx].dwFlags)) { refParam = gFXInfo[ndx].dwFlags; //used for Zxx macro control: limit to 7F max. } } @@ -2852,6 +2852,7 @@ //rewbs.customKeys void* CModDoc::GetChildFrame() +//---------------------------- { CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); if (!pMainFrm) return 0; Modified: trunk/OpenMPT/mptrack/View_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_gen.cpp 2009-11-01 16:27:14 UTC (rev 409) +++ trunk/OpenMPT/mptrack/View_gen.cpp 2009-11-02 21:54:36 UTC (rev 410) @@ -823,7 +823,7 @@ if ((nfx >= 0) && (nfx <= MAX_MIXPLUGINS) && (nChn < pSndFile->m_nChannels) && (pSndFile->ChnSettings[nChn].nMixPlugin != (UINT)nfx)) { - pSndFile->ChnSettings[nChn].nMixPlugin = nfx; + pSndFile->ChnSettings[nChn].nMixPlugin = (PLUGINDEX)nfx; if (pSndFile->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)) pModDoc->SetModified(); pModDoc->UpdateAllViews(this, HINT_MODCHANNELS | (m_nActiveTab << HINT_SHIFT_CHNTAB)); } @@ -898,7 +898,7 @@ int nPlugin = m_CbnPlugin.GetCurSel(); if ((pModDoc) && (nPlugin >= 0) && (nPlugin < MAX_MIXPLUGINS)) { - m_nCurrentPlugin = nPlugin; + m_nCurrentPlugin = (PLUGINDEX)nPlugin; pModDoc->UpdateAllViews(NULL, HINT_MIXPLUGINS | HINT_MODCHANNELS | (m_nActiveTab << HINT_SHIFT_CHNTAB)); } // -> CODE#0002 @@ -1314,12 +1314,35 @@ } -bool CViewGlobals::MovePlug(PLUGINDEX src, PLUGINDEX dest) -//-------------------------------------------------------- + +// Functor for adjusting plug indexes in modcommands. Adjusts all instrument column values in +// range [m_nInstrMin, m_nInstrMax] by m_nDiff. +struct PlugIndexModifier +//====================== { + PlugIndexModifier(PLUGINDEX nMin, PLUGINDEX nMax, int nDiff) : + m_nInstrMin(nMin), m_nInstrMax(nMax), m_nDiff(nDiff) {} + void operator()(MODCOMMAND& m) + { + if (m.IsInstrPlug() && m.instr >= m_nInstrMin && m.instr <= m_nInstrMax) + m.instr = (MODCOMMAND::INSTR)((int)m.instr + m_nDiff); + } + int m_nDiff; + MODCOMMAND::INSTR m_nInstrMin; + MODCOMMAND::INSTR m_nInstrMax; +}; + + +bool CViewGlobals::MovePlug(PLUGINDEX src, PLUGINDEX dest, bool bAdjustPat) +//------------------------------------------------------------------------- +{ + if (src == dest) + return false; //AfxMessageBox("Moving %d to %d", src, dest); CModDoc *pModDoc = GetDocument(); CSoundFile* pSndFile = pModDoc->GetSoundFile(); + + BeginWaitCursor(); BEGIN_CRITICAL(); @@ -1363,24 +1386,20 @@ } } - // Update patterns (param control notes) - for (PATTERNINDEX nPat = 0; nPat < pSndFile->Patterns.Size(); nPat++) if (pSndFile->Patterns[nPat]) - { - MODCOMMAND *m = pSndFile->Patterns[nPat]; - for (UINT len = pSndFile->PatternSize[nPat] * pSndFile->m_nChannels; len; m++, len--) - { - if((m->note == NOTE_PC || m->note == NOTE_PCS) && m->instr == src + 1) - m->instr = dest + 1; - } - } + // Update MODCOMMANDs so that they won't be referring to old indexes (e.g. with NOTE_PC). + if (bAdjustPat && pSndFile->GetType() == MOD_TYPE_MPT) + pSndFile->Patterns.ForEachModCommand(PlugIndexModifier(src + 1, src + 1, int(dest) - int(src))); END_CRITICAL(); pModDoc->SetModified(); + EndWaitCursor(); + return true; } + void CViewGlobals::BuildEmptySlotList(CArray<UINT, UINT> &emptySlots) //------------------------------------------------------------------- { @@ -1416,9 +1435,14 @@ //possible mem leak here... } - for (PLUGINDEX nSlot = MAX_MIXPLUGINS-1; nSlot > (PLUGINDEX)m_nCurrentPlugin; nSlot--) { + // Update MODCOMMANDs so that they won't be referring to old indexes (e.g. with NOTE_PC). + if (pSndFile->GetType() == MOD_TYPE_MPT) + pSndFile->Patterns.ForEachModCommand(PlugIndexModifier(m_nCurrentPlugin + 1, MAX_MIXPLUGINS - 1, 1)); + + + for (PLUGINDEX nSlot = MAX_MIXPLUGINS-1; nSlot > m_nCurrentPlugin; nSlot--) { if (pSndFile->m_MixPlugins[nSlot-1].pMixPlugin) { - MovePlug(nSlot-1, nSlot); + MovePlug(nSlot-1, nSlot, NoPatternAdjust); } } Modified: trunk/OpenMPT/mptrack/View_gen.h =================================================================== --- trunk/OpenMPT/mptrack/View_gen.h 2009-11-01 16:27:14 UTC (rev 409) +++ trunk/OpenMPT/mptrack/View_gen.h 2009-11-02 21:54:36 UTC (rev 410) @@ -42,6 +42,8 @@ CSpinButtonCtrl m_SpinMixGain; // update#02 // -! NEW_FEATURE#0028 + enum {AdjustPattern = true, NoPatternAdjust = false}; + protected: CViewGlobals():CFormView(IDD_VIEW_GLOBALS) { m_nLockCount = 1; } DECLARE_SERIAL(CViewGlobals) @@ -57,7 +59,7 @@ BOOL IsLocked() const { return (m_nLockCount > 0); } int GetDlgItemIntEx(UINT nID); void BuildEmptySlotList(CArray<UINT, UINT> &emptySlots); - bool MovePlug(PLUGINDEX src, PLUGINDEX dest); + bool MovePlug(PLUGINDEX src, PLUGINDEX dest, bool bAdjustPat = AdjustPattern); public: //{{AFX_VIRTUAL(CViewGlobals) Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2009-11-01 16:27:14 UTC (rev 409) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-11-02 21:54:36 UTC (rev 410) @@ -110,7 +110,7 @@ memset(m_NcButtonState, 0, sizeof(m_NcButtonState)); m_bmpEnvBar.Create(IDB_ENVTOOLBAR, 20, 0, RGB(192,192,192)); memset(m_baPlayingNote, 0, sizeof(bool)*NOTE_MAX); //rewbs.customKeys - m_nPlayingChannel =-1; //rewbs.customKeys + m_nPlayingChannel = UINT_MAX; //rewbs.customKeys //rewbs.envRowGrid m_bGrid=true; m_bGridForceRedraw=false; @@ -152,8 +152,8 @@ } -BOOL CViewInstrument::SetCurrentInstrument(UINT nIns, UINT nEnv) -//-------------------------------------------------------------- +BOOL CViewInstrument::SetCurrentInstrument(INSTRUMENTINDEX nIns, UINT nEnv) +//------------------------------------------------------------------------- { CModDoc *pModDoc = GetDocument(); DWORD dwNotify; @@ -1042,7 +1042,7 @@ } - if (windowResized || m_bGridForceRedraw || (cachedScrollPos != m_GridScrollPos) || (speed != m_GridSpeed)) { + if (windowResized || m_bGridForceRedraw || (cachedScrollPos != m_GridScrollPos) || (speed != (UINT)m_GridSpeed)) { m_GridSpeed = speed; m_GridScrollPos = cachedScrollPos; @@ -1161,7 +1161,7 @@ { maxpoint--; m_dcMemMain.SelectObject(CMainFrame::penEnvelope); - int releaseNode = EnvGetReleaseNode(); + UINT releaseNode = EnvGetReleaseNode(); for (UINT i=0; i<=maxpoint; i++) { int x = (EnvGetTick(i) + 1) * ENV_ZOOM - nScrollPos; @@ -1175,7 +1175,7 @@ } else { m_dcMemMain.MoveTo(x, y); } - if (i==releaseNode) { + if (i == releaseNode) { m_dcMemMain.FrameRect(&rect, CBrush::FromHandle(CMainFrame::brushHighLightRed)); m_dcMemMain.SelectObject(CMainFrame::penEnvelopeHighlight); } else { @@ -1371,7 +1371,7 @@ break; } memset(m_baPlayingNote, 0, sizeof(bool)*NOTE_MAX); //rewbs.instViewNNA - m_nPlayingChannel=-1; //rewbs.instViewNNA + m_nPlayingChannel = UINT_MAX; //rewbs.instViewNNA } } else if ((pnotify->dwType & dwType) && ((pnotify->dwType & 0xFFFF) == m_nInstrument)) @@ -1639,6 +1639,7 @@ CSoundFile *pSndFile = pModDoc->GetSoundFile(); if(pSndFile == nullptr) return; MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; + if (pIns == nullptr) return; BOOL bSplitCursor = FALSE; CHAR s[256]; @@ -1991,7 +1992,7 @@ void CViewInstrument::OnEnvToggleReleasNode() //--------------------------------------------------- { - int node = m_nDragItem-1; + UINT node = m_nDragItem-1; CModDoc *pModDoc = GetDocument(); if ((pModDoc) && (node>0) && (node <= EnvGetLastPoint())) @@ -2002,7 +2003,7 @@ if (envelope->nReleaseNode == node) { envelope->nReleaseNode = ENV_RELEASE_NODE_UNSET; } else { - envelope->nReleaseNode = node; + envelope->nReleaseNode = static_cast<BYTE>(node); } pModDoc->SetModified(); @@ -2137,11 +2138,11 @@ MODINSTRUMENT *pIns = pModDoc->GetSoundFile()->Instruments[m_nInstrument]; if ((!pIns) || (!pIns->Keyboard[note-1] && !pIns->nMixPlug)) return; m_baPlayingNote[note] = true; //rewbs.instViewNNA - m_nPlayingChannel= pModDoc->PlayNote(note, m_nInstrument, 0, FALSE); //rewbs.instViewNNA + m_nPlayingChannel = pModDoc->PlayNote(note, m_nInstrument, 0, FALSE); //rewbs.instViewNNA s[0] = 0; if ((note) && (note <= NOTE_MAX)) { - const std::string temp = pModDoc->GetSoundFile()->GetNoteName(note, m_nInstrument); + const std::string temp = pModDoc->GetSoundFile()->GetNoteName(static_cast<int16>(note), m_nInstrument); if(temp.size() >= sizeofS) wsprintf(s, "%s", "..."); else Modified: trunk/OpenMPT/mptrack/View_ins.h =================================================================== --- trunk/OpenMPT/mptrack/View_ins.h 2009-11-01 16:27:14 UTC (rev 409) +++ trunk/OpenMPT/mptrack/View_ins.h 2009-11-02 21:54:36 UTC (rev 410) @@ -41,7 +41,7 @@ public: void UpdateScrollSize(); - BOOL SetCurrentInstrument(UINT nIns, UINT m_nEnv=0); + BOOL SetCurrentInstrument(INSTRUMENTINDEX nIns, UINT m_nEnv=0); INSTRUMENTENVELOPE *GetEnvelopePtr() const; UINT EnvGetTick(int nPoint) const; UINT EnvGetValue(int nPoint) const; Modified: trunk/OpenMPT/soundlib/ModSequence.h =================================================================== --- trunk/OpenMPT/soundlib/ModSequence.h 2009-11-01 16:27:14 UTC (rev 409) +++ trunk/OpenMPT/soundlib/ModSequence.h 2009-11-02 21:54:36 UTC (rev 410) @@ -140,13 +140,12 @@ ModSequenceSet& operator=(const ModSequence& seq) {ModSequence::operator=(seq); return *this;} + static const ORDERINDEX s_nCacheSize = MAX_ORDERS; private: void CopyCacheToStorage(); void CopyStorageToCache(); - static const ORDERINDEX s_nCacheSize = MAX_ORDERS; - PATTERNINDEX m_Cache[s_nCacheSize]; // Local cache array. std::vector<ModSequence> m_Sequences; // Array of sequences. SEQUENCEINDEX m_nCurrentSeq; // Index of current sequence. Modified: trunk/OpenMPT/soundlib/modcommand.h =================================================================== --- trunk/OpenMPT/soundlib/modcommand.h 2009-11-01 16:27:14 UTC (rev 409) +++ trunk/OpenMPT/soundlib/modcommand.h 2009-11-02 21:54:36 UTC (rev 410) @@ -2,6 +2,19 @@ #define MODCOMMAND_H +// Note definitions +#define NOTE_NONE 0 +#define NOTE_MIDDLEC (5*12+1) +#define NOTE_KEYOFF 0xFF //255 +#define NOTE_NOTECUT 0xFE //254 +#define NOTE_FADE 0xFD //253, IT's action for illegal notes - DO NOT SAVE AS 253 as this is IT's internal representation of "no note"! +#define NOTE_PC 0xFC //252, Param Control 'note'. Changes param value on first tick. +#define NOTE_PCS 0xFB //251, Param Control(Smooth) 'note'. Changes param value during the whole row. +#define NOTE_MAX 120 //Defines maximum notevalue(with index starting from 1) as well as maximum number of notes. +#define NOTE_MAX_SPECIAL NOTE_KEYOFF +#define NOTE_MIN_SPECIAL NOTE_PCS + + //============== class MODCOMMAND //============== @@ -21,16 +34,9 @@ // Returns empty modcommand. static MODCOMMAND Empty() {MODCOMMAND m = {0,0,0,0,0,0}; return m;} - inline bool operator==(const MODCOMMAND& mc) const - { - return (memcmp(this, &mc, sizeof(MODCOMMAND)) == 0); - } + bool operator==(const MODCOMMAND& mc) const { return (memcmp(this, &mc, sizeof(MODCOMMAND)) == 0); } + bool operator!=(const MODCOMMAND& mc) const { return !(*this == mc); } - inline bool operator !=(const MODCOMMAND& mc) const - { - return !(*this == mc); - } - void Set(NOTE n, INSTR ins, uint16 volcol, uint16 effectcol) {note = n; instr = ins; SetValueVolCol(volcol); SetValueEffectCol(effectcol);} uint16 GetValueVolCol() const {return GetValueVolCol(volcmd, vol);} @@ -45,8 +51,11 @@ void Clear() {memset(this, 0, sizeof(MODCOMMAND));} // Returns true if modcommand is empty, false otherwise. - inline bool MODCOMMAND::IsEmpty() const {return (*this == Empty());} + bool IsEmpty() const {return (*this == Empty());} + // Returns true if instrument column represents plugin index. + bool IsInstrPlug() const {return note == NOTE_PC || note == NOTE_PCS;} + public: BYTE note; BYTE instr; @@ -60,19 +69,6 @@ typedef MODCOMMAND MODCOMMAND_ORIGINAL; -// Note definitions -#define NOTE_NONE 0 -#define NOTE_MIDDLEC (5*12+1) -#define NOTE_KEYOFF 0xFF //255 -#define NOTE_NOTECUT 0xFE //254 -#define NOTE_FADE 0xFD //253, IT's action for illegal notes - DO NOT SAVE AS 253 as this is IT's internal representation of "no note"! -#define NOTE_PC 0xFC //252, Param Control 'note'. Changes param value on first tick. -#define NOTE_PCS 0xFB //251, Param Control(Smooth) 'note'. Changes param value during the whole row. -#define NOTE_MAX 120 //Defines maximum notevalue(with index starting from 1) as well as maximum number of notes. -#define NOTE_MAX_SPECIAL NOTE_KEYOFF -#define NOTE_MIN_SPECIAL NOTE_PCS - - // Volume Column commands #define VOLCMD_NONE 0 #define VOLCMD_VOLUME 1 Modified: trunk/OpenMPT/soundlib/patternContainer.h =================================================================== --- trunk/OpenMPT/soundlib/patternContainer.h 2009-11-01 16:27:14 UTC (rev 409) +++ trunk/OpenMPT/soundlib/patternContainer.h 2009-11-02 21:54:36 UTC (rev 410) @@ -46,6 +46,13 @@ //'invisible' - the pattern data is cleared but the actual pattern object won't get removed. bool Remove(const PATTERNINDEX index); + // Applies function object for modcommands in patterns in given range. + // Return: Copy of the function object. + template <class Func> + Func ForEachModCommand(PATTERNINDEX nStartPat, PATTERNINDEX nLastPat, Func func); + template <class Func> + Func ForEachModCommand(Func func) {return ForEachModCommand(0, Size() - 1, func);} + PATTERNINDEX Size() const {return static_cast<PATTERNINDEX>(m_Patterns.size());} CSoundFile& GetSoundFile() {return m_rSndFile;} @@ -76,6 +83,18 @@ }; +template <class Func> +Func CPatternContainer::ForEachModCommand(PATTERNINDEX nStartPat, PATTERNINDEX nLastPat, Func func) +//------------------------------------------------------------------------------------------------- +{ + if (nStartPat > nLastPat || nLastPat >= Size()) + return func; + for (PATTERNINDEX nPat = nStartPat; nPat <= nLastPat; nPat++) if (m_Patterns[nPat]) + std::for_each(m_Patterns[nPat].Begin(), m_Patterns[nPat].End(), func); + return func; +} + + const char FileIdPatterns[] = "mptPc"; void ReadModPatterns(std::istream& iStrm, CPatternContainer& patc, const size_t nSize = 0); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-11-03 09:43:02
|
Revision: 411 http://modplug.svn.sourceforge.net/modplug/?rev=411&view=rev Author: saga-games Date: 2009-11-03 09:42:38 +0000 (Tue, 03 Nov 2009) Log Message: ----------- [New] Tree view: Clicking on a mod item (only filename node) switches to the corresponding window. [Fix] Updating 16bit and stereo channel flags when replacing a sample, in order to avoid broken sound when using undo (f.e. when undoing a 16->8 Bit conversion). [Fix] Mod Loading: Setting mod specs when loading MPTMs as well (mod specs pointer seems to be set somewhere else already, but the order list was not resized properly in all cases). [Fix] IT Saver: Save at least 2 order items. [Imp] Order list: Show cut/copy/paste orders in context menu Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/modsmp_ctrl.cpp Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-11-02 21:54:36 UTC (rev 410) +++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-11-03 09:42:38 UTC (rev 411) @@ -41,9 +41,14 @@ ON_WM_HSCROLL() ON_WM_SIZE() ON_COMMAND(ID_CONTROLTAB, OnSwitchToView) + ON_COMMAND(ID_ORDERLIST_INSERT, OnInsertOrder) ON_COMMAND(ID_ORDERLIST_DELETE, OnDeleteOrder) ON_COMMAND(ID_ORDERLIST_RENDER, OnRenderOrder) + ON_COMMAND(ID_ORDERLIST_EDIT_COPY, OnEditCopy) + ON_COMMAND(ID_ORDERLIST_EDIT_CUT, OnEditCut) + ON_COMMAND(ID_ORDERLIST_EDIT_PASTE, OnEditPaste) + ON_COMMAND(ID_PATTERN_PROPERTIES, OnPatternProperties) ON_COMMAND(ID_PLAYER_PLAY, OnPlayerPlay) ON_COMMAND(ID_PLAYER_PAUSE, OnPlayerPause) @@ -989,12 +994,18 @@ DWORD greyed = bPatternExists ? 0 : MF_GRAYED; + CInputHandler* ih = (CMainFrame::GetMainFrame())->GetInputHandler(); + if(bMultiSelection) { // several patterns are selected. AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_INSERT, "&Insert Patterns\tIns"); AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_DELETE, "&Remove Patterns\tDel"); AppendMenu(hMenu, MF_SEPARATOR, NULL, ""); + AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_EDIT_COPY, "&Copy Orders\t" + ih->GetKeyTextFromCommand(kcEditCopy)); + AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_EDIT_CUT, "&C&ut Orders\t" + ih->GetKeyTextFromCommand(kcEditCut)); + AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_EDIT_PASTE, "&Paste Orders\t" + ih->GetKeyTextFromCommand(kcEditPaste)); + AppendMenu(hMenu, MF_SEPARATOR, NULL, ""); AppendMenu(hMenu, MF_STRING | greyed, ID_ORDERLIST_COPY, "&Duplicate Patterns"); } else @@ -1007,6 +1018,7 @@ AppendMenu(hMenu, MF_STRING | greyed, ID_ORDERLIST_COPY, "&Duplicate Pattern"); AppendMenu(hMenu, MF_STRING | greyed, ID_PATTERNCOPY, "&Copy Pattern"); AppendMenu(hMenu, MF_STRING | greyed, ID_PATTERNPASTE, "P&aste Pattern"); + AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_EDIT_PASTE, "&Paste Orders\t" + ih->GetKeyTextFromCommand(kcEditPaste)); if (pSndFile->TypeIsIT_MPT_XM()) { AppendMenu(hMenu, MF_SEPARATOR, NULL, ""); Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-11-02 21:54:36 UTC (rev 410) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-11-03 09:42:38 UTC (rev 411) @@ -1372,6 +1372,16 @@ } +// Activate document's window. +void CModDoc::ActivateWindow() +//---------------------------- +{ + + CChildFrame *pChildFrm = (CChildFrame *)GetChildFrame(); + if(pChildFrm) pChildFrm->MDIActivate(); +} + + void CModDoc::UpdateAllViews(CView *pSender, LPARAM lHint, CObject *pHint) //------------------------------------------------------------------------ { Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-11-02 21:54:36 UTC (rev 410) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-11-03 09:42:38 UTC (rev 411) @@ -154,6 +154,9 @@ void ViewInstrument(UINT nIns); HWND GetFollowWnd() const { return m_hWndFollow; } void SetFollowWnd(HWND hwnd, DWORD dwType); + + void ActivateWindow(); + // Effects Description bool GetEffectName(LPSTR pszDescription, UINT command, UINT param, bool bXX = false, CHANNELINDEX nChn = CHANNELINDEX_INVALID); // bXX: Nxx: ... UINT GetNumEffects() const; @@ -189,7 +192,7 @@ BOOL ConvertInstrumentsToSamples(); UINT RemovePlugs(const bool (&keepMask)[MAX_MIXPLUGINS]); - PATTERNINDEX InsertPattern(ORDERINDEX nOrd = -1, ROWINDEX nRows = 64); + PATTERNINDEX InsertPattern(ORDERINDEX nOrd = ORDERINDEX_INVALID, ROWINDEX nRows = 64); SAMPLEINDEX InsertSample(bool bLimit = false); INSTRUMENTINDEX InsertInstrument(LONG lSample = 0, LONG lDuplicate = 0); void InitializeInstrument(MODINSTRUMENT *pIns, UINT nsample=0); Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2009-11-02 21:54:36 UTC (rev 410) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2009-11-03 09:42:38 UTC (rev 411) @@ -1184,6 +1184,10 @@ InstrumentLibraryChDir(GetItemText(hItem)); return TRUE; + case MODITEM_HDR_SONG: + if (pModDoc) pModDoc->ActivateWindow(); + return TRUE; + default: if (qwItemType & 0x8000) { @@ -2452,6 +2456,10 @@ } } break; + + case MODITEM_HDR_SONG: + ExecuteItem(hItem); + break; } } } Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2009-11-02 21:54:36 UTC (rev 410) +++ trunk/OpenMPT/mptrack/resource.h 2009-11-03 09:42:38 UTC (rev 411) @@ -1145,6 +1145,9 @@ #define ID_CLEANUP_REARRANGESAMPLES 59228 #define ID_ORDERLIST_RENDER 59229 #define ID_EDIT_CLEANUP 59230 +#define ID_ORDERLIST_EDIT_COPY 59231 +#define ID_ORDERLIST_EDIT_CUT 59232 +#define ID_ORDERLIST_EDIT_PASTE 59233 // Next default values for new objects // @@ -1152,7 +1155,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 522 -#define _APS_NEXT_COMMAND_VALUE 59231 +#define _APS_NEXT_COMMAND_VALUE 59234 #define _APS_NEXT_CONTROL_VALUE 2410 #define _APS_NEXT_SYMED_VALUE 901 #endif Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-11-02 21:54:36 UTC (rev 410) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-11-03 09:42:38 UTC (rev 411) @@ -1816,8 +1816,9 @@ } 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. + // Interestingly, this can exceed IT's 256 order limit. Also, IT will always save at least two orders. header.ordnum = min(Order.GetLengthTailTrimmed(), ModSpecs::itEx.ordersMax) + 1; + if(header.ordnum < 2) header.ordnum = 2; } @@ -2479,8 +2480,9 @@ header.highlight_major = (BYTE)(m_nRowsPerMeasure & 0xFF); // An additional "---" pattern is appended so Impulse Tracker won't ignore the last order item. - // Interestingly, this can exceed IT's 256 order limit. + // Interestingly, this can exceed IT's 256 order limit. Also, IT will always save at least two orders. header.ordnum = min(Order.GetLengthTailTrimmed(), ModSpecs::it.ordersMax) + 1; + if(header.ordnum < 2) header.ordnum = 2; header.patnum = MAX_PATTERNS; while ((header.patnum > 0) && (!Patterns[header.patnum-1])) { Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-11-02 21:54:36 UTC (rev 410) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-11-03 09:42:38 UTC (rev 411) @@ -774,7 +774,7 @@ m_pConfig->SetMixLevels(m_nMixLevels); RecalculateGainForAllPlugs(); - if (m_nType && (m_nType != MOD_TYPE_MPT)) + if (m_nType) { SetModSpecsPointer(m_pModSpecs, m_nType); Order.resize(GetModSpecifications().ordersMax); Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-11-02 21:54:36 UTC (rev 410) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-11-03 09:42:38 UTC (rev 411) @@ -971,7 +971,7 @@ inline uint32 MODSAMPLE::GetSampleRate(const MODTYPE type) const -//------------------------------------------------------------------ +//-------------------------------------------------------------- { uint32 nRate; if(type & (MOD_TYPE_MOD|MOD_TYPE_XM)) @@ -983,7 +983,7 @@ inline IMixPlugin* CSoundFile::GetInstrumentPlugin(INSTRUMENTINDEX instr) -//---------------------------------------------------------------- +//----------------------------------------------------------------------- { if(instr > 0 && instr < MAX_INSTRUMENTS && Instruments[instr] && Instruments[instr]->nMixPlug && Instruments[instr]->nMixPlug <= MAX_MIXPLUGINS) return m_MixPlugins[Instruments[instr]->nMixPlug-1].pMixPlugin; Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.cpp =================================================================== --- trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2009-11-02 21:54:36 UTC (rev 410) +++ trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2009-11-03 09:42:38 UTC (rev 411) @@ -15,9 +15,20 @@ //---------------------------------------------------------------------------------------------------------- { LPSTR const pOldSmp = smp.pSample; + DWORD dwOrFlags = 0; + DWORD dwAndFlags = MAXDWORD; + if(smp.uFlags & CHN_16BIT) + dwOrFlags |= CHN_16BIT; + else + dwAndFlags &= ~CHN_16BIT; + if(smp.uFlags & CHN_STEREO) + dwOrFlags |= CHN_STEREO; + else + dwAndFlags &= ~CHN_STEREO; + BEGIN_CRITICAL(); if (pSndFile != nullptr) - ctrlChn::ReplaceSample(pSndFile->Chn, pOldSmp, pNewSample, nNewLength); + ctrlChn::ReplaceSample(pSndFile->Chn, pOldSmp, pNewSample, nNewLength, dwOrFlags, dwAndFlags); smp.pSample = pNewSample; smp.nLength = nNewLength; CSoundFile::FreeSample(pOldSmp); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-11-06 20:40:35
|
Revision: 413 http://modplug.svn.sourceforge.net/modplug/?rev=413&view=rev Author: saga-games Date: 2009-11-06 20:40:06 +0000 (Fri, 06 Nov 2009) Log Message: ----------- [New] Pattern editor: Channel rename dialog in channel header context menu [Fix] Mod Specs: The XM and MOD format does not support "---" or "+++" items in the order list. "+++" and "---" are left out when saving as XM. The XM format supports up to 255 patterns in theory, but pattern 254/255 are still loaded as "+++"/"---" for now. [Fix] General tab: Channel name input field was not limited properly. [Imp] Orderlist: Middle click can now also be used for queuing patterns. [Imp] Orderlist: "+++" pattern item cannot be entered when writing an MOD / XM file. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_pat.h trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/View_gen.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/View_pat.h trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/dlg_misc.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/Load_med.cpp trunk/OpenMPT/soundlib/Load_mod.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/mod_specifications.h Modified: trunk/OpenMPT/mptrack/Ctrl_pat.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-11-06 17:48:42 UTC (rev 412) +++ trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-11-06 20:40:06 UTC (rev 413) @@ -54,6 +54,7 @@ BOOL UpdateScrollInfo(); void UpdateInfoText(); int GetFontWidth(); + void QueuePattern(CPoint pt); ORDERINDEX GetOrderFromPoint(const CRect& rect, const CPoint& pt) const; @@ -105,6 +106,7 @@ afx_msg void OnLButtonDblClk(UINT, CPoint); afx_msg void OnRButtonDown(UINT, CPoint); afx_msg void OnLButtonUp(UINT, CPoint); + afx_msg void OnMButtonDown(UINT, CPoint); afx_msg void OnMouseMove(UINT, CPoint); afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar*); afx_msg void OnSize(UINT nType, int cx, int cy); Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-11-06 17:48:42 UTC (rev 412) +++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-11-06 20:40:06 UTC (rev 413) @@ -36,6 +36,7 @@ ON_WM_LBUTTONDBLCLK() ON_WM_LBUTTONUP() ON_WM_RBUTTONDOWN() + ON_WM_MBUTTONDOWN() ON_WM_SETFOCUS() ON_WM_KILLFOCUS() ON_WM_HSCROLL() @@ -384,15 +385,17 @@ ord = 0; else { - if(ord > maxpat && ord < pSndFile->Order.GetIgnoreIndex()) - ord = pSndFile->Order.GetIgnoreIndex(); + const PATTERNINDEX nFirstInvalid = pSndFile->GetModSpecifications().hasIgnoreIndex ? pSndFile->Order.GetIgnoreIndex() : pSndFile->Order.GetInvalidPatIndex(); + if(ord > maxpat && ord < nFirstInvalid) + ord = nFirstInvalid; } } else if (nChar == '-') { + const PATTERNINDEX nFirstInvalid = pSndFile->GetModSpecifications().hasIgnoreIndex ? pSndFile->Order.GetIgnoreIndex() : pSndFile->Order.GetInvalidPatIndex(); ord--; if (ord < 0) ord = pSndFile->Order.GetInvalidPatIndex(); else - if ((ord > maxpat) && (ord < pSndFile->Order.GetIgnoreIndex())) ord = maxpat; + if ((ord > maxpat) && (ord < nFirstInvalid)) ord = maxpat; } if (ord != pSndFile->Order[m_nScrollPos]) { @@ -714,7 +717,7 @@ while (rect.left < rcClient.right) { bool bHighLight = ((bFocus) && (nIndex >= selection.nOrdLo && nIndex <= selection.nOrdHi)) ? true : false; - const PATTERNINDEX nPat = ((nIndex >= 0) && (nIndex < pSndFile->Order.GetLength())) ? pSndFile->Order[nIndex] : PATTERNINDEX_INVALID; + const PATTERNINDEX nPat = (nIndex < pSndFile->Order.GetLength()) ? pSndFile->Order[nIndex] : PATTERNINDEX_INVALID; if ((rect.right = rect.left + m_cxFont) > rcClient.right) rect.right = rcClient.right; rect.right--; if (bHighLight) { @@ -800,21 +803,7 @@ if (ih->CtrlPressed()) { // queue pattern - //m_nScrollPos2nd = ORDERINDEX_INVALID; - if (m_pModDoc) - { - CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); - ORDERINDEX nOrder = GetOrderFromPoint(rect, pt); - if ((nOrder >= 0) && (nOrder < pSndFile->Order.GetLength())) - { - if (pSndFile->m_nSeqOverride == static_cast<UINT>(nOrder)+1) { - pSndFile->m_nSeqOverride=0; - } else { - pSndFile->m_nSeqOverride = nOrder+1; - } - InvalidateRect(NULL, FALSE); - } - } + QueuePattern(pt); } else { // mark pattern (+skip to) @@ -858,7 +847,7 @@ if (rect.PtInRect(pt)) { ORDERINDEX n = GetOrderFromPoint(rect, pt); - if ((n >= 0) && (n == m_nDropPos) && (m_pModDoc)) + if ((n != ORDERINDEX_INVALID) && (n == m_nDropPos) && (m_pModDoc)) { // drag multiple orders (not quite as easy...) ORD_SELECTION selection = GetCurSel(false); @@ -934,9 +923,9 @@ n = GetOrderFromPoint(rect, pt); if (n >= pSndFile->Order.GetLength() || n >= pSndFile->GetModSpecifications().ordersMax) n = ORDERINDEX_INVALID; } - if (n != (int)m_nDropPos) + if (n != m_nDropPos) { - if (n >= 0) + if (n != ORDERINDEX_INVALID) { m_nDropPos = n; InvalidateRect(NULL, FALSE); @@ -1067,6 +1056,14 @@ } +void COrderList::OnMButtonDown(UINT nFlags, CPoint pt) +//---------------------------------------------------- +{ + UNREFERENCED_PARAMETER(nFlags); + QueuePattern(pt); +} + + void COrderList::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar*) //-------------------------------------------------------------- { @@ -1349,3 +1346,28 @@ m_pModDoc->SetModified(); m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this); } + + +void COrderList::QueuePattern(CPoint pt) +//-------------------------------------- +{ + CRect rect; + GetClientRect(&rect); + + if(!rect.PtInRect(pt)) return; + if (m_pModDoc == nullptr) return; + CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return; + + ORDERINDEX nOrder = GetOrderFromPoint(rect, pt); + + if (nOrder < pSndFile->Order.GetLength()) + { + if (pSndFile->m_nSeqOverride == static_cast<UINT>(nOrder) + 1) { + pSndFile->m_nSeqOverride = 0; + } else { + pSndFile->m_nSeqOverride = nOrder + 1; + } + InvalidateRect(NULL, FALSE); + } +} Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-11-06 17:48:42 UTC (rev 412) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-11-06 20:40:06 UTC (rev 413) @@ -329,6 +329,18 @@ } } + // If not supported, remove "+++" separator order items. + if(CSoundFile::GetModSpecifications(nNewType).hasIgnoreIndex == false) + { + for(ORDERINDEX nOrd = m_SndFile.Order.GetLengthTailTrimmed() - 1; nOrd > 0; nOrd--) + { + if(m_SndFile.Order[nOrd] == m_SndFile.Order.GetIgnoreIndex()) + { + m_SndFile.Order.Remove(nOrd, nOrd); + } + } + } + BEGIN_CRITICAL(); m_SndFile.ChangeModTypeTo(nNewType); if (!newTypeIsXM_IT_MPT && (m_SndFile.m_dwSongFlags & SONG_LINEARSLIDES)) Modified: trunk/OpenMPT/mptrack/View_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_gen.cpp 2009-11-06 17:48:42 UTC (rev 412) +++ trunk/OpenMPT/mptrack/View_gen.cpp 2009-11-06 20:40:06 UTC (rev 413) @@ -362,9 +362,13 @@ int pan = pSndFile->ChnSettings[nChn].nPan; m_sbPan[ichn].SetPos(pan/4); SetDlgItemInt(IDC_EDIT2+ichn*2, pan); + + // Channel name memcpy(s, pSndFile->ChnSettings[nChn].szName, MAX_CHANNELNAME); - s[MAX_CHANNELNAME-1] = 0; - SetDlgItemText(IDC_EDIT9+ichn, s); + s[MAX_CHANNELNAME - 1] = 0; + SetDlgItemText(IDC_EDIT9 + ichn, s); + ((CEdit*)(GetDlgItem(IDC_EDIT9 + ichn)))->LimitText(MAX_CHANNELNAME - 1); + // Channel effect m_CbnEffects[ichn].SetRedraw(FALSE); m_CbnEffects[ichn].ResetContent(); Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-11-06 17:48:42 UTC (rev 412) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-11-06 20:40:06 UTC (rev 413) @@ -108,6 +108,7 @@ ON_COMMAND(ID_PATTERN_AMPLIFY, OnPatternAmplify) ON_COMMAND(ID_CLEAR_SELECTION, OnClearSelectionFromMenu) ON_COMMAND(ID_SHOWTIMEATROW, OnShowTimeAtRow) + ON_COMMAND(ID_CHANNEL_RENAME, OnRenameChannel) ON_COMMAND_RANGE(ID_CHANGE_INSTRUMENT, ID_CHANGE_INSTRUMENT+MAX_INSTRUMENTS, OnSelectInstrument) ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateUndo) ON_COMMAND_RANGE(ID_PLUGSELECT, ID_PLUGSELECT+MAX_MIXPLUGINS, OnSelectPlugin) //rewbs.patPlugName @@ -1242,6 +1243,7 @@ AppendMenu(hMenu, MF_SEPARATOR, 0, ""); BuildRecordCtxMenu(hMenu, nChn, pModDoc); BuildChannelControlCtxMenu(hMenu); + BuildChannelMiscCtxMenu(hMenu, pSndFile); } } @@ -2533,13 +2535,13 @@ return; } - UINT nChn = GetChanFromCursor(m_nMenuParam); + CHANNELINDEX nChn = GetChanFromCursor(m_nMenuParam); CString str; str.Format("Remove channel %d?\nNote: Affects all patterns and no undo", nChn+1); if(CMainFrame::GetMainFrame()->MessageBox(str , "Remove channel", MB_YESNO | MB_ICONQUESTION) == IDYES) { BOOL chnMask[MAX_CHANNELS]; - for(UINT i = 0; i<MAX_CHANNELS; chnMask[i] = FALSE, i++) {} + for(CHANNELINDEX i = 0; i < MAX_CHANNELS; chnMask[i] = FALSE, i++) {} chnMask[nChn] = TRUE; pModDoc->RemoveChannels(chnMask); SetCurrentPattern(m_nPattern); //Updating the screen. @@ -4961,6 +4963,16 @@ } +bool CViewPattern::BuildChannelMiscCtxMenu(HMENU hMenu, CSoundFile* pSndFile) +//--------------------------------------------------------------------------- +{ + if((pSndFile->m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) == 0) return false; + AppendMenu(hMenu, MF_SEPARATOR, 0, 0); + AppendMenu(hMenu, MF_STRING, ID_CHANNEL_RENAME, "Rename channel"); + return true; +} + + UINT CViewPattern::GetSelectionStartRow() { //----------------------------------------- return min(GetRowFromCursor(m_dwBeginSel), GetRowFromCursor(m_dwEndSel)); @@ -5160,3 +5172,20 @@ iRow = m_nRow; } } + + +void CViewPattern::OnRenameChannel() +//---------------------------------- +{ + CModDoc *pModDoc = GetDocument(); + if(pModDoc == nullptr) return; + CSoundFile *pSndFile = pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return; + + CHANNELINDEX nChn = GetChanFromCursor(m_nMenuParam); + CChannelRenameDlg dlg(this, pSndFile->ChnSettings[nChn].szName, nChn + 1); + if(dlg.DoModal() != IDOK || dlg.bChanged == false) return; + + strcpy(pSndFile->ChnSettings[nChn].szName, dlg.m_sName); + pModDoc->UpdateAllViews(NULL, HINT_MODCHANNELS); +} Modified: trunk/OpenMPT/mptrack/View_pat.h =================================================================== --- trunk/OpenMPT/mptrack/View_pat.h 2009-11-06 17:48:42 UTC (rev 412) +++ trunk/OpenMPT/mptrack/View_pat.h 2009-11-06 20:40:06 UTC (rev 413) @@ -298,6 +298,7 @@ afx_msg void OnSelectInstrument(UINT nid); afx_msg void OnRunScript(); afx_msg void OnShowTimeAtRow(); + afx_msg void OnRenameChannel(); //}}AFX_MSG DECLARE_MESSAGE_MAP() @@ -324,6 +325,7 @@ bool BuildTransposeCtxMenu(HMENU hMenu, CInputHandler* ih); bool BuildSetInstCtxMenu(HMENU hMenu, CInputHandler* ih, CSoundFile* pSndFile); bool BuildAmplifyCtxMenu(HMENU hMenu, CInputHandler* ih); + bool BuildChannelMiscCtxMenu(HMENU hMenu, CSoundFile* pSndFile); UINT GetSelectionStartRow(); UINT GetSelectionEndRow(); Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-11-06 17:48:42 UTC (rev 412) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-11-06 20:40:06 UTC (rev 413) @@ -635,6 +635,43 @@ } //end rewbs.removeChansDlgCleanup + +/////////////////////////////////////////////////////////// +// CChannelRenameDlg + +BOOL CChannelRenameDlg::OnInitDialog() +//------------------------------------ +{ + CDialog::OnInitDialog(); + + CHAR s[32]; + wsprintf(s, "Set name for channel %d:", m_nChannel); + SetDlgItemText(IDC_STATIC_CHANNEL_NAME, s); + SetDlgItemText(IDC_EDIT_CHANNEL_NAME, m_sName); + ((CEdit*)(GetDlgItem(IDC_EDIT_CHANNEL_NAME)))->LimitText(MAX_CHANNELNAME - 1); + + return TRUE; +} + + +void CChannelRenameDlg::OnOK() +//---------------------------- +{ + CHAR sNewName[MAX_CHANNELNAME]; + GetDlgItemText(IDC_EDIT_CHANNEL_NAME, sNewName, MAX_CHANNELNAME); + if(!strcmp(sNewName, m_sName)) + { + bChanged = false; + CDialog::OnCancel(); + } else + { + strcpy(m_sName, sNewName); + bChanged = true; + CDialog::OnOK(); + } +} + + ////////////////////////////////////////////////////////////////////////////////////////// // Find/Replace Dialog Modified: trunk/OpenMPT/mptrack/dlg_misc.h =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.h 2009-11-06 17:48:42 UTC (rev 412) +++ trunk/OpenMPT/mptrack/dlg_misc.h 2009-11-06 20:40:06 UTC (rev 413) @@ -111,6 +111,33 @@ ///////////////////////////////////////////////////////////////////////// +// Channel rename dialog + +//===================================== +class CChannelRenameDlg: public CDialog +//===================================== +{ +protected: + CHANNELINDEX m_nChannel; + +public: + CHAR m_sName[MAX_CHANNELNAME]; + bool bChanged; + +public: + CChannelRenameDlg(CWnd *parent, CHAR *sName, CHANNELINDEX nChannel) : CDialog(IDD_CHANNEL_NAME, parent) + { + strcpy(m_sName, sName); + m_nChannel = nChannel; + bChanged = false; + } + + virtual BOOL OnInitDialog(); + virtual void OnOK(); +}; + + +///////////////////////////////////////////////////////////////////////// // Search/Replace #define PATSEARCH_NOTE 0x01 Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2009-11-06 17:48:42 UTC (rev 412) +++ trunk/OpenMPT/mptrack/mptrack.rc 2009-11-06 20:40:06 UTC (rev 413) @@ -70,7 +70,18 @@ GROUPBOX "Presets",IDC_STATIC,6,234,294,36 END +IDD_CHANNEL_NAME DIALOGEX 0, 0, 154, 58 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Channel name" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "IDC_STATIC_CHANNEL_NAME",IDC_STATIC_CHANNEL_NAME,6,6,138,8 + EDITTEXT IDC_EDIT_CHANNEL_NAME,6,18,138,12,ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,42,36,50,14 + PUSHBUTTON "Cancel",IDCANCEL,96,36,50,14 +END + ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO @@ -94,6 +105,14 @@ TOPMARGIN, 7 BOTTOMMARGIN, 274 END + + IDD_CHANNEL_NAME, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 147 + TOPMARGIN, 7 + BOTTOMMARGIN, 51 + END END #endif // APSTUDIO_INVOKED Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2009-11-06 17:48:42 UTC (rev 412) +++ trunk/OpenMPT/mptrack/resource.h 2009-11-06 20:40:06 UTC (rev 413) @@ -115,6 +115,7 @@ #define IDR_DEFAULT_KEYBINDINGS 519 #define IDR_BUILTIN_TUNINGS 520 #define IDD_CLEANUP_SONG 521 +#define IDD_CHANNEL_NAME 522 #define IDC_BUTTON1 1001 #define IDC_BUTTON2 1002 #define IDC_BUTTON3 1003 @@ -909,6 +910,8 @@ #define IDC_CHK_OPTIMIZE_SAMPLES 2406 #define IDC_CHK_MERGE_SEQUENCES 2408 #define IDC_CHECK_PT1X 2409 +#define IDC_STATIC_CHANNEL_NAME 2410 +#define IDC_EDIT_CHANNEL_NAME 2411 #define ID_FILE_NEWMOD 32771 #define ID_FILE_NEWXM 32772 #define ID_FILE_NEWS3M 32773 @@ -1145,18 +1148,19 @@ #define ID_CLEANUP_REARRANGESAMPLES 59228 #define ID_ORDERLIST_RENDER 59229 #define ID_EDIT_CLEANUP 59230 -#define ID_ORDERLIST_EDIT_COPY 59231 -#define ID_ORDERLIST_EDIT_CUT 59232 -#define ID_ORDERLIST_EDIT_PASTE 59233 +#define ID_ORDERLIST_EDIT_COPY 59231 +#define ID_ORDERLIST_EDIT_CUT 59232 +#define ID_ORDERLIST_EDIT_PASTE 59233 +#define ID_CHANNEL_RENAME 59234 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 522 -#define _APS_NEXT_COMMAND_VALUE 59234 -#define _APS_NEXT_CONTROL_VALUE 2410 +#define _APS_NEXT_RESOURCE_VALUE 523 +#define _APS_NEXT_COMMAND_VALUE 59235 +#define _APS_NEXT_CONTROL_VALUE 2412 #define _APS_NEXT_SYMED_VALUE 901 #endif #endif Modified: trunk/OpenMPT/soundlib/Load_med.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_med.cpp 2009-11-06 17:48:42 UTC (rev 412) +++ trunk/OpenMPT/soundlib/Load_med.cpp 2009-11-06 20:40:06 UTC (rev 413) @@ -636,7 +636,7 @@ } else { UINT nOrders, nSections; - UINT nTrks = BigEndianW(pmsh2->numtracks); + WORD nTrks = BigEndianW(pmsh2->numtracks); if ((nTrks >= 4) && (nTrks <= 32)) m_nChannels = nTrks; DWORD playseqtable = BigEndian(pmsh2->playseqtable); UINT numplayseqs = BigEndianW(pmsh2->numpseqs); Modified: trunk/OpenMPT/soundlib/Load_mod.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mod.cpp 2009-11-06 17:48:42 UTC (rev 412) +++ trunk/OpenMPT/soundlib/Load_mod.cpp 2009-11-06 20:40:06 UTC (rev 413) @@ -507,7 +507,7 @@ UINT nbp=0, norders=128; for (UINT iord=0; iord<128; iord++) { - if (Order[iord] == 0xFF) + if (Order[iord] == Order.GetInvalidPatIndex()) { norders = iord; break; Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-11-06 17:48:42 UTC (rev 412) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-11-06 20:40:06 UTC (rev 413) @@ -758,17 +758,21 @@ if(xmheader.channels > MAX_BASECHANNELS) xmheader.channels = MAX_BASECHANNELS; xmheader.channels = LittleEndianW(xmheader.channels); - xmheader.patterns = 0; - WORD nOrders = Order.GetLengthTailTrimmed(), nPatterns = 0; - xmheader.orders = LittleEndianW(nOrders); - xmheader.size = LittleEndian(xmheader.size + nOrders); - - for (i = 0; i < nOrders; i++) { // walk over orderlist and find last used pattern - if((Order[i] >= nPatterns) && (Order[i] < MAX_PATTERNS)) { - nPatterns = Order[i] + 1; + // Find out number of orders and patterns used. + // +++ and --- patterns are not taken into consideration as FastTracker does not support them. + ORDERINDEX nMaxOrds = 0; + PATTERNINDEX nPatterns = 0; + for(ORDERINDEX nOrd = 0; nOrd < Order.GetLengthTailTrimmed(); nOrd++) + { + if(Patterns.IsValidIndex(Order[nOrd])) + { + nMaxOrds++; + if(Order[nOrd] >= nPatterns) nPatterns = Order[nOrd] + 1; } } - xmheader.patterns = LittleEndianW(nPatterns); + xmheader.orders = LittleEndianW((WORD)nMaxOrds); + xmheader.patterns = LittleEndianW((WORD)nPatterns); + xmheader.size = LittleEndian((DWORD)(xmheader.size + nMaxOrds)); if(m_nInstruments > 0) xmheader.instruments = LittleEndianW(m_nInstruments); @@ -786,7 +790,15 @@ xmheader.speed = LittleEndianW(CLAMP(m_nDefaultSpeed, 1, 31)); fwrite(&xmheader, 1, sizeof(xmheader), f); - Order.WriteAsByte(f, nOrders); + // write order list (wihout +++ and ---, explained above) + for(ORDERINDEX nOrd = 0; nOrd < Order.GetLengthTailTrimmed(); nOrd++) + { + if(Patterns.IsValidIndex(Order[nOrd])) + { + BYTE nOrdval = static_cast<BYTE>(Order[nOrd]); + fwrite(&nOrdval, 1, sizeof(BYTE), f); + } + } // Writing patterns for (i = 0; i < nPatterns; i++) if (Patterns[i]) Modified: trunk/OpenMPT/soundlib/mod_specifications.h =================================================================== --- trunk/OpenMPT/soundlib/mod_specifications.h 2009-11-06 17:48:42 UTC (rev 412) +++ trunk/OpenMPT/soundlib/mod_specifications.h 2009-11-06 20:40:06 UTC (rev 413) @@ -41,6 +41,7 @@ UINT envelopePointsMax; // Maximum number of points of each envelope char commands[MAX_EFFECTS + 1]; // An array holding all commands this format supports; commands that are not supported are marked with "?" char volcommands[MAX_VOLCMDS + 1]; // dito, but for volume column + bool hasIgnoreIndex; // Does "+++" pattern exist? }; @@ -79,6 +80,7 @@ 240, //Envelope point count " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z\\:#", // Supported Effects " vpcdabuhlrgfe:o", // Supported Volume Column commands + true, // Has "+++" pattern }; @@ -112,6 +114,7 @@ 0, //No instrument envelopes " 0123456789ABCD?FF?E???????????????", // Supported Effects " ???????????????", // Supported Volume Column commands + false, // Doesn't have "+++" pattern }; // MOD with MPT extensions. @@ -143,6 +146,7 @@ 0, //No instrument envelopes " 0123456789ABCD?FF?E???????????????", // Supported Effects " ???????????????", // Supported Volume Column commands + false, // Doesn't have "+++" pattern }; const CModSpecifications xm = @@ -154,8 +158,8 @@ false, //No notecut. true, //Has noteoff. false, //No notefade. - 64, //Pattern max. - 128, //Order max. + 255, //Pattern max. + 255, //Order max. 1, //Channel min 32, //Channel max 32, //Min tempo @@ -173,6 +177,7 @@ 12, //Envelope point count " 0123456789ABCDRFFTE???GHK?YXPLZ\\:#", // Supported Effects " vpcdabuhlrg????", // Supported Volume Column commands + false, // Doesn't have "+++" pattern }; // XM with MPT extensions @@ -185,7 +190,7 @@ false, //No notecut. true, //Has noteoff. false, //No notefade. - 240, //Pattern max. + 255, //Pattern max. 256, //Order max. 1, //Channel min 127, //Channel max @@ -204,18 +209,20 @@ 12, //Envelope point count " 0123456789ABCDRFFTE???GHK?YXPLZ\\:#", // Supported Effects " vpcdabuhlrgfe:o", // Supported Volume Column commands + false, // Doesn't have "+++" pattern }; const CModSpecifications s3m = { + //TODO: Set correct values. "s3m", //File extension 13, //Minimum note index 120, //Maximum note index true, //Has notecut. false, //No noteoff. false, //No notefade. - 240, //Pattern max. - 256, //Order max. + 99, //Pattern max. + 255, //Order max. 1, //Channel min 32, //Channel max 32, //Min tempo @@ -233,6 +240,7 @@ 0, //No instrument envelopes " JFEGHLKRXODB?CQATI?SMNVW?U????????", // Supported Effects " vp?????????????", // Supported Volume Column commands + true, // Has "+++" pattern }; // S3M with MPT extensions @@ -246,7 +254,7 @@ false, //No noteoff. false, //No notefade. 240, //Pattern max. - 256, //Order max. + 255, //Order max. 1, //Channel min 32, //Channel max 32, //Min tempo @@ -264,6 +272,7 @@ 0, //No instrument envelopes " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z\\:#", // Supported Effects " vp?????????????", // Supported Volume Column commands + true, // Has "+++" pattern }; const CModSpecifications it = @@ -294,6 +303,7 @@ 25, //Envelope point count " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z???", // Supported Effects " vpcdab?h??gfe??", // Supported Volume Column commands + true, // Has "+++" pattern }; const CModSpecifications itEx = @@ -324,6 +334,7 @@ 25, //Envelope point count " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z\\:#", // Supported Effects " vpcdab?h??gfe:o", // Supported Volume Column commands + true, // Has "+++" pattern }; } //namespace ModSpecs This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2009-11-07 21:40:15
|
Revision: 415 http://modplug.svn.sourceforge.net/modplug/?rev=415&view=rev Author: saga-games Date: 2009-11-07 21:40:01 +0000 (Sat, 07 Nov 2009) Log Message: ----------- [Mod] Envelope editor: Middle line is also shown for volume envelope. [Ref] Envelope flags (enabled/loop/sustain/carry/filter) are now stored in the INSTRUMENTENVELOPE struct for ease of use. I did some tests, but I still hope this didn't break anything... [Ref] A lot of code cleanup and optimization due to the change above. Modified Paths: -------------- trunk/OpenMPT/mptrack/Childfrm.h trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/mptrack/View_ins.h trunk/OpenMPT/mptrack/view_com.cpp trunk/OpenMPT/soundlib/Dlsbank.cpp trunk/OpenMPT/soundlib/LOAD_DBM.CPP trunk/OpenMPT/soundlib/Load_ams.cpp trunk/OpenMPT/soundlib/Load_imf.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_mdl.cpp trunk/OpenMPT/soundlib/Load_mid.cpp trunk/OpenMPT/soundlib/Load_mt2.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/Sampleio.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 Modified: trunk/OpenMPT/mptrack/Childfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Childfrm.h 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/mptrack/Childfrm.h 2009-11-07 21:40:01 UTC (rev 415) @@ -48,7 +48,7 @@ typedef struct INSTRUMENTVIEWSTATE { DWORD cbStruct; - DWORD nEnv; + enmEnvelopeTypes nEnv; bool bGrid; } INSTRUMENTVIEWSTATE; Modified: trunk/OpenMPT/mptrack/CleanupSong.cpp =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp 2009-11-07 21:40:01 UTC (rev 415) @@ -862,21 +862,13 @@ pSndFile->Instruments[i]->nFadeOut = 256; pSndFile->Instruments[i]->nGlobalVol = 64; pSndFile->Instruments[i]->nPan = 128; - pSndFile->Instruments[i]->dwFlags &= ~ENV_SETPANNING; + pSndFile->Instruments[i]->dwFlags &= ~INS_SETPANNING; pSndFile->Instruments[i]->nMixPlug = 0; pSndFile->Instruments[i]->nVolSwing = 0; pSndFile->Instruments[i]->nPanSwing = 0; pSndFile->Instruments[i]->nCutSwing = 0; pSndFile->Instruments[i]->nResSwing = 0; - - //might be a good idea to leave those enabled... - /* - pSndFile->Instruments[i]->dwFlags &= ~ENV_VOLUME; - pSndFile->Instruments[i]->dwFlags &= ~ENV_PANNING; - pSndFile->Instruments[i]->dwFlags &= ~ENV_PITCH; - pSndFile->Instruments[i]->dwFlags &= ~ENV_FILTER; - */ } // reset samples Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-11-07 21:40:01 UTC (rev 415) @@ -1101,7 +1101,7 @@ SetDlgItemInt(IDC_EDIT8, pIns->nGlobalVol); // Panning SetDlgItemInt(IDC_EDIT9, pIns->nPan); - m_CheckPanning.SetCheck((pIns->dwFlags & ENV_SETPANNING) ? TRUE : FALSE); + m_CheckPanning.SetCheck((pIns->dwFlags & INS_SETPANNING) ? TRUE : FALSE); // Midi if (pIns->nMidiProgram>0 && pIns->nMidiProgram<=128) SetDlgItemInt(IDC_EDIT10, pIns->nMidiProgram); @@ -1774,8 +1774,8 @@ { const BOOL b = m_CheckPanning.GetCheck(); - if (b) pIns->dwFlags |= ENV_SETPANNING; - else pIns->dwFlags &= ~ENV_SETPANNING; + if (b) pIns->dwFlags |= INS_SETPANNING; + else pIns->dwFlags &= ~INS_SETPANNING; if(b && m_pSndFile->GetType() & MOD_TYPE_IT|MOD_TYPE_MPT) { Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-11-07 21:40:01 UTC (rev 415) @@ -1189,8 +1189,8 @@ //-------------------------------------------------------------- { if ((nInstr < 1) || (nInstr > m_SndFile.m_nInstruments) || (!m_SndFile.Instruments[nInstr])) return false; - if (bMute) m_SndFile.Instruments[nInstr]->dwFlags |= ENV_MUTE; - else m_SndFile.Instruments[nInstr]->dwFlags &= ~ENV_MUTE; + if (bMute) m_SndFile.Instruments[nInstr]->dwFlags |= INS_MUTE; + else m_SndFile.Instruments[nInstr]->dwFlags &= ~INS_MUTE; return true; } @@ -1267,7 +1267,7 @@ //----------------------------------------------------------- { if ((!nInstr) || (nInstr > m_SndFile.m_nInstruments) || (!m_SndFile.Instruments[nInstr])) return false; - return (m_SndFile.Instruments[nInstr]->dwFlags & ENV_MUTE) ? true : false; + return (m_SndFile.Instruments[nInstr]->dwFlags & INS_MUTE) ? true : false; } Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-11-07 21:40:01 UTC (rev 415) @@ -283,7 +283,10 @@ pIns->PanEnv.nSustainEnd = pIns->PanEnv.nSustainStart; bBrokenSustainLoop = true; } - pIns->dwFlags &= ~(ENV_SETPANNING|ENV_VOLCARRY|ENV_PANCARRY|ENV_PITCHCARRY|ENV_FILTER|ENV_PITCH); + pIns->VolEnv.dwFlags &= ~ENV_CARRY; + pIns->PanEnv.dwFlags &= ~ENV_CARRY; + pIns->PitchEnv.dwFlags &= ~(ENV_CARRY|ENV_ENABLED|ENV_FILTER); + pIns->dwFlags &= ~INS_SETPANNING; pIns->nIFC &= 0x7F; pIns->nIFR &= 0x7F; } @@ -1402,7 +1405,6 @@ CHAR s[4096]; MODINSTRUMENT *pIns; DWORD dwMemSize; - UINT bSus, bLoop, bCarry; if ((nIns < 1) || (nIns > m_SndFile.m_nInstruments) || (!m_SndFile.Instruments[nIns]) || (!pMainFrm)) return FALSE; BeginWaitCursor(); @@ -1414,27 +1416,17 @@ { case ENV_PANNING: pEnv = &pIns->PanEnv; - bLoop = (pIns->dwFlags & ENV_PANLOOP) ? 1 : 0; - bSus = (pIns->dwFlags & ENV_PANSUSTAIN) ? 1 : 0; - bCarry = (pIns->dwFlags & ENV_PANCARRY) ? 1 : 0; break; - case ENV_PITCH: pEnv = &pIns->PitchEnv; - bLoop = (pIns->dwFlags & ENV_PITCHLOOP) ? 1 : 0; - bSus = (pIns->dwFlags & ENV_PITCHSUSTAIN) ? 1 : 0; - bCarry = (pIns->dwFlags & ENV_PITCHCARRY) ? 1 : 0; break; - default: pEnv = &pIns->VolEnv; - bLoop = (pIns->dwFlags & ENV_VOLLOOP) ? 1 : 0; - bSus = (pIns->dwFlags & ENV_VOLSUSTAIN) ? 1 : 0; - bCarry = (pIns->dwFlags & ENV_VOLCARRY) ? 1 : 0; break; } + strcpy(s, pszEnvHdr); - wsprintf(s + strlen(s), pszEnvFmt, pEnv->nNodes, pEnv->nSustainStart, pEnv->nSustainEnd, pEnv->nLoopStart, pEnv->nLoopEnd, bSus, bLoop, bCarry); + wsprintf(s + strlen(s), pszEnvFmt, pEnv->nNodes, pEnv->nSustainStart, pEnv->nSustainEnd, pEnv->nLoopStart, pEnv->nLoopEnd, (pEnv->dwFlags & ENV_SUSTAIN) ? 1 : 0, (pEnv->dwFlags & ENV_LOOP) ? 1 : 0, (pEnv->dwFlags & ENV_CARRY) ? 1 : 0); for (UINT i = 0; i < pEnv->nNodes; i++) { if (strlen(s) >= sizeof(s)-32) break; @@ -1511,26 +1503,12 @@ { case ENV_PANNING: pEnv = &pIns->PanEnv; - pIns->dwFlags &= ~(ENV_PANLOOP|ENV_PANSUSTAIN|ENV_PANCARRY); - if (bLoop) pIns->dwFlags |= ENV_PANLOOP; - if (bSus) pIns->dwFlags |= ENV_PANSUSTAIN; - if (bCarry) pIns->dwFlags |= ENV_PANCARRY; break; - case ENV_PITCH: pEnv = &pIns->PitchEnv; - pIns->dwFlags &= ~(ENV_PITCHLOOP|ENV_PITCHSUSTAIN|ENV_PITCHCARRY); - if (bLoop) pIns->dwFlags |= ENV_PITCHLOOP; - if (bSus) pIns->dwFlags |= ENV_PITCHSUSTAIN; - if (bCarry) pIns->dwFlags |= ENV_PITCHCARRY; break; - default: pEnv = &pIns->VolEnv; - pIns->dwFlags &= ~(ENV_VOLLOOP|ENV_VOLSUSTAIN|ENV_VOLCARRY); - if (bLoop) pIns->dwFlags |= ENV_VOLLOOP; - if (bSus) pIns->dwFlags |= ENV_VOLSUSTAIN; - if (bCarry) pIns->dwFlags |= ENV_VOLCARRY; break; } pEnv->nNodes = nPoints; @@ -1539,6 +1517,7 @@ pEnv->nLoopStart = loopBegin; pEnv->nLoopEnd = loopEnd; pEnv->nReleaseNode = releaseNode; + pEnv->dwFlags = (bLoop ? ENV_LOOP : 0) | (bSus ? ENV_SUSTAIN : 0) | (bCarry ? ENV_CARRY: 0); int oldn = 0; for (UINT i=0; i<nPoints; i++) Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-11-07 21:40:01 UTC (rev 415) @@ -152,8 +152,8 @@ } -BOOL CViewInstrument::SetCurrentInstrument(INSTRUMENTINDEX nIns, UINT nEnv) -//------------------------------------------------------------------------- +BOOL CViewInstrument::SetCurrentInstrument(INSTRUMENTINDEX nIns, enmEnvelopeTypes nEnv) +//------------------------------------------------------------------------------------- { CModDoc *pModDoc = GetDocument(); DWORD dwNotify; @@ -244,27 +244,9 @@ UINT CViewInstrument::EnvGetValue(int nPoint) const //------------------------------------------------- { - CModDoc *pModDoc = GetDocument(); - if (pModDoc) - { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if ((pIns) && (nPoint >= 0)) - { - switch(m_nEnv) - { - case ENV_VOLUME: - if (nPoint < (int)pIns->VolEnv.nNodes) return pIns->VolEnv.Values[nPoint]; - break; - case ENV_PANNING: - if (nPoint < (int)pIns->PanEnv.nNodes) return pIns->PanEnv.Values[nPoint]; - break; - case ENV_PITCH: - if (nPoint < (int)pIns->PitchEnv.nNodes) return pIns->PitchEnv.Values[nPoint]; - break; - } - } - } + INSTRUMENTENVELOPE *envelope = GetEnvelopePtr(); + if(envelope == nullptr) return 0; + if(nPoint < (int)envelope->nNodes) return envelope->Values[nPoint]; return 0; } @@ -272,54 +254,39 @@ bool CViewInstrument::EnvSetValue(int nPoint, int nTick, int nValue) //------------------------------------------------------------------ { - bool bOk = false; - CModDoc *pModDoc = GetDocument(); - if (pModDoc) - { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if ((pIns) && (nPoint >= 0)) - { - LPWORD pPoints = NULL; - LPBYTE pData = NULL; - UINT maxpoints = 0; + if(nPoint < 0) return false; - INSTRUMENTENVELOPE *envelope = GetEnvelopePtr(); - if(envelope == nullptr) return false; + INSTRUMENTENVELOPE *envelope = GetEnvelopePtr(); + if(envelope == nullptr) return false; - maxpoints = envelope->nNodes; - pPoints = envelope->Ticks; - pData = envelope->Values; - - if (!nPoint) nTick = 0; - if ((nPoint < (int)maxpoints) && (pPoints) && (pData)) + bool bOK = false; + if (!nPoint) nTick = 0; + if (nPoint < (int)envelope->nNodes) + { + if (nTick >= 0) + { + int mintick = (nPoint) ? envelope->Ticks[nPoint-1] : 0; + int maxtick = envelope->Ticks[nPoint+1]; + if (nPoint + 1 == (int)envelope->nNodes) maxtick = 16383; + if (nTick < mintick) nTick = mintick; + if (nTick > maxtick) nTick = maxtick; + if (nTick != envelope->Ticks[nPoint]) { - if (nTick >= 0) - { - int mintick = (nPoint) ? pPoints[nPoint-1] : 0; - int maxtick = pPoints[nPoint+1]; - if (nPoint+1 == (int)maxpoints) maxtick = 16383; - if (nTick < mintick) nTick = mintick; - if (nTick > maxtick) nTick = maxtick; - if (nTick != pPoints[nPoint]) - { - pPoints[nPoint] = (WORD)nTick; - bOk = true; - } - } - if (nValue >= 0) - { - if (nValue > 64) nValue = 64; - if (nValue != pData[nPoint]) - { - pData[nPoint] = (BYTE)nValue; - bOk = true; - } - } + envelope->Ticks[nPoint] = (WORD)nTick; + bOK = true; } } + if (nValue >= 0) + { + if (nValue > 64) nValue = 64; + if (nValue != envelope->Values[nPoint]) + { + envelope->Values[nPoint] = (BYTE)nValue; + bOK = true; + } + } } - return bOk; + return bOK; } @@ -341,90 +308,16 @@ } -bool CViewInstrument::EnvGetLoop() const -//-------------------------------------- +// Return if an envelope flag is set. +bool CViewInstrument::EnvGetFlag(const DWORD dwFlag) const +//-------------------------------------------------------- { - CModDoc *pModDoc = GetDocument(); - if (pModDoc) - { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) - { - switch(m_nEnv) - { - case ENV_VOLUME: - if (pIns->dwFlags & ENV_VOLLOOP) return true; - break; - case ENV_PANNING: - if (pIns->dwFlags & ENV_PANLOOP) return true; - break; - case ENV_PITCH: - if (pIns->dwFlags & ENV_PITCHLOOP) return true; - break; - } - } - } + INSTRUMENTENVELOPE *pEnv = GetEnvelopePtr(); + if(pEnv != nullptr && pEnv->dwFlags & dwFlag) return true; return false; } -bool CViewInstrument::EnvGetSustain() const -//----------------------------------------- -{ - CModDoc *pModDoc = GetDocument(); - if (pModDoc) - { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) - { - switch(m_nEnv) - { - case ENV_VOLUME: - if (pIns->dwFlags & ENV_VOLSUSTAIN) return true; - break; - case ENV_PANNING: - if (pIns->dwFlags & ENV_PANSUSTAIN) return true; - break; - case ENV_PITCH: - if (pIns->dwFlags & ENV_PITCHSUSTAIN) return true; - break; - } - } - } - return false; -} - - -bool CViewInstrument::EnvGetCarry() const -//--------------------------------------- -{ - CModDoc *pModDoc = GetDocument(); - if (pModDoc) - { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) - { - switch(m_nEnv) - { - case ENV_VOLUME: - if (pIns->dwFlags & ENV_VOLCARRY) return true; - break; - case ENV_PANNING: - if (pIns->dwFlags & ENV_PANCARRY) return true; - break; - case ENV_PITCH: - if (pIns->dwFlags & ENV_PITCHCARRY) return true; - break; - } - } - } - return false; -} - - UINT CViewInstrument::EnvGetLoopStart() const //------------------------------------------- { @@ -469,7 +362,7 @@ { CSoundFile *pSndFile = pModDoc->GetSoundFile(); MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) return (pIns->dwFlags & ENV_VOLUME) ? true : false; + if (pIns) return (pIns->VolEnv.dwFlags & ENV_ENABLED) ? true : false; } return false; } @@ -483,7 +376,7 @@ { CSoundFile *pSndFile = pModDoc->GetSoundFile(); MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) return (pIns->dwFlags & ENV_PANNING) ? true : false; + if (pIns) return (pIns->PanEnv.dwFlags & ENV_ENABLED) ? true : false; } return false; } @@ -497,7 +390,7 @@ { CSoundFile *pSndFile = pModDoc->GetSoundFile(); MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) return ((pIns->dwFlags & (ENV_PITCH|ENV_FILTER)) == ENV_PITCH) ? true : false; + if (pIns) return ((pIns->PitchEnv.dwFlags & (ENV_ENABLED|ENV_FILTER)) == ENV_ENABLED) ? true : false; } return false; } @@ -511,7 +404,7 @@ { CSoundFile *pSndFile = pModDoc->GetSoundFile(); MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) return ((pIns->dwFlags & (ENV_PITCH|ENV_FILTER)) == (ENV_PITCH|ENV_FILTER)) ? true : false; + if (pIns) return ((pIns->PitchEnv.dwFlags & (ENV_ENABLED|ENV_FILTER)) == (ENV_ENABLED|ENV_FILTER)) ? true : false; } return false; } @@ -599,120 +492,57 @@ } -bool CViewInstrument::EnvSetLoop(bool bLoop) -//------------------------------------------ +// Enable or disable a flag of the current envelope +bool CViewInstrument::EnvSetFlag(const DWORD dwFlag, const bool bEnable) const +//---------------------------------------------------------------------------- { - CModDoc *pModDoc = GetDocument(); - if (pModDoc) + INSTRUMENTENVELOPE *envelope = GetEnvelopePtr(); + if(envelope == nullptr) return false; + if(bEnable) { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) + if(!(envelope->dwFlags & dwFlag)) { - DWORD dwMask = 0; - switch(m_nEnv) - { - case ENV_VOLUME: dwMask = ENV_VOLLOOP; break; - case ENV_PANNING: dwMask = ENV_PANLOOP; break; - case ENV_PITCH: dwMask = ENV_PITCHLOOP; break; - } - if (!dwMask) return false; - if (bLoop) - { - if (!(pIns->dwFlags & dwMask)) - { - pIns->dwFlags |= dwMask; - return true; - } - } else - { - if (pIns->dwFlags & dwMask) - { - pIns->dwFlags &= ~dwMask; - return true; - } - } + envelope->dwFlags |= dwFlag; + return true; } + } else + { + if(envelope->dwFlags & dwFlag) + { + envelope->dwFlags &= ~dwFlag; + return true; + } } return false; } -bool CViewInstrument::EnvSetSustain(bool bSustain) -//------------------------------------------------ +bool CViewInstrument::EnvToggleEnv(INSTRUMENTENVELOPE *pEnv, CSoundFile *pSndFile, MODINSTRUMENT *pIns, bool bEnable, BYTE cDefaultValue, DWORD dwChanFlag, DWORD dwExtraFlags) +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- { - CModDoc *pModDoc = GetDocument(); - if (pModDoc) + if(pEnv == nullptr) return false; + + if (bEnable) { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) + pEnv->dwFlags |= (ENV_ENABLED|dwExtraFlags); + if (!pEnv->nNodes) { - DWORD dwMask = 0; - switch(m_nEnv) - { - case ENV_VOLUME: dwMask = ENV_VOLSUSTAIN; break; - case ENV_PANNING: dwMask = ENV_PANSUSTAIN; break; - case ENV_PITCH: dwMask = ENV_PITCHSUSTAIN; break; - } - if (!dwMask) return false; - if (bSustain) - { - if (!(pIns->dwFlags & dwMask)) - { - pIns->dwFlags |= dwMask; - return true; - } - } else - { - if (pIns->dwFlags & dwMask) - { - pIns->dwFlags &= ~dwMask; - return true; - } - } + pEnv->Values[0] = pEnv->Values[1] = cDefaultValue; + pEnv->Ticks[0] = 0; + pEnv->Ticks[1] = 10; + pEnv->nNodes = 2; + InvalidateRect(NULL, FALSE); } - } - return false; -} - - -bool CViewInstrument::EnvSetCarry(bool bCarry) -//-------------------------------------------- -{ - CModDoc *pModDoc = GetDocument(); - if (pModDoc) + } else { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) + pEnv->dwFlags &= ~(ENV_ENABLED|dwExtraFlags); + for(CHANNELINDEX nChn = 0; nChn < MAX_CHANNELS; nChn++) { - DWORD dwMask = 0; - switch(m_nEnv) - { - case ENV_VOLUME: dwMask = ENV_VOLCARRY; break; - case ENV_PANNING: dwMask = ENV_PANCARRY; break; - case ENV_PITCH: dwMask = ENV_PITCHCARRY; break; - } - if (!dwMask) return false; - if (bCarry) - { - if (!(pIns->dwFlags & dwMask)) - { - pIns->dwFlags |= dwMask; - return true; - } - } else - { - if (pIns->dwFlags & dwMask) - { - pIns->dwFlags &= ~dwMask; - return true; - } - } + if(pSndFile->Chn[nChn].pModInstrument == pIns) + pSndFile->Chn[nChn].dwFlags &= ~dwChanFlag; } } - return false; + return true; } @@ -720,37 +550,13 @@ //---------------------------------------------- { CModDoc *pModDoc = GetDocument(); - if (pModDoc) - { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) - { - if (bEnable) - { - pIns->dwFlags |= ENV_VOLUME; - if (!pIns->VolEnv.nNodes) - { - pIns->VolEnv.Values[0] = 64; - pIns->VolEnv.Values[1] = 64; - pIns->VolEnv.Ticks[0] = 0; - pIns->VolEnv.Ticks[1] = 10; - pIns->VolEnv.nNodes = 2; - InvalidateRect(NULL, FALSE); - } - } 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; - } - } - return false; + if(pModDoc == nullptr) return false; + CSoundFile *pSndFile = pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return false; + MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; + if(pIns == nullptr) return false; + + return EnvToggleEnv(&pIns->VolEnv, pSndFile, pIns, bEnable, 64, CHN_VOLENV); } @@ -758,37 +564,13 @@ //---------------------------------------------- { CModDoc *pModDoc = GetDocument(); - if (pModDoc) - { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) - { - if (bEnable) - { - pIns->dwFlags |= ENV_PANNING; - if (!pIns->PanEnv.nNodes) - { - pIns->PanEnv.Values[0] = 32; - pIns->PanEnv.Values[1] = 32; - pIns->PanEnv.Ticks[0] = 0; - pIns->PanEnv.Ticks[1] = 10; - pIns->PanEnv.nNodes = 2; - InvalidateRect(NULL, FALSE); - } - } 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; - } - } - return false; + if(pModDoc == nullptr) return false; + CSoundFile *pSndFile = pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return false; + MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; + if(pIns == nullptr) return false; + + return EnvToggleEnv(&pIns->PanEnv, pSndFile, pIns, bEnable, 32, CHN_PANENV); } @@ -796,38 +578,14 @@ //------------------------------------------------ { CModDoc *pModDoc = GetDocument(); - if (pModDoc) - { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) - { - if ((bEnable) && (pSndFile->m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) - { - pIns->dwFlags |= ENV_PITCH; - pIns->dwFlags &= ~ENV_FILTER; - if (!pIns->PitchEnv.nNodes) - { - pIns->PitchEnv.Values[0] = 32; - pIns->PitchEnv.Values[1] = 32; - pIns->PitchEnv.Ticks[0] = 0; - pIns->PitchEnv.Ticks[1] = 10; - pIns->PitchEnv.nNodes = 2; - InvalidateRect(NULL, FALSE); - } - } 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; - } - } - return false; + if(pModDoc == nullptr) return false; + CSoundFile *pSndFile = pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return false; + MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; + if(pIns == nullptr) return false; + + pIns->PitchEnv.dwFlags &= ~ENV_FILTER; + return EnvToggleEnv(&pIns->PitchEnv, pSndFile, pIns, bEnable, 32, CHN_PITCHENV); } @@ -835,38 +593,14 @@ //------------------------------------------------- { CModDoc *pModDoc = GetDocument(); - if (pModDoc) - { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; - if (pIns) - { - if ((bEnable) && (pSndFile->m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) - { - pIns->dwFlags |= (ENV_PITCH|ENV_FILTER); - if (!pIns->PitchEnv.nNodes) - { - pIns->PitchEnv.Values[0] = 64; - pIns->PitchEnv.Values[1] = 64; - pIns->PitchEnv.Ticks[0] = 0; - pIns->PitchEnv.Ticks[1] = 10; - pIns->PitchEnv.nNodes = 2; - InvalidateRect(NULL, FALSE); - } - } 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; - } - } - return false; + if(pModDoc == nullptr) return false; + CSoundFile *pSndFile = pModDoc->GetSoundFile(); + if(pSndFile == nullptr) return false; + MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument]; + if(pIns == nullptr) return false; + + pIns->PitchEnv.dwFlags &= ~ENV_FILTER; + return EnvToggleEnv(&pIns->PitchEnv, pSndFile, pIns, bEnable, 64, CHN_PITCHENV, ENV_FILTER); } @@ -1123,11 +857,11 @@ { DrawGrid(&m_dcMemMain, pSndFile->m_nMusicSpeed); } - if (m_nEnv != ENV_VOLUME) - { - m_dcMemMain.MoveTo(0, ymed); - m_dcMemMain.LineTo(m_rcClient.right, ymed); - } + + // Middle line (half volume or pitch / panning center) + m_dcMemMain.MoveTo(0, ymed); + m_dcMemMain.LineTo(m_rcClient.right, ymed); + m_dcMemMain.SelectObject(CMainFrame::penDarkGray); // Drawing Loop Start/End if (EnvGetLoop()) @@ -1226,7 +960,7 @@ } bool CViewInstrument::EnvRemovePoint() -//-------------------------------------- +//------------------------------------ { CModDoc *pModDoc = GetDocument(); if ((pModDoc) && (m_nDragItem) && (m_nDragItem-1 <= EnvGetLastPoint())) @@ -1292,7 +1026,7 @@ cDefaultValue = 32; break; case ENV_PITCH: - cDefaultValue = (pIns->dwFlags & ENV_FILTER) ? 64 : 32; + cDefaultValue = (pIns->PitchEnv.dwFlags & ENV_FILTER) ? 64 : 32; break; default: return false; @@ -1659,7 +1393,7 @@ if (nVal > 64) nVal = 64; if (nTick < 0) nTick = 0; if (nTick <= EnvGetReleaseNodeTick() + 1 || EnvGetReleaseNode() == ENV_RELEASE_NODE_UNSET) { - int displayVal = (m_nEnv != ENV_VOLUME && !(m_nEnv == ENV_PITCH && (pIns->dwFlags & ENV_FILTER))) ? nVal - 32 : nVal; + int displayVal = (m_nEnv != ENV_VOLUME && !(m_nEnv == ENV_PITCH && (pIns->PitchEnv.dwFlags & ENV_FILTER))) ? nVal - 32 : nVal; wsprintf(s, "Tick %d, [%d]", nTick, displayVal); } else { int displayVal = (nVal - EnvGetReleaseNodeValue()) * 2; @@ -2468,10 +2202,11 @@ } + +// Get a pointer to the currently selected envelope. INSTRUMENTENVELOPE *CViewInstrument::GetEnvelopePtr() const //--------------------------------------------------------- { - // Get a pointer to the currently selected envelope. // First do some standard checks... CModDoc *pModDoc = GetDocument(); if(pModDoc == nullptr) return nullptr; Modified: trunk/OpenMPT/mptrack/View_ins.h =================================================================== --- trunk/OpenMPT/mptrack/View_ins.h 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/mptrack/View_ins.h 2009-11-07 21:40:01 UTC (rev 415) @@ -18,7 +18,8 @@ RECT m_rcClient; bool m_baPlayingNote[128]; //rewbs.instViewNNA INSTRUMENTINDEX m_nInstrument; - UINT m_nEnv, m_nDragItem, m_nBtnMouseOver, m_nPlayingChannel; + enmEnvelopeTypes m_nEnv; + UINT m_nDragItem, m_nBtnMouseOver, m_nPlayingChannel; DWORD m_dwStatus; DWORD m_NcButtonState[ENV_LEFTBAR_BUTTONS]; DWORD m_dwNotifyPos[MAX_CHANNELS]; @@ -39,37 +40,64 @@ CViewInstrument(); DECLARE_SERIAL(CViewInstrument) -public: - void UpdateScrollSize(); - BOOL SetCurrentInstrument(INSTRUMENTINDEX nIns, UINT m_nEnv=0); - INSTRUMENTENVELOPE *GetEnvelopePtr() const; +protected: + //////////////////////// + // Envelope get stuff + + // Flags + bool EnvGetFlag(const DWORD dwFlag) const; + bool EnvGetLoop() const {return EnvGetFlag(ENV_LOOP);}; + bool EnvGetSustain() const {return EnvGetFlag(ENV_SUSTAIN);}; + bool EnvGetCarry() const {return EnvGetFlag(ENV_CARRY);}; + + // Misc. UINT EnvGetTick(int nPoint) const; UINT EnvGetValue(int nPoint) const; UINT EnvGetLastPoint() const; UINT EnvGetNumPoints() const; + + // Get loop points UINT EnvGetLoopStart() const; UINT EnvGetLoopEnd() const; UINT EnvGetSustainStart() const; UINT EnvGetSustainEnd() const; - bool EnvGetLoop() const; - bool EnvGetSustain() const; - bool EnvGetCarry() const; + + // Get envelope status bool EnvGetVolEnv() const; bool EnvGetPanEnv() const; bool EnvGetPitchEnv() const; bool EnvGetFilterEnv() const; + + //////////////////////// + // Envelope set stuff + + // Flags + bool EnvSetFlag(const DWORD dwFlag, const bool bEnable) const; + bool EnvSetLoop(bool bEnable) const {return EnvSetFlag(ENV_LOOP, bEnable);}; + bool EnvSetSustain(bool bEnable) const {return EnvSetFlag(ENV_SUSTAIN, bEnable);}; + bool EnvSetCarry(bool bEnable) const {return EnvSetFlag(ENV_CARRY, bEnable);}; + + // Misc. bool EnvSetValue(int nPoint, int nTick=-1, int nValue=-1); + + // Set loop points bool EnvSetLoopStart(int nPoint); bool EnvSetLoopEnd(int nPoint); bool EnvSetSustainStart(int nPoint); bool EnvSetSustainEnd(int nPoint); - bool EnvSetLoop(bool bLoop); - bool EnvSetSustain(bool bSustain); - bool EnvSetCarry(bool bCarry); + + // Set envelope status + bool EnvToggleEnv(INSTRUMENTENVELOPE *pEnv, CSoundFile *pSndFile, MODINSTRUMENT *pIns, bool bEnable, BYTE cDefaultValue, DWORD dwChanFlag, DWORD dwExtraFlags = 0); bool EnvSetVolEnv(bool bEnable); bool EnvSetPanEnv(bool bEnable); bool EnvSetPitchEnv(bool bEnable); bool EnvSetFilterEnv(bool bEnable); + + //////////////////////// + // Misc stuff + void UpdateScrollSize(); + BOOL SetCurrentInstrument(INSTRUMENTINDEX nIns, enmEnvelopeTypes m_nEnv = ENV_VOLUME); + INSTRUMENTENVELOPE *GetEnvelopePtr() const; UINT EnvInsertPoint(); bool EnvRemovePoint(); int TickToScreen(int nTick) const; Modified: trunk/OpenMPT/mptrack/view_com.cpp =================================================================== --- trunk/OpenMPT/mptrack/view_com.cpp 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/mptrack/view_com.cpp 2009-11-07 21:40:01 UTC (rev 415) @@ -383,9 +383,9 @@ case INSLIST_ENVELOPES: if (pIns) { - if (pIns->dwFlags & ENV_VOLUME) strcat(s, "Vol"); - if (pIns->dwFlags & ENV_PANNING) { if (s[0]) strcat(s, ", "); strcat(s, "Pan"); } - if (pIns->dwFlags & ENV_PITCH) { if (s[0]) strcat(s, ", "); strcat(s, (pIns->dwFlags & ENV_FILTER) ? "Filter" : "Pitch"); } + if (pIns->VolEnv.dwFlags & ENV_ENABLED) strcat(s, "Vol"); + if (pIns->PanEnv.dwFlags & ENV_ENABLED) { if (s[0]) strcat(s, ", "); strcat(s, "Pan"); } + if (pIns->PitchEnv.dwFlags & ENV_ENABLED) { if (s[0]) strcat(s, ", "); strcat(s, (pIns->PitchEnv.dwFlags & ENV_FILTER) ? "Filter" : "Pitch"); } } break; case INSLIST_FILENAME: Modified: trunk/OpenMPT/soundlib/Dlsbank.cpp =================================================================== --- trunk/OpenMPT/soundlib/Dlsbank.cpp 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/soundlib/Dlsbank.cpp 2009-11-07 21:40:01 UTC (rev 415) @@ -1772,7 +1772,7 @@ // Volume Envelope if ((part->wVolAttack) || (part->wVolDecay < 20*50) || (part->nVolSustainLevel) || (part->wVolRelease < 20*50)) { - pIns->dwFlags |= ENV_VOLUME; + pIns->VolEnv.dwFlags |= ENV_ENABLED; // Delay section // -> DLS level 2 // Attack section @@ -1830,10 +1830,10 @@ nPoint++; } } - pIns->dwFlags |= ENV_VOLSUSTAIN; + pIns->VolEnv.dwFlags |= ENV_SUSTAIN; } else { - pIns->dwFlags |= ENV_VOLSUSTAIN; + pIns->VolEnv.dwFlags |= ENV_SUSTAIN; pIns->VolEnv.Ticks[nPoint] = (WORD)(pIns->VolEnv.Ticks[nPoint-1]+1); pIns->VolEnv.Values[nPoint] = pIns->VolEnv.Values[nPoint-1]; nPoint++; @@ -1884,10 +1884,10 @@ if (pDlsIns->ulBank & F_INSTRUMENT_DRUMS) { // Create a default envelope for drums - pIns->dwFlags &= ~ENV_VOLSUSTAIN; - if (!(pIns->dwFlags & ENV_VOLUME)) + pIns->VolEnv.dwFlags &= ~ENV_SUSTAIN; + if (!(pIns->VolEnv.dwFlags & ENV_ENABLED)) { - pIns->dwFlags |= ENV_VOLUME; + pIns->VolEnv.dwFlags |= ENV_ENABLED; pIns->VolEnv.Ticks[0] = 0; pIns->VolEnv.Values[0] = 64; pIns->VolEnv.Ticks[1] = 5; Modified: trunk/OpenMPT/soundlib/LOAD_DBM.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_DBM.CPP 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/soundlib/LOAD_DBM.CPP 2009-11-07 21:40:01 UTC (rev 415) @@ -166,7 +166,7 @@ pIns->nGlobalVol = 64; pIns->nPan = BigEndianW(pih->panning); if ((pIns->nPan) && (pIns->nPan < 256)) - pIns->dwFlags = ENV_SETPANNING; + pIns->dwFlags = INS_SETPANNING; else pIns->nPan = 128; pIns->nPPC = 5*12; @@ -218,9 +218,9 @@ { MODINSTRUMENT *pIns = Instruments[nins]; - if (peh->flags & 1) pIns->dwFlags |= ENV_VOLUME; - if (peh->flags & 2) pIns->dwFlags |= ENV_VOLSUSTAIN; - if (peh->flags & 4) pIns->dwFlags |= ENV_VOLLOOP; + if (peh->flags & 1) pIns->VolEnv.dwFlags |= ENV_ENABLED; + if (peh->flags & 2) pIns->VolEnv.dwFlags |= ENV_SUSTAIN; + if (peh->flags & 4) pIns->VolEnv.dwFlags |= ENV_LOOP; pIns->VolEnv.nNodes = peh->numpoints + 1; if (pIns->VolEnv.nNodes > MAX_ENVPOINTS) pIns->VolEnv.nNodes = MAX_ENVPOINTS; pIns->VolEnv.nLoopStart = peh->loopbegin; Modified: trunk/OpenMPT/soundlib/Load_ams.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_ams.cpp 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/soundlib/Load_ams.cpp 2009-11-07 21:40:01 UTC (rev 415) @@ -401,9 +401,9 @@ } pIns->nFadeOut = (((lpStream[dwMemPos+2] & 0x0F) << 8) | (lpStream[dwMemPos+1])) << 3; UINT envflags = lpStream[dwMemPos+3]; - if (envflags & 0x01) pIns->dwFlags |= ENV_VOLLOOP; - if (envflags & 0x02) pIns->dwFlags |= ENV_VOLSUSTAIN; - if (envflags & 0x04) pIns->dwFlags |= ENV_VOLUME; + if (envflags & 0x01) pIns->VolEnv.dwFlags |= ENV_LOOP; + if (envflags & 0x02) pIns->VolEnv.dwFlags |= ENV_SUSTAIN; + if (envflags & 0x04) pIns->VolEnv.dwFlags |= ENV_ENABLED; dwMemPos += 5; // Read Samples for (UINT ismp=0; ismp<pSmp->samples; ismp++) Modified: trunk/OpenMPT/soundlib/Load_imf.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_imf.cpp 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/soundlib/Load_imf.cpp 2009-11-07 21:40:01 UTC (rev 415) @@ -135,6 +135,7 @@ }; static void import_imf_effect(MODCOMMAND *note) +//--------------------------------------------- { BYTE n; // fix some of them @@ -224,17 +225,13 @@ } } -static unsigned int envflags[3][3] = { - {ENV_VOLUME, ENV_VOLSUSTAIN, ENV_VOLLOOP}, - {ENV_PANNING, ENV_PANSUSTAIN, ENV_PANLOOP}, - {ENV_PITCH | ENV_FILTER, ENV_PITCHSUSTAIN, ENV_PITCHLOOP}, -}; - -static void load_imf_envelope(MODINSTRUMENT *ins, INSTRUMENTENVELOPE *env, IMFINSTRUMENT *imfins, int e) +static void load_imf_envelope(INSTRUMENTENVELOPE *env, IMFINSTRUMENT *imfins, int e) +//---------------------------------------------------------------------------------- { UINT min = 0; // minimum tick value for next node int shift = (e == IMF_ENV_VOL) ? 0 : 2; + env->dwFlags = ((imfins->env[e].flags & 1) ? ENV_ENABLED : 0) | ((imfins->env[e].flags & 2) ? ENV_SUSTAIN : 0) | ((imfins->env[e].flags & 4) ? ENV_LOOP : 0); env->nNodes = CLAMP(imfins->env[e].points, 2, 25); env->nLoopStart = imfins->env[e].loop_start; env->nLoopEnd = imfins->env[e].loop_end; @@ -249,16 +246,10 @@ env->Values[n] = (BYTE)min(nValue, 64); min = nTick + 1; } - // this would be less retarded if the envelopes all had their own flags... - if (imfins->env[e].flags & 1) - ins->dwFlags |= envflags[e][0]; - if (imfins->env[e].flags & 2) - ins->dwFlags |= envflags[e][1]; - if (imfins->env[e].flags & 4) - ins->dwFlags |= envflags[e][2]; } bool CSoundFile::ReadIMF(const LPCBYTE lpStream, const DWORD dwMemLength) +//----------------------------------------------------------------------- { #define ASSERT_CAN_READ(x) \ if( dwMemPos > dwMemLength || x > dwMemLength - dwMemPos ) return false; @@ -487,12 +478,13 @@ pIns->nFadeOut = imfins.fadeout; pIns->nGlobalVol = 128; - load_imf_envelope(pIns, &pIns->VolEnv, &imfins, IMF_ENV_VOL); - load_imf_envelope(pIns, &pIns->PanEnv, &imfins, IMF_ENV_PAN); - load_imf_envelope(pIns, &pIns->PitchEnv, &imfins, IMF_ENV_FILTER); + load_imf_envelope(&pIns->VolEnv, &imfins, IMF_ENV_VOL); + load_imf_envelope(&pIns->PanEnv, &imfins, IMF_ENV_PAN); + load_imf_envelope(&pIns->PitchEnv, &imfins, IMF_ENV_FILTER); + if((pIns->PitchEnv.dwFlags & ENV_ENABLED) != 0) pIns->PitchEnv.dwFlags |= ENV_FILTER; // hack to get === to stop notes (from modplug's xm loader) - if (!(pIns->dwFlags & ENV_VOLUME) && !pIns->nFadeOut) + if (!(pIns->VolEnv.dwFlags & ENV_ENABLED) && !pIns->nFadeOut) pIns->nFadeOut = 8192; // read this instrument's samples Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-11-07 21:40:01 UTC (rev 415) @@ -216,10 +216,37 @@ return (value > 9) ? 9 : value; } +// Convert MPT's internal nvelope format into an IT/MPTM envelope. +void MPTEnvToIT(const INSTRUMENTENVELOPE *mptEnv, ITENVELOPE *itEnv, const BYTE envOffset) +//---------------------------------------------------------------------------------------- +{ + if(mptEnv->dwFlags & ENV_ENABLED) itEnv->flags |= 1; + if(mptEnv->dwFlags & ENV_LOOP) itEnv->flags |= 2; + if(mptEnv->dwFlags & ENV_SUSTAIN) itEnv->flags |= 4; + if(mptEnv->dwFlags & ENV_CARRY) itEnv->flags |= 8; + itEnv->num = (BYTE)min(mptEnv->nNodes, 25); + itEnv->lpb = (BYTE)mptEnv->nLoopStart; + itEnv->lpe = (BYTE)mptEnv->nLoopEnd; + itEnv->slb = (BYTE)mptEnv->nSustainStart; + itEnv->sle = (BYTE)mptEnv->nSustainEnd; + + // Attention: Full MPTM envelope is stored in extended instrument properties + for (UINT ev = 0; ev < 25; ev++) + { + itEnv->data[ev * 3] = mptEnv->Values[ev] - envOffset; + itEnv->data[ev * 3 + 1] = mptEnv->Ticks[ev] & 0xFF; + itEnv->data[ev * 3 + 2] = mptEnv->Ticks[ev] >> 8; + } +} + // Convert IT/MPTM envelope data into MPT's internal envelope format - To be used by ITInstrToMPT() void ITEnvToMPT(const ITENVELOPE *itEnv, INSTRUMENTENVELOPE *mptEnv, const BYTE envOffset, const int iEnvMax) //----------------------------------------------------------------------------------------------------------- { + if(itEnv->flags & 1) mptEnv->dwFlags |= ENV_ENABLED; + if(itEnv->flags & 2) mptEnv->dwFlags |= ENV_LOOP; + if(itEnv->flags & 4) mptEnv->dwFlags |= ENV_SUSTAIN; + if(itEnv->flags & 8) mptEnv->dwFlags |= ENV_CARRY; mptEnv->nNodes = min(itEnv->num, iEnvMax); mptEnv->nLoopStart = itEnv->lpb; mptEnv->nLoopEnd = itEnv->lpe; @@ -262,9 +289,9 @@ if (note < 128) pIns->NoteMap[j] = note+1; else if (note >= 0xFE) pIns->NoteMap[j] = note; } - if (pis->flags & 0x01) pIns->dwFlags |= ENV_VOLUME; - if (pis->flags & 0x02) pIns->dwFlags |= ENV_VOLLOOP; - if (pis->flags & 0x04) pIns->dwFlags |= ENV_VOLSUSTAIN; + if (pis->flags & 0x01) pIns->VolEnv.dwFlags |= ENV_ENABLED; + if (pis->flags & 0x02) pIns->VolEnv.dwFlags |= ENV_LOOP; + if (pis->flags & 0x04) pIns->VolEnv.dwFlags |= ENV_SUSTAIN; pIns->VolEnv.nLoopStart = pis->vls; pIns->VolEnv.nLoopEnd = pis->vle; pIns->VolEnv.nSustainStart = pis->sls; @@ -373,24 +400,12 @@ // Volume Envelope - if (pis->volenv.flags & 1) pIns->dwFlags |= ENV_VOLUME; - if (pis->volenv.flags & 2) pIns->dwFlags |= ENV_VOLLOOP; - if (pis->volenv.flags & 4) pIns->dwFlags |= ENV_VOLSUSTAIN; - if (pis->volenv.flags & 8) pIns->dwFlags |= ENV_VOLCARRY; ITEnvToMPT(&pis->volenv, &pIns->VolEnv, 0, iEnvMax); // Panning Envelope - if (pis->panenv.flags & 1) pIns->dwFlags |= ENV_PANNING; - if (pis->panenv.flags & 2) pIns->dwFlags |= ENV_PANLOOP; - if (pis->panenv.flags & 4) pIns->dwFlags |= ENV_PANSUSTAIN; - if (pis->panenv.flags & 8) pIns->dwFlags |= ENV_PANCARRY; ITEnvToMPT(&pis->panenv, &pIns->PanEnv, 32, iEnvMax); // Pitch Envelope - if (pis->pitchenv.flags & 1) pIns->dwFlags |= ENV_PITCH; - if (pis->pitchenv.flags & 2) pIns->dwFlags |= ENV_PITCHLOOP; - if (pis->pitchenv.flags & 4) pIns->dwFlags |= ENV_PITCHSUSTAIN; - if (pis->pitchenv.flags & 8) pIns->dwFlags |= ENV_PITCHCARRY; - if (pis->pitchenv.flags & 0x80) pIns->dwFlags |= ENV_FILTER; ITEnvToMPT(&pis->pitchenv, &pIns->PitchEnv, 32, iEnvMax); + if (pis->pitchenv.flags & 0x80) pIns->PitchEnv.dwFlags |= ENV_FILTER; pIns->nNNA = pis->nna; pIns->nDCT = pis->dct; @@ -406,11 +421,11 @@ pIns->nPluginVelocityHandling = PLUGIN_VELOCITYHANDLING_CHANNEL; pIns->nPluginVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE; if (pIns->nPan > 256) pIns->nPan = 128; - if (pis->dfp < 0x80) pIns->dwFlags |= ENV_SETPANNING; + if (pis->dfp < 0x80) pIns->dwFlags |= INS_SETPANNING; } - if ((pIns->VolEnv.nLoopStart >= iEnvMax) || (pIns->VolEnv.nLoopEnd >= iEnvMax)) pIns->dwFlags &= ~ENV_VOLLOOP; - if ((pIns->VolEnv.nSustainStart >= iEnvMax) || (pIns->VolEnv.nSustainEnd >= iEnvMax)) pIns->dwFlags &= ~ENV_VOLSUSTAIN; + if ((pIns->VolEnv.nLoopStart >= iEnvMax) || (pIns->VolEnv.nLoopEnd >= iEnvMax)) pIns->VolEnv.dwFlags &= ~ENV_LOOP; + if ((pIns->VolEnv.nSustainStart >= iEnvMax) || (pIns->VolEnv.nSustainEnd >= iEnvMax)) pIns->VolEnv.dwFlags &= ~ENV_SUSTAIN; return returnVal; //return offset } @@ -1995,7 +2010,7 @@ iti.ppc = pIns->nPPC; iti.gbv = (BYTE)(pIns->nGlobalVol << 1); iti.dfp = (BYTE)pIns->nPan >> 2; - if (!(pIns->dwFlags & ENV_SETPANNING)) iti.dfp |= 0x80; + if (!(pIns->dwFlags & INS_SETPANNING)) iti.dfp |= 0x80; iti.rv = pIns->nVolSwing; iti.rp = pIns->nPanSwing; iti.ifc = pIns->nIFC; @@ -2015,49 +2030,12 @@ keyboardex[i] = (smp>>8); } else keyboardex[i] = 0; // Writing Volume envelope - if (pIns->dwFlags & ENV_VOLUME) iti.volenv.flags |= 0x01; - if (pIns->dwFlags & ENV_VOLLOOP) iti.volenv.flags |= 0x02; - if (pIns->dwFlags & ENV_VOLSUSTAIN) iti.volenv.flags |= 0x04; - if (pIns->dwFlags & ENV_VOLCARRY) iti.volenv.flags |= 0x08; - iti.volenv.num = (BYTE)pIns->VolEnv.nNodes; - iti.volenv.lpb = (BYTE)pIns->VolEnv.nLoopStart; - iti.volenv.lpe = (BYTE)pIns->VolEnv.nLoopEnd; - iti.volenv.slb = pIns->VolEnv.nSustainStart; - iti.volenv.sle = pIns->VolEnv.nSustainEnd; + MPTEnvToIT(&pIns->VolEnv, &iti.volenv, 0); // Writing Panning envelope - if (pIns->dwFlags & ENV_PANNING) iti.panenv.flags |= 0x01; - if (pIns->dwFlags & ENV_PANLOOP) iti.panenv.flags |= 0x02; - if (pIns->dwFlags & ENV_PANSUSTAIN) iti.panenv.flags |= 0x04; - if (pIns->dwFlags & ENV_PANCARRY) iti.panenv.flags |= 0x08; - iti.panenv.num = (BYTE)pIns->PanEnv.nNodes; - iti.panenv.lpb = (BYTE)pIns->PanEnv.nLoopStart; - iti.panenv.lpe = (BYTE)pIns->PanEnv.nLoopEnd; - iti.panenv.slb = pIns->PanEnv.nSustainStart; - iti.panenv.sle = pIns->PanEnv.nSustainEnd; + MPTEnvToIT(&pIns->PanEnv, &iti.panenv, 32); // Writing Pitch Envelope - if (pIns->dwFlags & ENV_PITCH) iti.pitchenv.flags |= 0x01; - if (pIns->dwFlags & ENV_PITCHLOOP) iti.pitchenv.flags |= 0x02; - if (pIns->dwFlags & ENV_PITCHSUSTAIN) iti.pitchenv.flags |= 0x04; - if (pIns->dwFlags & ENV_PITCHCARRY) iti.pitchenv.flags |= 0x08; - if (pIns->dwFlags & ENV_FILTER) iti.pitchenv.flags |= 0x80; - iti.pitchenv.num = (BYTE)pIns->PitchEnv.nNodes; - iti.pitchenv.lpb = (BYTE)pIns->PitchEnv.nLoopStart; - iti.pitchenv.lpe = (BYTE)pIns->PitchEnv.nLoopEnd; - iti.pitchenv.slb = (BYTE)pIns->PitchEnv.nSustainStart; - iti.pitchenv.sle = (BYTE)pIns->PitchEnv.nSustainEnd; - // Writing Envelopes data - for (UINT ev=0; ev<25; ev++) - { - iti.volenv.data[ev*3] = pIns->VolEnv.Values[ev]; - iti.volenv.data[ev*3+1] = pIns->VolEnv.Ticks[ev] & 0xFF; - iti.volenv.data[ev*3+2] = pIns->VolEnv.Ticks[ev] >> 8; - iti.panenv.data[ev*3] = pIns->PanEnv.Values[ev] - 32; - iti.panenv.data[ev*3+1] = pIns->PanEnv.Ticks[ev] & 0xFF; - iti.panenv.data[ev*3+2] = pIns->PanEnv.Ticks[ev] >> 8; - iti.pitchenv.data[ev*3] = pIns->PitchEnv.Values[ev] - 32; - iti.pitchenv.data[ev*3+1] = pIns->PitchEnv.Ticks[ev] & 0xFF; - iti.pitchenv.data[ev*3+2] = pIns->PitchEnv.Ticks[ev] >> 8; - } + MPTEnvToIT(&pIns->PitchEnv, &iti.pitchenv, 32); + if (pIns->PitchEnv.dwFlags & ENV_FILTER) iti.pitchenv.flags |= 0x80; } else // Save Empty Instrument { @@ -2636,7 +2614,7 @@ iti.ppc = pIns->nPPC; iti.gbv = (BYTE)(pIns->nGlobalVol << 1); iti.dfp = (BYTE)pIns->nPan >> 2; - if (!(pIns->dwFlags & ENV_SETPANNING)) iti.dfp |= 0x80; + if (!(pIns->dwFlags & INS_SETPANNING)) iti.dfp |= 0x80; iti.rv = pIns->nVolSwing; iti.rp = pIns->nPanSwing; iti.ifc = pIns->nIFC; @@ -2656,49 +2634,12 @@ keyboardex[i] = (smp>>8); } else keyboardex[i] = 0; // Writing Volume envelope - if (pIns->dwFlags & ENV_VOLUME) iti.volenv.flags |= 0x01; - if (pIns->dwFlags & ENV_VOLLOOP) iti.volenv.flags |= 0x02; - if (pIns->dwFlags & ENV_VOLSUSTAIN) iti.volenv.flags |= 0x04; - if (pIns->dwFlags & ENV_VOLCARRY) iti.volenv.flags |= 0x08; - iti.volenv.num = (BYTE)pIns->VolEnv.nNodes; - iti.volenv.lpb = (BYTE)pIns->VolEnv.nLoopStart; - iti.volenv.lpe = (BYTE)pIns->VolEnv.nLoopEnd; - iti.volenv.slb = pIns->VolEnv.nSustainStart; - iti.volenv.sle = pIns->VolEnv.nSustainEnd; + MPTEnvToIT(&pIns->VolEnv, &iti.volenv, 0); // Writing Panning envelope - if (pIns->dwFlags & ENV_PANNING) iti.panenv.flags |= 0x01; - if (pIns->dwFlags & ENV_PANLOOP) iti.panenv.flags |= 0x02; - if (pIns->dwFlags & ENV_PANSUSTAIN) iti.panenv.flags |= 0x04; - if (pIns->dwFlags & ENV_PANCARRY) iti.panenv.flags |= 0x08; - iti.panenv.num = (BYTE)pIns->PanEnv.nNodes; - iti.panenv.lpb = (BYTE)pIns->PanEnv.nLoopStart; - iti.panenv.lpe = (BYTE)pIns->PanEnv.nLoopEnd; - iti.panenv.slb = pIns->PanEnv.nSustainStart; - iti.panenv.sle = pIns->PanEnv.nSustainEnd; + MPTEnvToIT(&pIns->PanEnv, &iti.panenv, 32); // Writing Pitch Envelope - if (pIns->dwFlags & ENV_PITCH) iti.pitchenv.flags |= 0x01; - if (pIns->dwFlags & ENV_PITCHLOOP) iti.pitchenv.flags |= 0x02; - if (pIns->dwFlags & ENV_PITCHSUSTAIN) iti.pitchenv.flags |= 0x04; - if (pIns->dwFlags & ENV_PITCHCARRY) iti.pitchenv.flags |= 0x08; - if (pIns->dwFlags & ENV_FILTER) iti.pitchenv.flags |= 0x80; - iti.pitchenv.num = (BYTE)pIns->PitchEnv.nNodes; - iti.pitchenv.lpb = (BYTE)pIns->PitchEnv.nLoopStart; - iti.pitchenv.lpe = (BYTE)pIns->PitchEnv.nLoopEnd; - iti.pitchenv.slb = (BYTE)pIns->PitchEnv.nSustainStart; - iti.pitchenv.sle = (BYTE)pIns->PitchEnv.nSustainEnd; - // Writing Envelopes data - for (UINT ev=0; ev<25; ev++) - { - iti.volenv.data[ev*3] = pIns->VolEnv.Values[ev]; - iti.volenv.data[ev*3+1] = pIns->VolEnv.Ticks[ev] & 0xFF; - iti.volenv.data[ev*3+2] = pIns->VolEnv.Ticks[ev] >> 8; - iti.panenv.data[ev*3] = pIns->PanEnv.Values[ev] - 32; - iti.panenv.data[ev*3+1] = pIns->PanEnv.Ticks[ev] & 0xFF; - iti.panenv.data[ev*3+2] = pIns->PanEnv.Ticks[ev] >> 8; - iti.pitchenv.data[ev*3] = pIns->PitchEnv.Values[ev] - 32; - iti.pitchenv.data[ev*3+1] = pIns->PitchEnv.Ticks[ev] & 0xFF; - iti.pitchenv.data[ev*3+2] = pIns->PitchEnv.Ticks[ev] >> 8; - } + MPTEnvToIT(&pIns->PitchEnv, &iti.pitchenv, 32); + if (pIns->PitchEnv.dwFlags & ENV_FILTER) iti.pitchenv.flags |= 0x80; } else // Save Empty Instrument { Modified: trunk/OpenMPT/soundlib/Load_mdl.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-11-07 21:40:01 UTC (rev 415) @@ -95,6 +95,30 @@ } +// Convert MDL envelope data (env points and flags) +void ConvertMDLEnvelope(const unsigned char *pMDLEnv, INSTRUMENTENVELOPE *pMPTEnv) +//-------------------------------------------------------------------------------- +{ + WORD nCurTick = 1; + pMPTEnv->nNodes = 15; + for (UINT nTick = 0; nTick < 15; nTick++) + { + if (nTick) nCurTick += pMDLEnv[nTick * 2 + 1]; + pMPTEnv->Ticks[nTick] = nCurTick; + pMPTEnv->Values[nTick] = pMDLEnv[nTick * 2 + 2]; + if (!pMDLEnv[nTick * 2 + 1]) // last point reached + { + pMPTEnv->nNodes = nTick + 1; + break; + } + } + pMPTEnv->nSustainStart = pMPTEnv->nSustainEnd = pMDLEnv[31] & 0x0F; + pMPTEnv->dwFlags |= ((pMDLEnv[31] & 0x10) ? ENV_SUSTAIN : 0) | ((pMDLEnv[31] & 0x20) ? ENV_LOOP : 0); + pMPTEnv->nLoopStart = pMDLEnv[32] & 0x0F; + pMPTEnv->nLoopEnd = pMDLEnv[32] >> 4; +} + + void UnpackMDLTrack(MODCOMMAND *pat, UINT nChannels, UINT nRows, UINT nTrack, const BYTE *lpTracks) //------------------------------------------------------------------------------------------------- { @@ -359,13 +383,13 @@ // Use volume envelope ? if (ps[3] & 0x80) { - pIns->dwFlags |= ENV_VOLUME; + pIns->VolEnv.dwFlags |= ENV_ENABLED; insvolenv[nins] = (ps[3] & 0x3F) + 1; } // Use panning envelope ? if (ps[5] & 0x80) { - pIns->dwFlags |= ENV_PANNING; + pIns->PanEnv.dwFlags |= ENV_ENABLED; inspanenv[nins] = (ps[5] & 0x3F) + 1; } } @@ -495,56 +519,24 @@ // Set up envelopes for (UINT iIns=1; iIns<=m_nInstruments; iIns++) if (Instruments[iIns]) { - MODINSTRUMENT *pIns = Instruments[iIns]; // Setup volume envelope if ((nvolenv) && (pvolenv) && (insvolenv[iIns])) { LPCBYTE pve = pvolenv; - for (UINT nve=0; nve<nvolenv; nve++, pve+=33) if (pve[0]+1 == insvolenv[iIns]) + for (UINT nve = 0; nve < nvolenv; nve++, pve += 33) { - WORD vtick = 1; - pIns->VolEnv.nNodes = 15; - for (UINT iv=0; iv<15; iv++) - { - if (iv) vtick += pve[iv*2+1]; - pIns->VolEnv.Ticks[iv] = vtick; - pIns->VolEnv.Values[iv] = pve[iv*2+2]; - if (!pve[iv*2+1]) - { - pIns->VolEnv.nNodes = iv+1; - break; - } - } - pIns->VolEnv.nSustainStart = pIns->VolEnv.nSustainEnd = pve[31] & 0x0F; - if (pve[31] & 0x10) pIns->dwFlags |= ENV_VOLSUSTAIN; - if (pve[31] & 0x20) pIns->dwFlags |= ENV_VOLLOOP; - pIns->VolEnv.nLoopStart = pve[32] & 0x0F; - pIns->VolEnv.nLoopEnd = pve[32] >> 4; + if (pve[0] + 1 == insvolenv[iIns]) + ConvertMDLEnvelope(pve, &Instruments[iIns]->VolEnv); } } // Setup panning envelope if ((npanenv) && (ppanenv) && (inspanenv[iIns])) { LPCBYTE ppe = ppanenv; - for (UINT npe=0; npe<npanenv; npe++, ppe+=33) if (ppe[0]+1 == inspanenv[iIns]) + for (UINT npe = 0; npe < npanenv; npe++, ppe += 33) { - WORD vtick = 1; - pIns->PanEnv.nNodes = 15; - for (UINT iv=0; iv<15; iv++) - { - if (iv) vtick += ppe[iv*2+1]; - pIns->PanEnv.Ticks[iv] = vtick; - pIns->PanEnv.Values[iv] = ppe[iv*2+2]; - if (!ppe[iv*2+1]) - { - pIns->PanEnv.nNodes = iv+1; - break; - } - } - if (ppe[31] & 0x10) pIns->dwFlags |= ENV_PANSUSTAIN; - if (ppe[31] & 0x20) pIns->dwFlags |= ENV_PANLOOP; - pIns->PanEnv.nLoopStart = ppe[32] & 0x0F; - pIns->PanEnv.nLoopEnd = ppe[32] >> 4; + if (ppe[0] + 1 == inspanenv[iIns]) + ConvertMDLEnvelope(ppe, &Instruments[iIns]->PanEnv); } } } Modified: trunk/OpenMPT/soundlib/Load_mid.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mid.cpp 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/soundlib/Load_mid.cpp 2009-11-07 21:40:01 UTC (rev 415) @@ -439,8 +439,8 @@ pIns->Keyboard[j] = m_nSamples; pIns->NoteMap[j] = (BYTE)mapnote; } - pIns->dwFlags |= ENV_VOLUME; - if (nChannel != MIDI_DRUMCHANNEL) pIns->dwFlags |= ENV_VOLSUSTAIN; + pIns->VolEnv.dwFlags |= ENV_ENABLED; + if (nChannel != MIDI_DRUMCHANNEL) pIns->VolEnv.dwFlags |= ENV_SUSTAIN; pIns->VolEnv.nNodes = 4; pIns->VolEnv.Ticks[0] = 0; pIns->VolEnv.Values[0] = 64; Modified: trunk/OpenMPT/soundlib/Load_mt2.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-11-07 21:40:01 UTC (rev 415) @@ -270,7 +270,7 @@ } // Load Patterns dwMemPos = dwExtraDataPos + nExtraDataLen; - for (UINT iPat=0; iPat<pfh->wPatterns; iPat++) if (dwMemPos < dwMemLength-6) + for (PATTERNINDEX iPat=0; iPat < pfh->wPatterns; iPat++) if (dwMemPos < dwMemLength - 6) { MT2PATTERN *pmp = (MT2PATTERN *)(lpStream+dwMemPos); UINT wDataLen = (pmp->wDataLen + 1) & ~1; @@ -411,7 +411,7 @@ SpaceToNullStringFixed(pIns->name, 32); pIns->nGlobalVol = 64; pIns->nPan = 128; - for (UINT i=0; i<NOTE_MAX; i++) + for (BYTE i = 0; i < NOTE_MAX; i++) { pIns->NoteMap[i] = i+1; } @@ -461,59 +461,40 @@ for (UINT iEnv=0; iEnv<4; iEnv++) if (pehdr[iEnv]) { MT2ENVELOPE *pme = pehdr[iEnv]; - WORD *pEnvPoints = NULL; - BYTE *pEnvData = NULL; + INSTRUMENTENVELOPE *pEnv; #ifdef MT2DEBUG Log(" Env %d.%d @%04X: %d points\n", iIns, iEnv, (UINT)(((BYTE *)pme)-lpStream), pme->nPoints); #endif + switch(iEnv) - { - // Volume Envelope - case 0: - if (pme->nFlags & 1) pIns->dwFlags |= ENV_VOLUME; - if (pme->nFlags & 2) pIns->dwFlags |= ENV_VOLSUSTAIN; - if (pme->nFlags & 4) pIns->dwFlags |= ENV_VOLLOOP; - pIns->VolEnv.nNodes = (pme->nPoints > 16) ? 16 : pme->nPoints; - pIns->VolEnv.nSustainStart = pIns->VolEnv.nSustainEnd = pme->nSustainPos; - pIns->VolEnv.nLoopStart = pme->nLoopStart; - pIns->VolEnv.nLoopEnd = pme->nLoopEnd; - pEnvPoints = pIns->VolEnv.Ticks; - pEnvData = pIns->VolEnv.Values; + { + case 0: // Volume Envelope + pEnv = &pIns->VolEnv; break; - - // Panning Envelope - case 1: - if (pme->nFlags & 1) pIns->dwFlags |= ENV_PANNING; - if (pme->nFlags & 2) pIns->dwFlags |= ENV_PANSUSTAIN; - if (pme->nFlags & 4) pIns->dwFlags |= ENV_PANLOOP; - pIns->PanEnv.nNodes = (pme->nPoints > 16) ? 16 : pme->nPoints; - pIns->PanEnv.nSustainStart = pIns->PanEnv.nSustainEnd = pme->nSustainPos; - pIns->PanEnv.nLoopStart = pme->nLoopStart; - pIns->PanEnv.nLoopEnd = pme->nLoopEnd; - pEnvPoints = pIns->PanEnv.Ticks; - pEnvData = pIns->PanEnv.Values; + case 1: // Panning Envelope + pEnv = &pIns->PanEnv; break; - - // Pitch/Filter envelope - default: - if (pme->nFlags & 1) pIns->dwFlags |= (iEnv==3) ? (ENV_PITCH|ENV_FILTER) : ENV_PITCH; - if (pme->nFlags & 2) pIns->dwFlags |= ENV_PITCHSUSTAIN; - if (pme->nFlags & 4) pIns->dwFlags |= ENV_PITCHLOOP; - pIns->PitchEnv.nNodes = (pme->nPoints > 16) ? 16 : pme->nPoints; - pIns->PitchEnv.nSustainStart = pIns->PitchEnv.nSustainEnd = pme->nSustainPos; - pIns->PitchEnv.nLoopStart = pme->nLoopStart; - pIns->PitchEnv.nLoopEnd = pme->nLoopEnd; - pEnvPoints = pIns->PitchEnv.Ticks; - pEnvData = pIns->PitchEnv.Values; + default: // Pitch/Filter envelope + pEnv = &pIns->PitchEnv; + if ((pme->nFlags & 1) && (iEnv == 3)) pIns->PitchEnv.dwFlags |= ENV_FILTER; } + + if (pme->nFlags & 1) pEnv->dwFlags |= ENV_ENABLED; + if (pme->nFlags & 2) pEnv->dwFlags |= ENV_SUSTAIN; + if (pme->nFlags & 4) pEnv->dwFlags |= ENV_LOOP; + pEnv->nNodes = (pme->nPoints > 16) ? 16 : pme->nPoints; + pEnv->nSustainStart = pEnv->nSustainEnd = pme->nSustainPos; + pEnv->nLoopStart = pme->nLoopStart; + pEnv->nLoopEnd = pme->nLoopEnd; + // Envelope data - if ((pEnvPoints) && (pEnvData) && (pedata[iEnv])) + if (pedata[iEnv]) { WORD *psrc = pedata[iEnv]; for (UINT i=0; i<16; i++) { - pEnvPoints[i] = psrc[i*2]; - pEnvData[i] = (BYTE)psrc[i*2+1]; + pEnv->Ticks[i] = psrc[i*2]; + pEnv->Values[i] = (BYTE)psrc[i*2+1]; } } } Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-11-07 21:40:01 UTC (rev 415) @@ -440,30 +440,30 @@ SetDefaultInstrumentValues(pIns); pIns->nPluginVelocityHandling = PLUGIN_VELOCITYHANDLING_CHANNEL; pIns->nPluginVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE; - if (xmsh.vtype & 1) pIns->dwFlags |= ENV_VOLUME; - if (xmsh.vtype & 2) pIns->dwFlags |= ENV_VOLSUSTAIN; - if (xmsh.vtype & 4) pIns->dwFlags |= ENV_VOLLOOP; - if (xmsh.ptype & 1) pIns->dwFlags |= ENV_PANNING; - if (xmsh.ptype & 2) pIns->dwFlags |= ENV_PANSUSTAIN; - if (xmsh.ptype & 4) pIns->dwFlags |= ENV_PANLOOP; + if (xmsh.vtype & 1) pIns->VolEnv.dwFlags |= ENV_ENABLED; + if (xmsh.vtype & 2) pIns->VolEnv.dwFlags |= ENV_SUSTAIN; + if (xmsh.vtype & 4) pIns->VolEnv.dwFlags |= ENV_LOOP; + if (xmsh.ptype & 1) pIns->PanEnv.dwFlags |= ENV_ENABLED; + if (xmsh.ptype & 2) pIns->PanEnv.dwFlags |= ENV_SUSTAIN; + if (xmsh.ptype & 4) pIns->PanEnv.dwFlags |= ENV_LOOP; if (xmsh.vnum > 12) xmsh.vnum = 12; if (xmsh.pnum > 12) xmsh.pnum = 12; pIns->VolEnv.nNodes = xmsh.vnum; - if (!xmsh.vnum) pIns->dwFlags &= ~ENV_VOLUME; - if (!xmsh.pnum) pIns->dwFlags &= ~ENV_PANNING; + if (!xmsh.vnum) pIns->VolEnv.dwFlags &= ~ENV_ENABLED; + if (!xmsh.pnum) pIns->PanEnv.dwFlags &= ~ENV_ENABLED; pIns->PanEnv.nNodes = xmsh.pnum; pIns->VolEnv.nSustainStart = pIns->VolEnv.nSustainEnd = xmsh.vsustain; - if (xmsh.vsustain >= 12) pIns->dwFlags &= ~ENV_VOLSUSTAIN; + if (xmsh.vsustain >= 12) pIns->VolEnv.dwFlags &= ~ENV_SUSTAIN; pIns->VolEnv.nLoopStart = xmsh.vloops; pIns->VolEnv.nLoopEnd = xmsh.vloope; if (pIns->VolEnv.nLoopEnd >= 12) pIns->VolEnv.nLoopEnd = 0; - if (pIns->VolEnv.nLoopStart >= pIns->VolEnv.nLoopEnd) pIns->dwFlags &= ~ENV_VOLLOOP; + if (pIns->VolEnv.nLoopStart >= pIns->VolEnv.nLoopEnd) pIns->VolEnv.dwFlags &= ~ENV_LOOP; pIns->PanEnv.nSustainStart = pIns->PanEnv.nSustainEnd = xmsh.psustain; - if (xmsh.psustain >= 12) pIns->dwFlags &= ~ENV_PANSUSTAIN; + if (xmsh.psustain >= 12) pIns->PanEnv.dwFlags &= ~ENV_SUSTAIN; pIns->PanEnv.nLoopStart = xmsh.ploops; pIns->PanEnv.nLoopEnd = xmsh.ploope; if (pIns->PanEnv.nLoopEnd >= 12) pIns->PanEnv.nLoopEnd = 0; - if (pIns->PanEnv.nLoopStart >= pIns->PanEnv.nLoopEnd) pIns->dwFlags &= ~ENV_PANLOOP; + if (pIns->PanEnv.nLoopStart >= pIns->PanEnv.nLoopEnd) pIns->PanEnv.dwFlags &= ~ENV_LOOP; pIns->nGlobalVol = 64; for (UINT ienv=0; ienv<12; ienv++) { @@ -918,12 +918,12 @@ xmsh.penv[ienv*2] = LittleEndianW(pIns->PanEnv.Ticks[ienv]); xmsh.penv[ienv*2+1] = LittleEndianW(pIns->PanEnv.Values[ienv]); } - if (pIns->dwFlags & ENV_VOLUME) xmsh.vtype |= 1; - if (pIns->dwFlags & ENV_VOLSUSTAIN) xmsh.vtype |= 2; - if (pIns->dwFlags & ENV_VOLLOOP) xmsh.vtype |= 4; - if (pIns->dwFlags & ENV_PANNING) xmsh.ptype |= 1; - if (pIns->dwFlags & ENV_PANSUSTAIN) xmsh.ptype |= 2; - if (pIns->dwFlags & ENV_PANLOOP) xmsh.ptype |= 4; + if (pIns->VolEnv.dwFlags & ENV_ENABLED) xmsh.vtype |= 1; + if (pIns->VolEnv.dwFlags & ENV_SUSTAIN) xmsh.vtype |= 2; + if (pIns->VolEnv.dwFlags & ENV_LOOP) xmsh.vtype |= 4; + if (pIns->PanEnv.dwFlags & ENV_ENABLED) xmsh.ptype |= 1; + if (pIns->PanEnv.dwFlags & ENV_SUSTAIN) xmsh.ptype |= 2; + if (pIns->PanEnv.dwFlags & ENV_LOOP) xmsh.ptype |= 4; xmsh.vsustain = (BYTE)pIns->VolEnv.nSustainStart; xmsh.vloops = (BYTE)pIns->VolEnv.nLoopStart; xmsh.vloope = (BYTE)pIns->VolEnv.nLoopEnd; Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2009-11-07 15:47:35 UTC (rev 414) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2009-11-07 21:40:01 UTC (rev 415) @@ -1165,32 +1165,32 @@ if (n < nsamples) pIns->Keyboard[k+12] = samplemap[n]; } pIns->nFadeOut = pih->volfade; - if (pih->vtype & 1) pIns->dwFlags |= ENV_VOLUME; - if (pih->vtype & 2) pIns->dwFlags |= ENV_VOLSUSTAIN; - if (pih->vtype & 4) pIns->dwFlags |= ENV_VOLLOOP; - if (pih->ptype & 1) pIns->dwFlags |= ENV_PANNING; - if (pih->ptype & 2) pIns->dwFlags |= ENV_PANSUSTAIN; - if (pih->ptype & 4) pIns->dwFlags |= ENV_PANLOOP; + if (pih->vtype & 1) pIns->VolEnv.dwFlags |= ENV_ENABLED; + if (pih->vtype & 2) pIns->VolEnv.dwFlags |= ENV_SUSTAIN; + if (pih->vtype & 4) pIns->VolEnv.dwFlags |= ENV_LOOP; + if (pih->ptype & 1) pIns->PanEnv.dwFlags |= ENV_ENABLED; + if (pih->ptype & 2) pIns->PanEnv.dwFlags |= ENV_SUSTAIN; + if (pih->ptype & 4) pIns->PanEnv.dwFlags |= ENV_LOOP; pIns->VolEnv.nNodes = pih->vnum; pIns->PanEnv.nNodes = pih->pnum; if (pIns->VolEnv.nNodes > 12) pIns->VolEnv.nNodes = 12; if (pIns->PanEnv.nNodes > 12) pIns->PanEnv.nNodes = 12; - if (!pIns->VolEnv.nNodes) pIns->dwFlags &= ~ENV_VOLUME; - if (!pIns->PanEnv.nNodes) pIns->dwFlags &= ~ENV_PANNING; + if (!pIns->VolEnv.nNodes) pIns->VolEnv.dwFlags &= ~ENV_ENABLED; + if (!pIns->PanEnv.nNodes) pIns->PanEnv.dwFlags &= ~ENV_ENABLED; pIns->VolEnv.nSustainStart = pih->vsustain; pIns->VolEnv.nSustainEnd = pih->vsustain; - if (pih->vsustain ... [truncated message content] |
From: <sag...@us...> - 2009-11-12 22:29:04
|
Revision: 417 http://modplug.svn.sourceforge.net/modplug/?rev=417&view=rev Author: saga-games Date: 2009-11-12 21:32:08 +0000 (Thu, 12 Nov 2009) Log Message: ----------- [New] Pattern Editor: The "paste flood" command pastes the clipboard content again and again until it hits the bottom of the pattern (overflow paste will be disabled autmatically if paste flood is used, for obvious reasons) [Fix] Instrument Editor: Last patch changed semantic of CViewInstrument::EnvGetValue a bit. [Fix] Further fixes to Invert Loop. Still not perfect. [Ref] Updated modular code dictionary description. Modified Paths: -------------- trunk/OpenMPT/mptrack/CommandSet.cpp trunk/OpenMPT/mptrack/CommandSet.h trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Undo.cpp trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/View_pat.h trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/CommandSet.cpp =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.cpp 2009-11-07 23:38:07 UTC (rev 416) +++ trunk/OpenMPT/mptrack/CommandSet.cpp 2009-11-12 21:32:08 UTC (rev 417) @@ -2345,6 +2345,11 @@ commands[kcNoteFadeOld].isHidden = false; commands[kcNoteFadeOld].isDummy = false; + commands[kcEditPasteFlood].UID = 1793; + commands[kcEditPasteFlood].Message = "Paste Flood"; + commands[kcEditPasteFlood].isHidden = false; + commands[kcEditPasteFlood].isDummy = false; + #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 2009-11-07 23:38:07 UTC (rev 416) +++ trunk/OpenMPT/mptrack/CommandSet.h 2009-11-12 21:32:08 UTC (rev 417) @@ -84,6 +84,7 @@ kcEditPaste, kcEditMixPaste, kcEditMixPasteITStyle, + kcEditPasteFlood, kcSwitchOverflowPaste, kcEditSelectAll, kcEditFind, Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-11-07 23:38:07 UTC (rev 416) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-11-12 21:32:08 UTC (rev 417) @@ -240,8 +240,8 @@ BOOL ShrinkPattern(PATTERNINDEX nPattern); // Copy&Paste - BOOL CopyPattern(PATTERNINDEX nPattern, DWORD dwBeginSel, DWORD dwEndSel); - BOOL PastePattern(PATTERNINDEX nPattern, DWORD dwBeginSel, BOOL mix, BOOL ITStyleMix=FALSE); //rewbs.mixpaste + bool CopyPattern(PATTERNINDEX nPattern, DWORD dwBeginSel, DWORD dwEndSel); + bool PastePattern(PATTERNINDEX nPattern, DWORD dwBeginSel, bool mix, bool ITStyleMix = false, bool PasteFlood = false); BOOL CopyEnvelope(UINT nIns, UINT nEnv); BOOL PasteEnvelope(UINT nIns, UINT nEnv); Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-11-07 23:38:07 UTC (rev 416) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-11-12 21:32:08 UTC (rev 417) @@ -995,8 +995,8 @@ static LPCSTR lpszClipboardPatternHdr = "ModPlug Tracker %3s\x0D\x0A"; -BOOL CModDoc::CopyPattern(PATTERNINDEX nPattern, DWORD dwBeginSel, DWORD dwEndSel) -//------------------------------------------------------------------------ +bool CModDoc::CopyPattern(PATTERNINDEX nPattern, DWORD dwBeginSel, DWORD dwEndSel) +//-------------------------------------------------------------------------------- { CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); DWORD dwMemSize; @@ -1004,7 +1004,7 @@ UINT nrows = (dwEndSel >> 16) - (dwBeginSel >> 16) + 1; UINT ncols = ((dwEndSel & 0xFFFF) >> 3) - ((dwBeginSel & 0xFFFF) >> 3) + 1; - if ((!pMainFrm) || (nPattern >= m_SndFile.Patterns.Size()) || (!m_SndFile.Patterns[nPattern])) return FALSE; + if ((!pMainFrm) || (nPattern >= m_SndFile.Patterns.Size()) || (!m_SndFile.Patterns[nPattern])) return false; BeginWaitCursor(); dwMemSize = strlen(lpszClipboardPatternHdr) + 1; dwMemSize += nrows * (ncols * 12 + 2); @@ -1138,20 +1138,16 @@ CloseClipboard(); } EndWaitCursor(); - return TRUE; + return true; } -//rewbs.mixpaste: using eric's method, as it is fat more elegant. -// -> CODE#0014 -// -> DESC="vst wet/dry slider" //BOOL CModDoc::PastePattern(UINT nPattern, DWORD dwBeginSel) -BOOL CModDoc::PastePattern(PATTERNINDEX nPattern, DWORD dwBeginSel, BOOL mix, BOOL ITStyleMix) -// -! NEW_FEATURE#0014 -//--------------------------------------------------------- +bool CModDoc::PastePattern(PATTERNINDEX nPattern, DWORD dwBeginSel, bool mix, bool ITStyleMix, bool PasteFlood) +//------------------------------------------------------------------------------------------------------------- { CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); - if ((!pMainFrm) || (nPattern >= m_SndFile.Patterns.Size()) || (!m_SndFile.Patterns[nPattern])) return FALSE; + if ((!pMainFrm) || (nPattern >= m_SndFile.Patterns.Size()) || (!m_SndFile.Patterns[nPattern])) return false; BeginWaitCursor(); if (pMainFrm->OpenClipboard()) { @@ -1168,11 +1164,11 @@ UINT col; bool bS3MCommands = false, bOk = false; MODTYPE origFormat = MOD_TYPE_IT; - UINT len = 0; + UINT len = 0, startLen; MODCOMMAND origModCmd; ORDERINDEX oCurrentOrder; //jojo.echopaste - ROWINDEX rTemp; + ROWINDEX rTemp, startRow; PATTERNINDEX pTemp; GetEditPosition(rTemp, pTemp, oCurrentOrder); @@ -1199,15 +1195,24 @@ bOk = true; GetPatternUndo()->PrepareUndo(nPattern, 0, 0, m_SndFile.m_nChannels, m_SndFile.PatternSize[nPattern]); + startLen = len; + startRow = nrow; - while ((nrow < m_SndFile.PatternSize[nPattern]) && (len + 11 < dwMemSize)) + while ((nrow < m_SndFile.PatternSize[nPattern])) { - // Search for column separator - while (p[len] != '|') + // Search for column separator or end of paste data + while ((len + 11 >= dwMemSize) || p[len] != '|') { - if (len + 11 >= dwMemSize) goto PasteDone; - if (!p[len]) goto PasteDone; - len++; + if (len + 11 >= dwMemSize || !p[len]) + { + if((PasteFlood == true) && (nrow != startRow)) // prevent infinite loop with malformed clipboard data + len = startLen; // paste from beginning + else + goto PasteDone; + } else + { + len++; + } } col = ncol; // Paste columns @@ -1359,8 +1364,9 @@ m += m_SndFile.m_nChannels; nrow++; - //jojo.echopaste - if(CMainFrame::m_dwPatternSetup & PATTERN_OVERFLOWPASTE) + // Overflow paste. Continue pasting in next pattern if enabled. + // If Paste Flood is enabled, this won't be called due to obvious reasons. + if((CMainFrame::m_dwPatternSetup & PATTERN_OVERFLOWPASTE) && !PasteFlood) { while(nrow >= m_SndFile.PatternSize[nPattern]) { @@ -1387,7 +1393,7 @@ CloseClipboard(); } EndWaitCursor(); - return TRUE; + return true; } Modified: trunk/OpenMPT/mptrack/Undo.cpp =================================================================== --- trunk/OpenMPT/mptrack/Undo.cpp 2009-11-07 23:38:07 UTC (rev 416) +++ trunk/OpenMPT/mptrack/Undo.cpp 2009-11-12 21:32:08 UTC (rev 417) @@ -31,6 +31,12 @@ // Create undo point. +// Parameter list: +// - pattern: Pattern of which an undo step should be created from. +// - x: first channel +// - y: first row +// - cx: last channel +// - cy: last row bool CPatternUndo::PrepareUndo(PATTERNINDEX pattern, UINT x, UINT y, UINT cx, UINT cy) //------------------------------------------------------------------------------------ { Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2009-11-07 23:38:07 UTC (rev 416) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-11-12 21:32:08 UTC (rev 417) @@ -246,7 +246,7 @@ { INSTRUMENTENVELOPE *envelope = GetEnvelopePtr(); if(envelope == nullptr) return 0; - if(nPoint < (int)envelope->nNodes) return envelope->Values[nPoint]; + if(nPoint >= 0 && nPoint < (int)envelope->nNodes) return envelope->Values[nPoint]; return 0; } Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-11-07 23:38:07 UTC (rev 416) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-11-12 21:32:08 UTC (rev 417) @@ -53,7 +53,8 @@ ON_COMMAND(ID_EDIT_CUT, OnEditCut) ON_COMMAND(ID_EDIT_COPY, OnEditCopy) ON_COMMAND(ID_EDIT_PASTE, OnEditPaste) - ON_COMMAND(ID_EDIT_MIXPASTE, OnEditMixPaste) //rewbs.mixPaste + ON_COMMAND(ID_EDIT_MIXPASTE, OnEditMixPaste) + ON_COMMAND(ID_EDIT_PASTEFLOOD, OnEditPasteFlood) ON_COMMAND(ID_EDIT_SELECT_ALL, OnEditSelectAll) ON_COMMAND(ID_EDIT_SELECTCOLUMN,OnEditSelectColumn) ON_COMMAND(ID_EDIT_SELECTCOLUMN2,OnSelectCurrentColumn) @@ -1004,10 +1005,24 @@ } } + //end rewbs.mixPaste +void CViewPattern::OnEditPasteFlood() +//----------------------------------- +{ + CModDoc *pModDoc = GetDocument(); + if (pModDoc && IsEditingEnabled_bmsg()) + { + pModDoc->PastePattern(m_nPattern, m_dwBeginSel, false, false, true); + InvalidatePattern(FALSE); + SetFocus(); + } +} + + void CViewPattern::OnLButtonDown(UINT nFlags, CPoint point) //-------------------------------------------------- { @@ -3613,6 +3628,7 @@ case kcEditPaste: OnEditPaste(); return wParam; case kcEditMixPaste: OnEditMixPaste(); return wParam; case kcEditMixPasteITStyle: OnEditMixPasteITStyle(); return wParam; + case kcEditPasteFlood: OnEditPasteFlood(); return wParam; case kcEditSelectAll: OnEditSelectAll(); return wParam; case kcTogglePluginEditor: TogglePluginEditor((m_dwCursor & 0xFFFF) >> 3); return wParam; case kcToggleFollowSong: SendCtrlMessage(CTRLMSG_PAT_FOLLOWSONG); return wParam; @@ -4824,6 +4840,7 @@ AppendMenu(hMenu, MF_STRING, ID_EDIT_COPY, "Copy\t" + ih->GetKeyTextFromCommand(kcEditCopy)); AppendMenu(hMenu, MF_STRING, ID_EDIT_PASTE, "Paste\t" + ih->GetKeyTextFromCommand(kcEditPaste)); AppendMenu(hMenu, MF_STRING, ID_EDIT_MIXPASTE, "Mix Paste\t" + ih->GetKeyTextFromCommand(kcEditMixPaste)); + AppendMenu(hMenu, MF_STRING, ID_EDIT_PASTEFLOOD, "Paste Flood\t" + ih->GetKeyTextFromCommand(kcEditPasteFlood)); DWORD greyed = pModDoc->GetPatternUndo()->CanUndo()?FALSE:MF_GRAYED; if (!greyed || !(CMainFrame::m_dwPatternSetup&PATTERN_OLDCTXMENUSTYLE)) { Modified: trunk/OpenMPT/mptrack/View_pat.h =================================================================== --- trunk/OpenMPT/mptrack/View_pat.h 2009-11-07 23:38:07 UTC (rev 416) +++ trunk/OpenMPT/mptrack/View_pat.h 2009-11-12 21:32:08 UTC (rev 417) @@ -230,6 +230,7 @@ afx_msg void OnEditPaste(); afx_msg void OnEditMixPaste(); //rewbs.mixPaste afx_msg void OnEditMixPasteITStyle(); //rewbs.mixPaste + afx_msg void OnEditPasteFlood(); afx_msg void OnClearSelection(bool ITStyle=false, RowMask sb = DefaultRowMask); //rewbs.customKeys afx_msg void OnGrowSelection(); //rewbs.customKeys afx_msg void OnShrinkSelection(); //rewbs.customKeys Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2009-11-07 23:38:07 UTC (rev 416) +++ trunk/OpenMPT/mptrack/resource.h 2009-11-12 21:32:08 UTC (rev 417) @@ -1152,6 +1152,7 @@ #define ID_ORDERLIST_EDIT_CUT 59232 #define ID_ORDERLIST_EDIT_PASTE 59233 #define ID_CHANNEL_RENAME 59234 +#define ID_EDIT_PASTEFLOOD 59235 // Next default values for new objects // @@ -1159,7 +1160,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 523 -#define _APS_NEXT_COMMAND_VALUE 59235 +#define _APS_NEXT_COMMAND_VALUE 59236 #define _APS_NEXT_CONTROL_VALUE 2412 #define _APS_NEXT_SYMED_VALUE 901 #endif Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-11-07 23:38:07 UTC (rev 416) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-11-12 21:32:08 UTC (rev 417) @@ -2530,7 +2530,6 @@ 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 @@ -2701,7 +2700,7 @@ if((m_nType & MOD_TYPE_MOD) == 0 || pChn->nEFxSpeed == 0) return; // we obviously also need a sample for this - MODSAMPLE *pModSample = pChn->pEFxSample; + MODSAMPLE *pModSample = pChn->pModSample; if(pModSample == nullptr || pModSample->pSample == nullptr || !(pModSample->uFlags & CHN_LOOP)) return; pChn->nEFxDelay += ModEFxTable[pChn->nEFxSpeed & 0x0F]; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-11-07 23:38:07 UTC (rev 416) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-11-12 21:32:08 UTC (rev 417) @@ -127,8 +127,8 @@ - use 'VE[.' for VolEnv.Values[MAX_ENVPOINTS] -* In use CODE tag dictionnary (alphabetical order): [ see in Sndfile.cpp ] --------------------------------------------------------------------------- +* In use CODE tag dictionary (alphabetical order): [ see in Sndfile.cpp ] +------------------------------------------------------------------------- !!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!! SECTION TO BE UPDATED !!! @@ -209,6 +209,9 @@ PERN PitchEnv.nReleaseNode AERN PanEnv.nReleaseNode VERN VolEnv.nReleaseNode +PFLG PitchEnv.dwFlag +AFLG PanEnv.dwFlags +VFLG VolEnv.dwFlags ----------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------*/ Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-11-07 23:38:07 UTC (rev 416) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-11-12 21:32:08 UTC (rev 417) @@ -205,7 +205,6 @@ 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 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |