Index: build/android_ndk/Android.mk
===================================================================
--- build/android_ndk/Android.mk	(revision 7555)
+++ build/android_ndk/Android.mk	(working copy)
@@ -187,6 +187,7 @@
 	soundlib/Load_s3m.cpp \
 	soundlib/Load_sfx.cpp \
 	soundlib/Load_stm.cpp \
+	soundlib/Load_stp.cpp \
 	soundlib/Load_ult.cpp \
 	soundlib/Load_umx.cpp \
 	soundlib/Load_wav.cpp \
Index: build/autotools/Makefile.am
===================================================================
--- build/autotools/Makefile.am	(revision 7555)
+++ build/autotools/Makefile.am	(working copy)
@@ -205,6 +205,7 @@
 libopenmpt_la_SOURCES += soundlib/Load_s3m.cpp
 libopenmpt_la_SOURCES += soundlib/Load_sfx.cpp
 libopenmpt_la_SOURCES += soundlib/Load_stm.cpp
+libopenmpt_la_SOURCES += soundlib/Load_stp.cpp
 libopenmpt_la_SOURCES += soundlib/Load_ult.cpp
 libopenmpt_la_SOURCES += soundlib/Load_umx.cpp
 libopenmpt_la_SOURCES += soundlib/Load_wav.cpp
@@ -463,6 +464,7 @@
 libopenmpttest_SOURCES += soundlib/Load_s3m.cpp
 libopenmpttest_SOURCES += soundlib/Load_sfx.cpp
 libopenmpttest_SOURCES += soundlib/Load_stm.cpp
+libopenmpttest_SOURCES += soundlib/Load_stp.cpp
 libopenmpttest_SOURCES += soundlib/Load_ult.cpp
 libopenmpttest_SOURCES += soundlib/Load_umx.cpp
 libopenmpttest_SOURCES += soundlib/Load_wav.cpp
Index: build/vs2010/libopenmpt-small.vcxproj
===================================================================
--- build/vs2010/libopenmpt-small.vcxproj	(revision 7555)
+++ build/vs2010/libopenmpt-small.vcxproj	(working copy)
@@ -529,6 +529,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2010/libopenmpt-small.vcxproj.filters
===================================================================
--- build/vs2010/libopenmpt-small.vcxproj.filters	(revision 7555)
+++ build/vs2010/libopenmpt-small.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2010/libopenmpt.vcxproj
===================================================================
--- build/vs2010/libopenmpt.vcxproj	(revision 7555)
+++ build/vs2010/libopenmpt.vcxproj	(working copy)
@@ -529,6 +529,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2010/libopenmpt.vcxproj.filters
===================================================================
--- build/vs2010/libopenmpt.vcxproj.filters	(revision 7555)
+++ build/vs2010/libopenmpt.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2010/libopenmpt_test.vcxproj
===================================================================
--- build/vs2010/libopenmpt_test.vcxproj	(revision 7555)
+++ build/vs2010/libopenmpt_test.vcxproj	(working copy)
@@ -361,6 +361,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2010/libopenmpt_test.vcxproj.filters
===================================================================
--- build/vs2010/libopenmpt_test.vcxproj.filters	(revision 7555)
+++ build/vs2010/libopenmpt_test.vcxproj.filters	(working copy)
@@ -533,6 +533,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2010xp/libopenmpt-small.vcxproj
===================================================================
--- build/vs2010xp/libopenmpt-small.vcxproj	(revision 7555)
+++ build/vs2010xp/libopenmpt-small.vcxproj	(working copy)
@@ -527,6 +527,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2010xp/libopenmpt-small.vcxproj.filters
===================================================================
--- build/vs2010xp/libopenmpt-small.vcxproj.filters	(revision 7555)
+++ build/vs2010xp/libopenmpt-small.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2010xp/libopenmpt.vcxproj
===================================================================
--- build/vs2010xp/libopenmpt.vcxproj	(revision 7555)
+++ build/vs2010xp/libopenmpt.vcxproj	(working copy)
@@ -527,6 +527,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2010xp/libopenmpt.vcxproj.filters
===================================================================
--- build/vs2010xp/libopenmpt.vcxproj.filters	(revision 7555)
+++ build/vs2010xp/libopenmpt.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2010xp/libopenmpt_test.vcxproj
===================================================================
--- build/vs2010xp/libopenmpt_test.vcxproj	(revision 7555)
+++ build/vs2010xp/libopenmpt_test.vcxproj	(working copy)
@@ -360,6 +360,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2010xp/libopenmpt_test.vcxproj.filters
===================================================================
--- build/vs2010xp/libopenmpt_test.vcxproj.filters	(revision 7555)
+++ build/vs2010xp/libopenmpt_test.vcxproj.filters	(working copy)
@@ -533,6 +533,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2012/libopenmpt-small.vcxproj
===================================================================
--- build/vs2012/libopenmpt-small.vcxproj	(revision 7555)
+++ build/vs2012/libopenmpt-small.vcxproj	(working copy)
@@ -537,6 +537,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2012/libopenmpt-small.vcxproj.filters
===================================================================
--- build/vs2012/libopenmpt-small.vcxproj.filters	(revision 7555)
+++ build/vs2012/libopenmpt-small.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2012/libopenmpt.vcxproj
===================================================================
--- build/vs2012/libopenmpt.vcxproj	(revision 7555)
+++ build/vs2012/libopenmpt.vcxproj	(working copy)
@@ -537,6 +537,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2012/libopenmpt.vcxproj.filters
===================================================================
--- build/vs2012/libopenmpt.vcxproj.filters	(revision 7555)
+++ build/vs2012/libopenmpt.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2012/libopenmpt_test.vcxproj
===================================================================
--- build/vs2012/libopenmpt_test.vcxproj	(revision 7555)
+++ build/vs2012/libopenmpt_test.vcxproj	(working copy)
@@ -365,6 +365,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2012/libopenmpt_test.vcxproj.filters
===================================================================
--- build/vs2012/libopenmpt_test.vcxproj.filters	(revision 7555)
+++ build/vs2012/libopenmpt_test.vcxproj.filters	(working copy)
@@ -533,6 +533,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2012xp/libopenmpt-small.vcxproj
===================================================================
--- build/vs2012xp/libopenmpt-small.vcxproj	(revision 7555)
+++ build/vs2012xp/libopenmpt-small.vcxproj	(working copy)
@@ -537,6 +537,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2012xp/libopenmpt-small.vcxproj.filters
===================================================================
--- build/vs2012xp/libopenmpt-small.vcxproj.filters	(revision 7555)
+++ build/vs2012xp/libopenmpt-small.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2012xp/libopenmpt.vcxproj
===================================================================
--- build/vs2012xp/libopenmpt.vcxproj	(revision 7555)
+++ build/vs2012xp/libopenmpt.vcxproj	(working copy)
@@ -537,6 +537,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2012xp/libopenmpt.vcxproj.filters
===================================================================
--- build/vs2012xp/libopenmpt.vcxproj.filters	(revision 7555)
+++ build/vs2012xp/libopenmpt.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2012xp/libopenmpt_test.vcxproj
===================================================================
--- build/vs2012xp/libopenmpt_test.vcxproj	(revision 7555)
+++ build/vs2012xp/libopenmpt_test.vcxproj	(working copy)
@@ -365,6 +365,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2012xp/libopenmpt_test.vcxproj.filters
===================================================================
--- build/vs2012xp/libopenmpt_test.vcxproj.filters	(revision 7555)
+++ build/vs2012xp/libopenmpt_test.vcxproj.filters	(working copy)
@@ -533,6 +533,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2013/libopenmpt-small.vcxproj
===================================================================
--- build/vs2013/libopenmpt-small.vcxproj	(revision 7555)
+++ build/vs2013/libopenmpt-small.vcxproj	(working copy)
@@ -538,6 +538,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2013/libopenmpt-small.vcxproj.filters
===================================================================
--- build/vs2013/libopenmpt-small.vcxproj.filters	(revision 7555)
+++ build/vs2013/libopenmpt-small.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2013/libopenmpt.vcxproj
===================================================================
--- build/vs2013/libopenmpt.vcxproj	(revision 7555)
+++ build/vs2013/libopenmpt.vcxproj	(working copy)
@@ -538,6 +538,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2013/libopenmpt.vcxproj.filters
===================================================================
--- build/vs2013/libopenmpt.vcxproj.filters	(revision 7555)
+++ build/vs2013/libopenmpt.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2013/libopenmpt_test.vcxproj
===================================================================
--- build/vs2013/libopenmpt_test.vcxproj	(revision 7555)
+++ build/vs2013/libopenmpt_test.vcxproj	(working copy)
@@ -366,6 +366,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2013/libopenmpt_test.vcxproj.filters
===================================================================
--- build/vs2013/libopenmpt_test.vcxproj.filters	(revision 7555)
+++ build/vs2013/libopenmpt_test.vcxproj.filters	(working copy)
@@ -533,6 +533,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2013/OpenMPT.vcxproj
===================================================================
--- build/vs2013/OpenMPT.vcxproj	(revision 7555)
+++ build/vs2013/OpenMPT.vcxproj	(working copy)
@@ -1062,6 +1062,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2013/OpenMPT.vcxproj.filters
===================================================================
--- build/vs2013/OpenMPT.vcxproj.filters	(revision 7555)
+++ build/vs2013/OpenMPT.vcxproj.filters	(working copy)
@@ -1169,6 +1169,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2013xp/libopenmpt-small.vcxproj
===================================================================
--- build/vs2013xp/libopenmpt-small.vcxproj	(revision 7555)
+++ build/vs2013xp/libopenmpt-small.vcxproj	(working copy)
@@ -538,6 +538,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2013xp/libopenmpt-small.vcxproj.filters
===================================================================
--- build/vs2013xp/libopenmpt-small.vcxproj.filters	(revision 7555)
+++ build/vs2013xp/libopenmpt-small.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2013xp/libopenmpt.vcxproj
===================================================================
--- build/vs2013xp/libopenmpt.vcxproj	(revision 7555)
+++ build/vs2013xp/libopenmpt.vcxproj	(working copy)
@@ -538,6 +538,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2013xp/libopenmpt.vcxproj.filters
===================================================================
--- build/vs2013xp/libopenmpt.vcxproj.filters	(revision 7555)
+++ build/vs2013xp/libopenmpt.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2013xp/libopenmpt_test.vcxproj
===================================================================
--- build/vs2013xp/libopenmpt_test.vcxproj	(revision 7555)
+++ build/vs2013xp/libopenmpt_test.vcxproj	(working copy)
@@ -366,6 +366,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2013xp/libopenmpt_test.vcxproj.filters
===================================================================
--- build/vs2013xp/libopenmpt_test.vcxproj.filters	(revision 7555)
+++ build/vs2013xp/libopenmpt_test.vcxproj.filters	(working copy)
@@ -533,6 +533,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2013xp/OpenMPT.vcxproj
===================================================================
--- build/vs2013xp/OpenMPT.vcxproj	(revision 7555)
+++ build/vs2013xp/OpenMPT.vcxproj	(working copy)
@@ -1062,6 +1062,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2013xp/OpenMPT.vcxproj.filters
===================================================================
--- build/vs2013xp/OpenMPT.vcxproj.filters	(revision 7555)
+++ build/vs2013xp/OpenMPT.vcxproj.filters	(working copy)
@@ -1169,6 +1169,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2015/libopenmpt-small.vcxproj
===================================================================
--- build/vs2015/libopenmpt-small.vcxproj	(revision 7555)
+++ build/vs2015/libopenmpt-small.vcxproj	(working copy)
@@ -538,6 +538,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2015/libopenmpt-small.vcxproj.filters
===================================================================
--- build/vs2015/libopenmpt-small.vcxproj.filters	(revision 7555)
+++ build/vs2015/libopenmpt-small.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2015/libopenmpt.vcxproj
===================================================================
--- build/vs2015/libopenmpt.vcxproj	(revision 7555)
+++ build/vs2015/libopenmpt.vcxproj	(working copy)
@@ -538,6 +538,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2015/libopenmpt.vcxproj.filters
===================================================================
--- build/vs2015/libopenmpt.vcxproj.filters	(revision 7555)
+++ build/vs2015/libopenmpt.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2015/libopenmpt_test.vcxproj
===================================================================
--- build/vs2015/libopenmpt_test.vcxproj	(revision 7555)
+++ build/vs2015/libopenmpt_test.vcxproj	(working copy)
@@ -366,6 +366,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2015/libopenmpt_test.vcxproj.filters
===================================================================
--- build/vs2015/libopenmpt_test.vcxproj.filters	(revision 7555)
+++ build/vs2015/libopenmpt_test.vcxproj.filters	(working copy)
@@ -533,6 +533,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2015/OpenMPT.vcxproj
===================================================================
--- build/vs2015/OpenMPT.vcxproj	(revision 7555)
+++ build/vs2015/OpenMPT.vcxproj	(working copy)
@@ -1062,6 +1062,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2015/OpenMPT.vcxproj.filters
===================================================================
--- build/vs2015/OpenMPT.vcxproj.filters	(revision 7555)
+++ build/vs2015/OpenMPT.vcxproj.filters	(working copy)
@@ -1178,6 +1178,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2015xp/libopenmpt-small.vcxproj
===================================================================
--- build/vs2015xp/libopenmpt-small.vcxproj	(revision 7555)
+++ build/vs2015xp/libopenmpt-small.vcxproj	(working copy)
@@ -538,6 +538,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2015xp/libopenmpt-small.vcxproj.filters
===================================================================
--- build/vs2015xp/libopenmpt-small.vcxproj.filters	(revision 7555)
+++ build/vs2015xp/libopenmpt-small.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2015xp/libopenmpt.vcxproj
===================================================================
--- build/vs2015xp/libopenmpt.vcxproj	(revision 7555)
+++ build/vs2015xp/libopenmpt.vcxproj	(working copy)
@@ -538,6 +538,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2015xp/libopenmpt.vcxproj.filters
===================================================================
--- build/vs2015xp/libopenmpt.vcxproj.filters	(revision 7555)
+++ build/vs2015xp/libopenmpt.vcxproj.filters	(working copy)
@@ -515,6 +515,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2015xp/libopenmpt_test.vcxproj
===================================================================
--- build/vs2015xp/libopenmpt_test.vcxproj	(revision 7555)
+++ build/vs2015xp/libopenmpt_test.vcxproj	(working copy)
@@ -366,6 +366,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2015xp/libopenmpt_test.vcxproj.filters
===================================================================
--- build/vs2015xp/libopenmpt_test.vcxproj.filters	(revision 7555)
+++ build/vs2015xp/libopenmpt_test.vcxproj.filters	(working copy)
@@ -533,6 +533,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: build/vs2015xp/OpenMPT.vcxproj
===================================================================
--- build/vs2015xp/OpenMPT.vcxproj	(revision 7555)
+++ build/vs2015xp/OpenMPT.vcxproj	(working copy)
@@ -1062,6 +1062,7 @@
     <ClCompile Include="..\..\soundlib\Load_s3m.cpp" />
     <ClCompile Include="..\..\soundlib\Load_sfx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_stm.cpp" />
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp" />
     <ClCompile Include="..\..\soundlib\Load_ult.cpp" />
     <ClCompile Include="..\..\soundlib\Load_umx.cpp" />
     <ClCompile Include="..\..\soundlib\Load_wav.cpp" />
Index: build/vs2015xp/OpenMPT.vcxproj.filters
===================================================================
--- build/vs2015xp/OpenMPT.vcxproj.filters	(revision 7555)
+++ build/vs2015xp/OpenMPT.vcxproj.filters	(working copy)
@@ -1178,6 +1178,9 @@
     <ClCompile Include="..\..\soundlib\Load_stm.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\soundlib\Load_stp.cpp">
+      <Filter>soundlib</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\soundlib\Load_ult.cpp">
       <Filter>soundlib</Filter>
     </ClCompile>
Index: installer/filetypes.iss
===================================================================
--- installer/filetypes.iss	(revision 7555)
+++ installer/filetypes.iss	(working copy)
@@ -47,6 +47,7 @@
 Name: "associate_exotic\sfx2"; Description: "SoundFX 2 (SFX2)";
 Name: "associate_exotic\st26"; Description: "SoundTracker 2.6 (ST26)";
 Name: "associate_exotic\stm"; Description: "Scream Tracker 2 (STM)";
+Name: "associate_exotic\stp"; Description: "Soundtracker Pro II (STP)";
 Name: "associate_exotic\ult"; Description: "UltraTracker (ULT)";
 Name: "associate_exotic\umx"; Description: "Unreal Music (UMX)";
 Name: "associate_exotic\wow"; Description: "Grave Composer (WOW)";
@@ -95,6 +96,7 @@
 Root: HKCR; Subkey: ".sfx2"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_exotic\sfx2
 Root: HKCR; Subkey: ".st26"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_exotic\st26
 Root: HKCR; Subkey: ".stm"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_exotic\stm
+Root: HKCR; Subkey: ".stp"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_exotic\stp
 Root: HKCR; Subkey: ".ult"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_exotic\ult
 Root: HKCR; Subkey: ".umx"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_exotic\umx
 Root: HKCR; Subkey: ".wow"; ValueType: string; ValueName: ""; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: associate_exotic\wow
@@ -165,6 +167,7 @@
 Root: HKLM; Subkey: "Software\Clients\Media\OpenMPT\Capabilities\FileAssociations"; ValueType: string; ValueName: ".sfx2"; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: not portable
 Root: HKLM; Subkey: "Software\Clients\Media\OpenMPT\Capabilities\FileAssociations"; ValueType: string; ValueName: ".st26"; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: not portable
 Root: HKLM; Subkey: "Software\Clients\Media\OpenMPT\Capabilities\FileAssociations"; ValueType: string; ValueName: ".stm"; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: not portable
+Root: HKLM; Subkey: "Software\Clients\Media\OpenMPT\Capabilities\FileAssociations"; ValueType: string; ValueName: ".stp"; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: not portable
 Root: HKLM; Subkey: "Software\Clients\Media\OpenMPT\Capabilities\FileAssociations"; ValueType: string; ValueName: ".ult"; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: not portable
 Root: HKLM; Subkey: "Software\Clients\Media\OpenMPT\Capabilities\FileAssociations"; ValueType: string; ValueName: ".umx"; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: not portable
 Root: HKLM; Subkey: "Software\Clients\Media\OpenMPT\Capabilities\FileAssociations"; ValueType: string; ValueName: ".wow"; ValueData: "OpenMPTFile"; Flags: uninsdeletevalue; Tasks: not portable
@@ -211,6 +214,7 @@
 Root: HKLM; Subkey: "Software\Classes\Applications\mptrack.exe\SupportedTypes"; ValueType: string; ValueName: ".sfx2"; ValueData: ""; Flags: uninsdeletevalue; Tasks: not portable
 Root: HKLM; Subkey: "Software\Classes\Applications\mptrack.exe\SupportedTypes"; ValueType: string; ValueName: ".st26"; ValueData: ""; Flags: uninsdeletevalue; Tasks: not portable
 Root: HKLM; Subkey: "Software\Classes\Applications\mptrack.exe\SupportedTypes"; ValueType: string; ValueName: ".stm"; ValueData: ""; Flags: uninsdeletevalue; Tasks: not portable
+Root: HKLM; Subkey: "Software\Classes\Applications\mptrack.exe\SupportedTypes"; ValueType: string; ValueName: ".stp"; ValueData: ""; Flags: uninsdeletevalue; Tasks: not portable
 Root: HKLM; Subkey: "Software\Classes\Applications\mptrack.exe\SupportedTypes"; ValueType: string; ValueName: ".ult"; ValueData: ""; Flags: uninsdeletevalue; Tasks: not portable
 Root: HKLM; Subkey: "Software\Classes\Applications\mptrack.exe\SupportedTypes"; ValueType: string; ValueName: ".umx"; ValueData: ""; Flags: uninsdeletevalue; Tasks: not portable
 Root: HKLM; Subkey: "Software\Classes\Applications\mptrack.exe\SupportedTypes"; ValueType: string; ValueName: ".wow"; ValueData: ""; Flags: uninsdeletevalue; Tasks: not portable
Index: libopenmpt/foo_openmpt.cpp
===================================================================
--- libopenmpt/foo_openmpt.cpp	(revision 7555)
+++ libopenmpt/foo_openmpt.cpp	(working copy)
@@ -319,6 +319,7 @@
 	"*.imf" ";"
 	"*.j2b" ";"
 	"*.plm" ";"
+	"*.stp" ";"
 	"*.sfx" ";"
 	"*.sfx2" ";"
 	"*.mms" ";"
Index: mptrack/Mptrack.cpp
===================================================================
--- mptrack/Mptrack.cpp	(revision 7555)
+++ mptrack/Mptrack.cpp	(working copy)
@@ -1431,7 +1431,7 @@
 		"FastTracker Modules (*.xm)|*.xm;*.xmz|"
 		"Impulse Tracker Modules (*.it)|*.it;*.itz|"
 		"OpenMPT Modules (*.mptm)|*.mptm;*.mptmz|"
-		"Other Modules (mtm,okt,mdl,669,far,...)|*.mtm;*.669;*.ult;*.wow;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.med;*.ams;*.dbm;*.digi;*.dsm;*.umx;*.amf;*.psm;*.mt2;*.gdm;*.imf;*.itp;*.j2b;*.ice;*.st26;*.plm;*.sfx;*.sfx2;*.mms|"
+		"Other Modules (mtm,okt,mdl,669,far,...)|*.mtm;*.669;*.ult;*.wow;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.med;*.ams;*.dbm;*.digi;*.dsm;*.umx;*.amf;*.psm;*.mt2;*.gdm;*.imf;*.itp;*.j2b;*.ice;*.st26;*.plm;*.stp;*.sfx;*.sfx2;*.mms|"
 		"Wave Files (*.wav)|*.wav|"
 		"MIDI Files (*.mid,*.rmi)|*.mid;*.rmi;*.smf|"
 		"All Files (*.*)|*.*||")
Index: soundlib/Load_stp.cpp
===================================================================
--- soundlib/Load_stp.cpp	(nonexistent)
+++ soundlib/Load_stp.cpp	(working copy)
@@ -0,0 +1,923 @@
+/*
+ * Load_stp.cpp
+ * ------------
+ * Purpose: STP (Soundtracker Pro II) module loader
+ * Notes  : A few exotic effects aren't supported.
+ *          Multiple sample loops are supported, but only the first 10 can be used as cue points
+ *          (with 16xx and 18xx).
+ *          Fractional speed values and combined auto effects are handled whenever possible,
+ *          but some effects may be omitted (and there may be tempo accuracy issues).
+ * Authors: Devin Acker
+ *          OpenMPT Devs
+ * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
+ *
+ * Wisdom from the Soundtracker Pro II manual:
+ * "To create shorter patterns, simply create shorter patterns."
+ */
+
+#include "stdafx.h"
+#include "Loaders.h"
+
+OPENMPT_NAMESPACE_BEGIN
+
+// File header (except for "STP3" magic)
+struct STPFileHeader
+{
+	uint16be version;
+	uint8be  numOrders;
+	uint8be  patternLength;
+	uint8be  orderList[128];
+	uint16be speed;
+	uint16be speedFrac;
+	uint16be timerCount;
+	uint16be flags;
+	uint32be reserved;
+	uint16be midiCount; // always 50
+	uint8be  midi[50];
+	uint16be numSamples;
+	uint16be sampleStructSize;
+};
+
+MPT_BINARY_STRUCT(STPFileHeader, 200);
+
+
+// Sample header (versions 0 and 1)
+struct STPSampleHeaderOld
+{
+	char     pathName[31];
+	uint8be  flags;
+	char     fileName[30];
+	uint32be length;
+	uint8be  volume;
+	uint8be  reserved1;
+	uint32be loopStart;
+	uint32be loopLength;
+	uint16be defaultCmd;
+	uint32be reserved2;
+
+	void ConvertToMPT(ModSample &mptSmp) const
+	{
+		mptSmp.Initialize(MOD_TYPE_MOD);
+		mptSmp.nLength = length;
+		mptSmp.nVolume = 4u * std::min<uint16>(volume, 64);
+
+		mptSmp.nLoopStart = loopStart;
+		mptSmp.nLoopEnd = loopStart + loopLength;
+
+		if(mptSmp.nLoopStart >= mptSmp.nLength)
+		{
+			mptSmp.nLoopStart = mptSmp.nLength - 1;
+		}
+		if(mptSmp.nLoopEnd > mptSmp.nLength)
+		{
+			mptSmp.nLoopEnd = mptSmp.nLength;
+		}
+
+		if(mptSmp.nLoopStart > mptSmp.nLoopEnd)
+		{
+			mptSmp.nLoopStart = 0;
+			mptSmp.nLoopEnd = 0;
+		}
+		else if(mptSmp.nLoopEnd > mptSmp.nLoopStart)
+		{
+			mptSmp.uFlags.set(CHN_LOOP);
+		}
+	}
+
+	void Read(FileReader &file)
+	{
+		file.ReadStruct(*this);
+	}
+};
+
+MPT_BINARY_STRUCT(STPSampleHeaderOld, 82);
+
+
+// Sample header (version 2), no endian-defined integers due to variable string length and alignment in file (we read the fields manually)
+struct STPSampleHeader
+{
+	//char pathName[256];
+	uint8  flags;
+	char   fileName[30];
+	uint32 length;
+	uint8  volume;
+	uint8  reserved1;
+	uint32 loopStart;
+	uint32 loopLength;
+	uint16 defaultCmd;
+	uint16 defaultPeriod;
+	uint8  finetune;
+	uint8  reserved2;
+
+	void ConvertToMPT(ModSample &mptSmp) const
+	{
+		mptSmp.Initialize(MOD_TYPE_MOD);
+		mptSmp.nLength = length;
+		mptSmp.nFineTune = static_cast<int8>(finetune << 3);
+		mptSmp.nVolume = 4 * std::min<uint8>(volume, 64);
+
+		mptSmp.nLoopStart = loopStart;
+		mptSmp.nLoopEnd = loopStart + loopLength;
+
+		if(mptSmp.nLoopStart >= mptSmp.nLength)
+		{
+			mptSmp.nLoopStart = mptSmp.nLength - 1;
+		}
+		if(mptSmp.nLoopEnd > mptSmp.nLength)
+		{
+			mptSmp.nLoopEnd = mptSmp.nLength;
+		}
+
+		if(mptSmp.nLoopStart > mptSmp.nLoopEnd)
+		{
+			mptSmp.nLoopStart = 0;
+			mptSmp.nLoopEnd = 0;
+		} else if(mptSmp.nLoopEnd > mptSmp.nLoopStart)
+		{
+			mptSmp.cues[0] = mptSmp.nLoopStart;
+			mptSmp.uFlags.set(CHN_LOOP);
+		}
+	}
+
+	void Read(FileReader &file)
+	{
+		std::string str;
+
+		file.ReadNullString(str, 255);
+		//mpt::String::Copy(pathName, str);
+
+		flags = file.ReadUint8();
+
+		file.ReadNullString(str, 29);
+		mpt::String::Copy(fileName, str);
+
+		// seek to even boundary
+		if(file.GetPosition() % 2u)
+			file.Skip(1);
+
+		length = file.ReadUint32BE();
+		volume = file.ReadUint8();
+		reserved1 = file.ReadUint8();
+
+		loopStart = file.ReadUint32BE();
+		loopLength = file.ReadUint32BE();
+
+		defaultCmd = file.ReadUint16BE();
+		defaultPeriod = file.ReadUint16BE();
+
+		finetune = file.ReadUint8();
+		reserved2 = file.ReadUint8();
+	}
+};
+
+struct STPLoopInfo
+{
+	SmpLength loopStart;
+	SmpLength loopLength;
+	SAMPLEINDEX looped;
+	SAMPLEINDEX nonLooped;
+};
+
+typedef std::vector<STPLoopInfo> STPLoopList;
+
+template <typename T>
+static void ReadSample(FileReader &file, T &sampleHeader, ModSample &sample, char (&sampleName)[MAX_SAMPLENAME])
+//--------------------------------------------------------------------------------------------------------------
+{
+	sampleHeader.Read(file);
+	sampleHeader.ConvertToMPT(sample);
+
+	mpt::String::Read<mpt::String::maybeNullTerminated>(sampleName, sampleHeader.fileName);
+}
+
+
+static TEMPO ConvertTempo(uint16 ciaSpeed)
+//----------------------------------------
+{
+	// 3546 is the resulting CIA timer value when using 4F7D (tempo 125 bpm) command in STProII
+	return TEMPO((125.0 * 3546.0) / ciaSpeed);
+}
+
+
+static void ConvertLoopSlice(ModSample &src, ModSample &dest, SmpLength start, SmpLength len, bool loop)
+//------------------------------------------------------------------------------------------------------
+{
+	if(!src.HasSampleData()) return;
+
+	dest.FreeSample();
+
+	dest = src;
+	dest.nLength = len;
+	dest.pSample = nullptr;
+
+	if(!dest.AllocateSample())
+	{
+		return;
+	}
+
+	// only preserve cue points if the target sample length is the same
+	if(len != src.nLength)
+		MemsetZero(dest.cues);
+
+	std::memcpy(dest.pSample8, src.pSample8 + start, len);
+	if(loop)
+	{
+		dest.nLoopStart = 0;
+		dest.nLoopEnd = len;
+		dest.uFlags.set(CHN_LOOP);
+	} else
+	{
+		dest.nLoopStart = 0;
+		dest.nLoopEnd = 0;
+		dest.uFlags.reset(CHN_LOOP);
+	}
+}
+
+static void ConvertLoopSequence(ModSample &smp, STPLoopList &loopList)
+//--------------------------------------------------------------------
+{
+	// This should only modify a sample if it has more than one loop
+	// (otherwise, it behaves like a normal sample loop)
+	if(!smp.HasSampleData() || loopList.size() < 2) return;
+
+	ModSample newSmp = smp;
+	newSmp.nLength = 0;
+	newSmp.pSample = nullptr;
+
+	size_t numLoops = loopList.size();
+
+	// get the total length of the sample after combining all looped sections
+	for(size_t i = 0; i < numLoops; i++)
+	{
+		STPLoopInfo &info = loopList[i];
+
+		// if adding this loop would cause the sample length to exceed maximum,
+		// then limit and bail out
+		if((newSmp.nLength + info.loopLength > MAX_SAMPLE_LENGTH) ||
+		   (info.loopLength > MAX_SAMPLE_LENGTH) ||
+		   (info.loopStart + info.loopLength > smp.nLength))
+		{
+			numLoops = i;
+			break;
+		}
+
+		newSmp.nLength += info.loopLength;
+	}
+
+	if(!newSmp.AllocateSample())
+	{
+		return;
+	}
+
+	// start copying the looped sample data parts
+	SmpLength start = 0;
+
+	for(size_t i = 0; i < numLoops; i++)
+	{
+		STPLoopInfo &info = loopList[i];
+
+		memcpy(newSmp.pSample8 + start, smp.pSample8 + info.loopStart, info.loopLength);
+
+		// update loop info based on position in edited sample
+		info.loopStart = start;
+		if(i > 0 && i <= CountOf(newSmp.cues))
+		{
+			newSmp.cues[i - 1] = start;
+		}
+		start += info.loopLength;
+	}
+
+	// replace old sample with new one
+	smp.FreeSample();
+	smp = newSmp;
+
+	smp.nLoopStart = 0;
+	smp.nLoopEnd = smp.nLength;
+	smp.uFlags.set(CHN_LOOP);
+}
+
+
+bool CSoundFile::ReadSTP(FileReader &file, ModLoadingFlags loadFlags)
+//-------------------------------------------------------------------
+{
+	file.Rewind();
+	if(!file.ReadMagic("STP3"))
+		return false;
+
+	STPFileHeader fileHeader;
+	file.ReadStruct(fileHeader);
+	if(fileHeader.version > 2
+		|| fileHeader.numOrders > 128
+		|| fileHeader.numSamples >= MAX_SAMPLES
+		|| fileHeader.midiCount != 50)
+		return false;
+
+	if(loadFlags == onlyVerifyHeader)
+		return true;
+
+	InitializeGlobals(MOD_TYPE_STP);
+
+	m_nChannels = 4;
+	m_nSamples = 0;
+	m_nInstruments = 0;
+
+	m_nDefaultSpeed = fileHeader.speed;
+	m_nDefaultTempo = ConvertTempo(fileHeader.timerCount);
+
+	m_nMinPeriod = 14 * 4;
+	m_nMaxPeriod = 3424 * 4;
+
+	Order.ReadFromArray(fileHeader.orderList, fileHeader.numOrders);
+
+	std::vector<STPLoopList> loopInfo;
+	// non-looped versions of samples with loops (when needed)
+	std::vector<SAMPLEINDEX> nonLooped;
+
+	// Load sample headers
+	SAMPLEINDEX samplesInFile = 0;
+
+	for(SAMPLEINDEX smp = 1; smp <= fileHeader.numSamples; smp++)
+	{
+		// this is 1-based the same as smp
+		SAMPLEINDEX actualSmp = file.ReadUint16BE();
+		if(actualSmp >= MAX_SAMPLES)
+			return false;
+
+		samplesInFile = m_nSamples = std::max(m_nSamples, actualSmp);
+
+		ModSample &thisSmp = Samples[actualSmp];
+
+		if(fileHeader.version == 2)
+		{
+			STPSampleHeader sampleHeader;
+			uint32 headerSize = file.ReadUint32BE();
+
+			ReadSample(file, sampleHeader, thisSmp, m_szNames[actualSmp]);
+			// TODO: verify string lengths against headerSize?
+			MPT_UNUSED_VARIABLE(headerSize);
+		} else
+		{
+			STPSampleHeaderOld sampleHeaderOld;
+			ReadSample(file, sampleHeaderOld, thisSmp, m_szNames[actualSmp]);
+		}
+
+		STPLoopList loopList;
+
+		if(fileHeader.version >= 1)
+		{
+			uint16 numLoops = file.ReadUint16BE();
+
+			STPLoopInfo loop;
+			loop.looped = loop.nonLooped = 0;
+
+			if(numLoops == 0 && thisSmp.uFlags[CHN_LOOP])
+			{
+				loop.loopStart  = thisSmp.nLoopStart;
+				loop.loopLength = thisSmp.nLoopEnd - thisSmp.nLoopStart;
+				loopList.push_back(loop);
+			} else for(SAMPLEINDEX i = 0; i < numLoops; i++)
+			{
+				loop.loopStart  = file.ReadUint32BE();
+				loop.loopLength = file.ReadUint32BE();
+				loopList.push_back(loop);
+			}
+		}
+
+		if(actualSmp)
+		{
+			nonLooped.resize(actualSmp);
+			loopInfo.resize(actualSmp);
+			loopInfo[actualSmp - 1] = loopList;
+		}
+	}
+
+	// Load patterns
+	uint16 numPatterns = 128;
+	if(fileHeader.version == 0)
+		numPatterns = file.ReadUint16BE();
+
+	uint16 patternLength = fileHeader.patternLength;
+	CHANNELINDEX channels = 4;
+	if(fileHeader.version > 0)
+	{
+		// Scan for total number of channels
+		FileReader::off_t patOffset = file.GetPosition();
+		for(uint16 pat = 0; pat < numPatterns; pat++)
+		{
+			PATTERNINDEX actualPat = file.ReadUint16BE();
+			if(actualPat == 0xFFFF)
+				break;
+
+			patternLength = file.ReadUint16BE();
+			channels = file.ReadUint16BE();
+			m_nChannels = std::max(m_nChannels, channels);
+
+			file.Skip(channels * patternLength * 4u);
+		}
+		file.Seek(patOffset);
+		if(m_nChannels > MAX_BASECHANNELS)
+			return false;
+	}
+
+	uint8 globalVolSlide = 0;
+	std::vector<uint8> autoFinePorta(m_nChannels, 0);
+	std::vector<uint8> autoPortaUp(m_nChannels, 0);
+	std::vector<uint8> autoPortaDown(m_nChannels, 0);
+	std::vector<uint8> autoVolSlide(m_nChannels, 0);
+	std::vector<uint8> autoVibrato(m_nChannels, 0);
+	std::vector<uint8> vibratoMem(m_nChannels, 0);
+	std::vector<uint8> autoTremolo(m_nChannels, 0);
+	std::vector<uint8> autoTonePorta(m_nChannels, 0);
+	std::vector<uint8> tonePortaMem(m_nChannels, 0);
+
+	for(uint16 pat = 0; pat < numPatterns; pat++)
+	{
+		PATTERNINDEX actualPat = pat;
+
+		if(fileHeader.version > 0)
+		{
+			actualPat = file.ReadUint16BE();
+			if(actualPat == 0xFFFF)
+				break;
+
+			patternLength = file.ReadUint16BE();
+			channels = file.ReadUint16BE();
+		}
+
+		if(!(loadFlags & loadPatternData) || !Patterns.Insert(actualPat, patternLength))
+		{
+			file.Skip(channels * patternLength * 4u);
+			continue;
+		}
+
+		for(ROWINDEX row = 0; row < patternLength; row++)
+		{
+			PatternRow rowBase = Patterns[actualPat].GetpModCommand(row, 0);
+
+			bool didGlobalVolSlide = false;
+			bool shouldDelay = false;
+
+			// if a fractional speed value is in use then determine if we should stick a fine pattern delay somewhere
+			switch(fileHeader.speedFrac & 3)
+			{
+			// 1/4
+			case 1: shouldDelay = (row & 3) == 0; break;
+			// 1/2
+			case 2: shouldDelay = (row & 1) == 0; break;
+			// 3/4
+			case 3: shouldDelay = (row & 3) != 3; break;
+			}
+
+			for(CHANNELINDEX chn = 0; chn < channels; chn++)
+			{
+				ModCommand &m = rowBase[chn];
+				uint8 data[4];
+				file.ReadArray(data);
+
+				m.instr   = data[0];
+				m.note    = data[1];
+				m.command = data[2];
+				m.param   = data[3];
+
+				if(m.note)
+				{
+					m.note += 24 + NOTE_MIN;
+
+					autoFinePorta[chn] = 0;
+					autoPortaUp[chn] = 0;
+					autoPortaDown[chn] = 0;
+					autoVolSlide[chn] = 0;
+					autoVibrato[chn] = vibratoMem[chn] = 0;
+					autoTremolo[chn] = 0;
+					autoTonePorta[chn] = tonePortaMem[chn] = 0;
+				}
+
+				// this is a nibble-swapped param value used for auto fine volside
+				// and auto global fine volside
+				uint8 swap = (m.param >> 4) | (m.param << 4);
+
+				if((m.command & 0xF0) == 0xF0)
+				{
+					m.param = mpt::saturate_cast<ModCommand::PARAM>(Util::Round(ConvertTempo(m.param | (((uint16)m.command & 0xF) << 8)).ToDouble()));
+					m.command = CMD_TEMPO;
+				} else switch(m.command)
+				{
+				case 0x00: // arpeggio
+					if(m.param)
+						m.command = CMD_ARPEGGIO;
+					break;
+
+				case 0x01: // portamento up
+					m.command = CMD_PORTAMENTOUP;
+					break;
+
+				case 0x02: // portamento down
+					m.command = CMD_PORTAMENTODOWN;
+					break;
+
+				case 0x03: // auto fine portamento up
+					autoFinePorta[chn] = 0x10 | std::min(m.param, ModCommand::PARAM(15));
+					autoPortaUp[chn] = 0;
+					autoPortaDown[chn] = 0;
+					autoTonePorta[chn] = 0;
+
+					m.command = m.param = 0;
+					break;
+
+				case 0x04: // auto fine portamento down
+					autoFinePorta[chn] = 0x20 | std::min(m.param, ModCommand::PARAM(15));
+					autoPortaUp[chn] = 0;
+					autoPortaDown[chn] = 0;
+					autoTonePorta[chn] = 0;
+
+					m.command = m.param = 0;
+					break;
+
+				case 0x05: // auto portamento up
+					autoFinePorta[chn] = 0;
+					autoPortaUp[chn] = m.param;
+					autoPortaDown[chn] = 0;
+					autoTonePorta[chn] = 0;
+
+					m.command = m.param = 0;
+					break;
+
+				case 0x06: // auto portamento down
+					autoFinePorta[chn] = 0;
+					autoPortaUp[chn] = 0;
+					autoPortaDown[chn] = m.param;
+					autoTonePorta[chn] = 0;
+
+					m.command = m.param = 0;
+					break;
+
+				case 0x07: // set global volume
+					m.command = CMD_GLOBALVOLUME;
+					globalVolSlide = 0;
+					break;
+
+				case 0x08: // auto global fine volume slide
+					globalVolSlide = swap;
+					m.command = m.param = 0;
+					break;
+
+				case 0x09: // fine portamento up
+					m.command = CMD_MODCMDEX;
+					m.param = 0x10 | std::min(m.param, ModCommand::PARAM(15));
+					break;
+
+				case 0x0A: // fine portamento down
+					m.command = CMD_MODCMDEX;
+					m.param = 0x20 | std::min(m.param, ModCommand::PARAM(15));
+					break;
+
+				case 0x0B: // auto fine volume slide
+					autoVolSlide[chn] = swap;
+					m.command = m.param = 0;
+					break;
+
+				case 0x0C: // set volume
+					m.volcmd = VOLCMD_VOLUME;
+					m.vol = m.param;
+					autoVolSlide[chn] = 0;
+					m.command = m.param = 0;
+					break;
+
+				case 0x0D: // volume slide (param is swapped compared to .mod)
+					if(m.param & 0xF0)
+					{
+						m.volcmd = VOLCMD_VOLSLIDEDOWN;
+						m.vol = m.param >> 4;
+					} else if(m.param & 0x0F)
+					{
+						m.volcmd = VOLCMD_VOLSLIDEUP;
+						m.vol = m.param & 0xF;
+					}
+					autoVolSlide[chn] = 0;
+					m.command = m.param = 0;
+					break;
+
+				case 0x0E: // set filter (also uses opposite value compared to .mod)
+					m.command = CMD_MODCMDEX;
+					m.param = 1 ^ (m.param ? 1 : 0);
+					break;
+
+				case 0x0F: // set speed
+					m.command = CMD_SPEED;
+					fileHeader.speedFrac = m.param & 0xF;
+					m.param >>= 4;
+					break;
+
+				case 0x10: // auto vibrato
+					autoVibrato[chn] = m.param;
+					vibratoMem[chn] = 0;
+					m.command = m.param = 0;
+					break;
+
+				case 0x11: // auto tremolo
+					if(m.param & 0xF)
+						autoTremolo[chn] = m.param;
+					else
+						autoTremolo[chn] = 0;
+					m.command = m.param = 0;
+					break;
+
+				case 0x12: // pattern break
+					m.command = CMD_PATTERNBREAK;
+					break;
+
+				case 0x13: // auto tone portamento
+					autoFinePorta[chn] = 0;
+					autoPortaUp[chn] = 0;
+					autoPortaDown[chn] = 0;
+					autoTonePorta[chn] = m.param;
+
+					tonePortaMem[chn] = 0;
+					m.command = m.param = 0;
+					break;
+
+				case 0x14: // position jump
+					m.command = CMD_POSITIONJUMP;
+					break;
+
+				case 0x16: // start loop sequence
+					if(m.instr && m.instr <= loopInfo.size())
+					{
+						STPLoopList &loopList = loopInfo[m.instr - 1];
+
+						m.param--;
+						if(m.param < std::min(MPT_ARRAY_COUNT(ModSample().cues), loopList.size()))
+						{
+							m.volcmd = VOLCMD_OFFSET;
+							m.vol = m.param;
+						}
+					}
+
+					m.command = m.param = 0;
+					break;
+
+				case 0x17: // play only loop nn
+					if(m.instr && m.instr <= loopInfo.size())
+					{
+						STPLoopList &loopList = loopInfo[m.instr - 1];
+
+						m.param--;
+						if(m.param < loopList.size())
+						{
+							if(!loopList[m.param].looped && m_nSamples < MAX_SAMPLES - 1)
+								loopList[m.param].looped = ++m_nSamples;
+							m.instr = static_cast<ModCommand::INSTR>(loopList[m.param].looped);
+						}
+					}
+
+					m.command = m.param = 0;
+					break;
+
+				case 0x18: // play sequence without loop
+					if(m.instr && m.instr <= loopInfo.size())
+					{
+						STPLoopList &loopList = loopInfo[m.instr - 1];
+
+						m.param--;
+						if(m.param < std::min(MPT_ARRAY_COUNT(ModSample().cues), loopList.size()))
+						{
+							m.volcmd = VOLCMD_OFFSET;
+							m.vol = m.param;
+						}
+						// switch to non-looped version of sample and create it if needed
+						if(!nonLooped[m.instr - 1] && m_nSamples < MAX_SAMPLES - 1)
+							nonLooped[m.instr - 1] = ++m_nSamples;
+						m.instr = static_cast<ModCommand::INSTR>(nonLooped[m.instr - 1]);
+					}
+
+					m.command = m.param = 0;
+					break;
+
+				case 0x19: // play only loop nn without loop
+					if(m.instr && m.instr <= loopInfo.size())
+					{
+						STPLoopList &loopList = loopInfo[m.instr - 1];
+
+						m.param--;
+						if(m.param < loopList.size())
+						{
+							if(!loopList[m.param].nonLooped && m_nSamples < MAX_SAMPLES-1)
+								loopList[m.param].nonLooped = ++m_nSamples;
+							m.instr = static_cast<ModCommand::INSTR>(loopList[m.param].nonLooped);
+						}
+					}
+
+					m.command = m.param = 0;
+					break;
+
+				case 0x1D: // fine volume slide (nibble order also swapped)
+					m.command = CMD_VOLUMESLIDE;
+					m.param = swap;
+					if(m.param & 0xF0) // slide down
+						m.param |= 0x0F;
+					else if(m.param & 0x0F)
+						m.param |= 0xF0;
+					break;
+
+				case 0x20: // "delayed fade"
+					// just behave like either a normal fade or a notecut
+					// depending on the speed
+					if(m.param & 0xF0)
+					{
+						autoVolSlide[chn] = m.param >> 4;
+						m.command = m.param = 0;
+					} else
+					{
+						m.command = CMD_MODCMDEX;
+						m.param = 0xC0 | (m.param & 0xF);
+					}
+					break;
+
+				case 0x21: // note delay
+					m.command = CMD_MODCMDEX;
+					m.param = 0xD0 | std::min(m.param, ModCommand::PARAM(15));
+					break;
+
+				case 0x22: // retrigger note
+					m.command = CMD_RETRIG;
+					m.param = std::min(m.param, ModCommand::PARAM(15));
+					break;
+
+				case 0x49: // set sample offset
+					m.command = CMD_OFFSET;
+					break;
+
+				case 0x4E: // other protracker commands (pattern loop / delay)
+					if((m.param & 0xF0) == 0x60 || (m.param & 0xF0) == 0xE0)
+						m.command = CMD_MODCMDEX;
+					else
+						m.command = m.param = 0;
+					break;
+
+				case 0x4F: // set speed/tempo
+					if(m.param < 0x20)
+					{
+						m.command = CMD_SPEED;
+						fileHeader.speedFrac = 0;
+					} else
+					{
+						m.command = CMD_TEMPO;
+					}
+					break;
+
+				default:
+					m.command = CMD_NONE;
+					break;
+				}
+
+				bool didVolSlide = false;
+
+				// try to put volume slide in volume command
+				if(autoVolSlide[chn] && !m.volcmd)
+				{
+					if(autoVolSlide[chn] & 0xF0)
+					{
+						m.volcmd = VOLCMD_FINEVOLUP;
+						m.vol = autoVolSlide[chn] >> 4;
+					} else
+					{
+						m.volcmd = VOLCMD_FINEVOLDOWN;
+						m.vol = autoVolSlide[chn] & 0xF;
+					}
+					didVolSlide = true;
+				}
+
+				// try to place/combine all remaining running effects.
+				if(m.command == CMD_NONE)
+				{
+					if(autoPortaUp[chn])
+					{
+						m.command = CMD_PORTAMENTOUP;
+						m.param = autoPortaUp[chn];
+
+					} else if(autoPortaDown[chn])
+					{
+						m.command = CMD_PORTAMENTODOWN;
+						m.param = autoPortaDown[chn];
+
+					} else if(autoFinePorta[chn])
+					{
+						m.command = CMD_MODCMDEX;
+						m.param = autoFinePorta[chn];
+
+					} else if(autoTonePorta[chn])
+					{
+						m.command = CMD_TONEPORTAMENTO;
+						m.param = tonePortaMem[chn] = autoTonePorta[chn];
+
+					} else if(autoVibrato[chn])
+					{
+						m.command = CMD_VIBRATO;
+						m.param = vibratoMem[chn] = autoVibrato[chn];
+
+					} else if(!didVolSlide && autoVolSlide[chn])
+					{
+						m.command = CMD_VOLUMESLIDE;
+						m.param = autoVolSlide[chn];
+						// convert to a "fine" value by setting the other nibble to 0xF
+						if(m.param & 0x0F)
+							m.param |= 0xF0;
+						else if(m.param & 0xF0)
+							m.param |= 0x0F;
+						didVolSlide = true;
+
+					} else if(autoTremolo[chn])
+					{
+						m.command = CMD_TREMOLO;
+						m.param = autoTremolo[chn];
+
+					} else if(shouldDelay)
+					{
+						// insert a fine pattern delay here
+						m.command = CMD_S3MCMDEX;
+						m.param = 0x61;
+						shouldDelay = false;
+
+					} else if(!didGlobalVolSlide && globalVolSlide)
+					{
+						m.command = CMD_GLOBALVOLSLIDE;
+						m.param = globalVolSlide;
+						// convert to a "fine" value by setting the other nibble to 0xF
+						if(m.param & 0x0F)
+							m.param |= 0xF0;
+						else if(m.param & 0xF0)
+							m.param |= 0x0F;
+
+						didGlobalVolSlide = true;
+					}
+				}
+			}
+
+			// TODO: create/use extra channels for global volslide/delay if needed
+		}
+	}
+
+	// after we know how many channels there really are...
+	m_nSamplePreAmp = 256 / m_nChannels;
+	// Setup channel pan positions and volume
+	SetupMODPanning(true);
+
+	// Skip over scripts and drumpad info
+	if(fileHeader.version > 0)
+	{
+		while(file.CanRead(2))
+		{
+			uint16 scriptNum = file.ReadUint16BE();
+			if(scriptNum == 0xFFFF)
+				break;
+
+			file.Skip(2);
+			uint32 length = file.ReadUint32BE();
+			file.Skip(length);
+		}
+
+		// Skip drumpad stuff
+		file.Skip(17*2);
+	}
+
+	// Reading samples
+	if(loadFlags & loadSampleData)
+	{
+		for(SAMPLEINDEX smp = 1; smp <= samplesInFile; smp++) if(Samples[smp].nLength)
+		{
+			SampleIO(
+				SampleIO::_8bit,
+				SampleIO::mono,
+				SampleIO::littleEndian,
+				SampleIO::signedPCM)
+				.ReadSample(Samples[smp], file);
+
+			ConvertLoopSequence(Samples[smp], loopInfo[smp - 1]);
+
+			// make a non-looping duplicate of this sample if needed
+			if(nonLooped[smp - 1])
+			{
+				ConvertLoopSlice(Samples[smp], Samples[nonLooped[smp-1]], 0, Samples[smp].nLength, false);
+			}
+
+			for(SAMPLEINDEX loop = 0; loop < loopInfo[smp - 1].size(); loop++)
+			{
+				STPLoopInfo &info = loopInfo[smp - 1][loop];
+
+				// make duplicate samples for this individual section if needed
+				if(info.looped)
+				{
+					ConvertLoopSlice(Samples[smp], Samples[info.looped], info.loopStart, info.loopLength, true);
+				}
+				if(info.nonLooped)
+				{
+					ConvertLoopSlice(Samples[smp], Samples[info.nonLooped], info.loopStart, info.loopLength, false);
+				}
+			}
+		}
+	}
+
+	return true;
+}
+
+OPENMPT_NAMESPACE_END

Property changes on: soundlib/Load_stp.cpp
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/x-c++src
\ No newline at end of property
Index: soundlib/Snd_defs.h
===================================================================
--- soundlib/Snd_defs.h	(revision 7555)
+++ soundlib/Snd_defs.h	(working copy)
@@ -98,6 +98,7 @@
 	MOD_TYPE_UAX	= 0x10000000, // sampleset as module
 	MOD_TYPE_PLM	= 0x20000000,
 	MOD_TYPE_SFX	= 0x40000000,
+	MOD_TYPE_STP	= 0x80000000,
 };
 DECLARE_FLAGSET(MODTYPE)
 
Index: soundlib/Snd_fx.cpp
===================================================================
--- soundlib/Snd_fx.cpp	(revision 7555)
+++ soundlib/Snd_fx.cpp	(working copy)
@@ -3434,7 +3434,7 @@
 	else
 		param = pChn->nOldPortaUpDown;
 
-	const bool doFineSlides = !doFinePortamentoAsRegular && !(GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_MT2 | MOD_TYPE_MED | MOD_TYPE_AMF0 | MOD_TYPE_DIGI));
+	const bool doFineSlides = !doFinePortamentoAsRegular && !(GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_MT2 | MOD_TYPE_MED | MOD_TYPE_AMF0 | MOD_TYPE_DIGI | MOD_TYPE_STP));
 
 	// Process MIDI pitch bend for instrument plugins
 	MidiPortamento(nChn, param, doFineSlides);
@@ -3493,7 +3493,7 @@
 	else
 		param = pChn->nOldPortaUpDown;
 
-	const bool doFineSlides = !doFinePortamentoAsRegular && !(GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_MT2 | MOD_TYPE_MED | MOD_TYPE_AMF0 | MOD_TYPE_DIGI));
+	const bool doFineSlides = !doFinePortamentoAsRegular && !(GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_MT2 | MOD_TYPE_MED | MOD_TYPE_AMF0 | MOD_TYPE_DIGI | MOD_TYPE_STP));
 
 	// Process MIDI pitch bend for instrument plugins
 	MidiPortamento(nChn, -static_cast<int>(param), doFineSlides);
@@ -3989,7 +3989,7 @@
 	else
 		param = pChn->nOldVolumeSlide;
 
-	if((GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_MT2 | MOD_TYPE_MED | MOD_TYPE_DIGI)))
+	if((GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_MT2 | MOD_TYPE_MED | MOD_TYPE_DIGI | MOD_TYPE_STP)))
 	{
 		// MOD / XM nibble priority
 		if((param & 0xF0) != 0)
Index: soundlib/Sndfile.cpp
===================================================================
--- soundlib/Sndfile.cpp	(revision 7555)
+++ soundlib/Sndfile.cpp	(working copy)
@@ -309,6 +309,7 @@
 			 && !ReadJ2B(file, loadFlags)
 			 && !ReadPT36(file, loadFlags)
 			 && !ReadSFX(file, loadFlags)
+			 && !ReadSTP(file, loadFlags)
 			 && !ReadMod(file, loadFlags)
 			 && !ReadICE(file, loadFlags)
 			 && !Read669(file, loadFlags)
@@ -1075,6 +1076,7 @@
 	case MOD_TYPE_AMF0:
 	case MOD_TYPE_DIGI:
 	case MOD_TYPE_SFX:
+	case MOD_TYPE_STP:
 		return MOD_TYPE_MOD;
 	case MOD_TYPE_MED:
 		if(m_nDefaultTempo == TEMPO(125, 0) && m_nDefaultSpeed == 6 && !m_nInstruments)
Index: soundlib/Sndfile.h
===================================================================
--- soundlib/Sndfile.h	(revision 7555)
+++ soundlib/Sndfile.h	(working copy)
@@ -680,6 +680,7 @@
 	bool ReadS3M(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule);
 	bool ReadSFX(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule);
 	bool ReadSTM(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule);
+	bool ReadSTP(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule);
 	bool ReadUlt(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule);
 	bool ReadUMX(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule);
 	bool ReadWav(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule);
@@ -884,7 +885,7 @@
 	// Returns true if the current format uses transpose+finetune rather than frequency in Hz to specify middle-C.
 	static bool UseFinetuneAndTranspose(MODTYPE type)
 	{
-		return (type & (MOD_TYPE_AMF0 | MOD_TYPE_DIGI | MOD_TYPE_MED | MOD_TYPE_MOD | MOD_TYPE_MTM | MOD_TYPE_OKT | MOD_TYPE_SFX | MOD_TYPE_XM));
+		return (type & (MOD_TYPE_AMF0 | MOD_TYPE_DIGI | MOD_TYPE_MED | MOD_TYPE_MOD | MOD_TYPE_MTM | MOD_TYPE_OKT | MOD_TYPE_SFX | MOD_TYPE_STP | MOD_TYPE_XM));
 	}
 	bool UseFinetuneAndTranspose() const
 	{
Index: soundlib/Tables.cpp
===================================================================
--- soundlib/Tables.cpp	(revision 7555)
+++ soundlib/Tables.cpp	(working copy)
@@ -90,6 +90,7 @@
 	{ MOD_TYPE_SFX,		"SoundFX",					"sfx" },
 	{ MOD_TYPE_SFX,		"SoundFX",					"sfx2" },
 	{ MOD_TYPE_SFX,		"MultiMedia Sound",			"mms" },
+	{ MOD_TYPE_STP,		"Soundtracker Pro II",		"stp" },
 
 #ifndef NO_ARCHIVE_SUPPORT
 	// Compressed modules
@@ -151,6 +152,7 @@
 	{ MOD_TYPE_DBM , mpt::CharsetISO8859_1  },
 	{ MOD_TYPE_DIGI, mpt::CharsetISO8859_1  },
 	{ MOD_TYPE_SFX , mpt::CharsetISO8859_1  },
+	{ MOD_TYPE_STP,  mpt::CharsetISO8859_1  },
 	// Amiga // DOS
 	{ MOD_TYPE_MOD , mpt::CharsetISO8859_1  },
 	{ MOD_TYPE_MED , mpt::CharsetISO8859_1  },
