[NCSF] Move track allocation into the SSEQ command handler.
[NCSF] Move track allocation into the SSEQ command handler.

This was suggested by fincs after I found some sequences that appeared
to do track allocations later in them than expected originally.

file:a/README.txt -> file:b/README.txt
--- a/README.txt
+++ b/README.txt
@@ -8,53 +8,57 @@
 
 Version History
 ---------------
-  v1.0 - 2013-03-25 - Initial Version
-  v1.1 - 2013-04-02 - Fixed crash upon seeking backwards (also causes crash
-                      in XMPlay on stopping).
-                    - Added version number to the plugin description.
-                    - Added 3 more interpolation options: B-spline, Hermite,
-                      and Optimal.
-  v1.2 - 2013-04-07 - Fixed crash if Winamp tries to access a file that no
-                      longer exists, reported by Caitsith2.
-                    - Utilized the SSEQ's volume from the INFO section.
-                    - Minor optimizations.
-  v1.3 - 2013-04-10 - Added more interpolation methods, cleanup of interpolation
-                      code, and stopped using slope to determine points outside
-                      the sample in an attempt to prevent clipping or popping.
-                    - Made it so certain changes in the configuration dialog
-                      will apply immediately after clicking OK.
-                    - Minor optimizations.
-  v1.4 - 2013-04-12 - Removed the Optimal, Lagrange, and Hermite interpolations,
-                      added in 2nd-order Osculating interpolation.
-                    - Changed handling of start/end of SWAV data to use the
-                      closest data point instead of only the current one.
-  v1.5 - 2013-04-18 - Implemented circular interpolation buffer to fix
-                      interpolation, thanks to kode54 for the code.
-  v1.6 - 2013-04-23 - Added Lanczos (Sinc) interpolation. Also modified Cosine
-                      interpolation to use a lookup table instead.
-  v1.7 - 2013-04-26 - Fixed Lanczos interpolation a bit (thanks to kode54), also
-                      allowed the plugin to handle 32-bit samples.
-v1.7.1 - 2013-04-26 - Minor update to scale the phase offset, thanks to kode54.
-  v1.8 - 2013-05-07 - Replaced Lanczos window for Sinc with the Hann window.
-                    - Added a ring buffer designed to work with SWAVs, replaces
-                      kode54's implementation (still have to give him big thanks
-                      for the original implementation).
-                    - Corrected clamping issue which caused some clipping-like
-                      effects.
-v1.8.1 - 2014-06-17 - Reverted Sinc interpolation back to the Lanczos window.
-  v1.9 - 2014-09-28 - Removed the Cosine, B-Spline, and Osculating
-                      interpolations, added 4-point and 6-point Legrange
-                      interpolations in their place.
-                    - Updated zlib to v1.2.8.
-v1.9.1 - 2014-10-05 - Fixed volume issues that stemmed from how FeOS Sound
-                      System was handling volume. Utilized some code from the
-                      Nintendo DS SDK to help fix this.
-                    - Added a clone of DeSmuME's Sound View that only shows up
-                      in debug builds, was used to help me identify the above
-                      issue to fix it.
- v1.10 - 2014-10-13 - Implemented the random, variable, and conditional
-                      commands.
-                    - Fixed loop counter.
+   v1.0 - 2013-03-25 - Initial Version
+   v1.1 - 2013-04-02 - Fixed crash upon seeking backwards (also causes crash
+                       in XMPlay on stopping).
+                     - Added version number to the plugin description.
+                     - Added 3 more interpolation options: B-spline, Hermite,
+                       and Optimal.
+   v1.2 - 2013-04-07 - Fixed crash if Winamp tries to access a file that no
+                       longer exists, reported by Caitsith2.
+                     - Utilized the SSEQ's volume from the INFO section.
+                     - Minor optimizations.
+   v1.3 - 2013-04-10 - Added more interpolation methods, cleanup of interpolation
+                       code, and stopped using slope to determine points outside
+                       the sample in an attempt to prevent clipping or popping.
+                     - Made it so certain changes in the configuration dialog
+                       will apply immediately after clicking OK.
+                     - Minor optimizations.
+   v1.4 - 2013-04-12 - Removed the Optimal, Lagrange, and Hermite interpolations,
+                       added in 2nd-order Osculating interpolation.
+                     - Changed handling of start/end of SWAV data to use the
+                       closest data point instead of only the current one.
+   v1.5 - 2013-04-18 - Implemented circular interpolation buffer to fix
+                       interpolation, thanks to kode54 for the code.
+   v1.6 - 2013-04-23 - Added Lanczos (Sinc) interpolation. Also modified Cosine
+                       interpolation to use a lookup table instead.
+   v1.7 - 2013-04-26 - Fixed Lanczos interpolation a bit (thanks to kode54), also
+                       allowed the plugin to handle 32-bit samples.
+ v1.7.1 - 2013-04-26 - Minor update to scale the phase offset, thanks to kode54.
+   v1.8 - 2013-05-07 - Replaced Lanczos window for Sinc with the Hann window.
+                     - Added a ring buffer designed to work with SWAVs, replaces
+                       kode54's implementation (still have to give him big thanks
+                       for the original implementation).
+                     - Corrected clamping issue which caused some clipping-like
+                       effects.
+ v1.8.1 - 2014-06-17 - Reverted Sinc interpolation back to the Lanczos window.
+   v1.9 - 2014-09-28 - Removed the Cosine, B-Spline, and Osculating
+                       interpolations, added 4-point and 6-point Legrange
+                       interpolations in their place.
+                     - Updated zlib to v1.2.8.
+ v1.9.1 - 2014-10-05 - Fixed volume issues that stemmed from how FeOS Sound
+                       System was handling volume.
+                     - Stopped utilizing SSEQ's volume from the INFO section, as
+                       it seemed like it wasn't used in the real thing.
+                     - Added a clone of DeSmuME's Sound View that only shows up
+                       in debug builds, was used to help me identify the above
+                       issue to fix it.
+  v1.10 - 2014-10-13 - Implemented the random, variable, and conditional
+                       commands.
+                     - Fixed loop counter.
+v1.10.1 - 2014-10-15 - Moved track allocation into the SSEQ command handler on a
+                       suggestion from fincs when I had found a sequence that
+                       allocated tracks later than expected originally.
 
 This is a Winamp plugin to play NCSF files. NCSF is a PSF-style music format that
 uses SDAT files from Nintendo DS ROMs as it's "program".

--- a/src/in_ncsf/SSEQPlayer/Player.cpp
+++ b/src/in_ncsf/SSEQPlayer/Player.cpp
@@ -1,7 +1,7 @@
 /*
  * SSEQ Player - Player structure
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-10-13
+ * Last modification on 2014-10-15
  *
  * Adapted from source code of FeOS Sound System
  * By fincs
@@ -31,21 +31,7 @@
 	this->nTracks = 1;
 	this->trackIds[0] = firstTrack;
 
-	auto pData = &this->sseq->data[0];
-	if (*pData == 0xFE)
-		for (pData += 3; *pData == 0x93; ) // Prepare extra tracks
-		{
-			++pData;
-			int tNum = read8(&pData);
-			auto pos = &this->sseq->data[read24(&pData)];
-			int newTrack = this->TrackAlloc();
-			if (newTrack == -1)
-				continue;
-			this->tracks[newTrack].Init(newTrack, this, pos, tNum);
-			this->trackIds[this->nTracks++] = newTrack;
-		}
-
-	this->tracks[firstTrack].startPos = this->tracks[firstTrack].pos = pData;
+	this->tracks[firstTrack].startPos = this->tracks[firstTrack].pos = &this->sseq->data[0];
 
 	this->ClearState();
 

--- a/src/in_ncsf/SSEQPlayer/Track.cpp
+++ b/src/in_ncsf/SSEQPlayer/Track.cpp
@@ -1,7 +1,7 @@
 /*
  * SSEQ Player - Track structure
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-10-13
+ * Last modification on 2014-10-15
  *
  * Adapted from source code of FeOS Sound System
  * By fincs
@@ -260,6 +260,9 @@
 
 enum SseqCommand
 {
+	SSEQ_CMD_ALLOCTRACK = 0xFE, // Silently ignored
+	SSEQ_CMD_OPENTRACK = 0x93,
+
 	SSEQ_CMD_REST = 0x80,
 	SSEQ_CMD_PATCH = 0x81,
 	SSEQ_CMD_PAN = 0xC0,
@@ -359,6 +362,7 @@
 			case SSEQ_CMD_MUTE:
 				return 1;
 
+			case SSEQ_CMD_ALLOCTRACK:
 			case SSEQ_CMD_TEMPO:
 			case SSEQ_CMD_SWEEPPITCH:
 			case SSEQ_CMD_MODDELAY:
@@ -380,6 +384,9 @@
 			case SSEQ_CMD_CMP_LT:
 			case SSEQ_CMD_CMP_NE:
 				return 3;
+
+			case SSEQ_CMD_OPENTRACK:
+				return 4;
 
 			case SSEQ_CMD_FROMVAR:
 				return 1 | ExtraByteOnNoteOrVarOrCmp; // Technically 2 bytes with an additional 1, leaving 1 off because we will be reading it to determine if the additional byte is needed
@@ -510,6 +517,19 @@
 				// Main commands
 				//-----------------------------------------------------------------
 
+				case SSEQ_CMD_OPENTRACK:
+				{
+					int tNum = read8(pData);
+					auto pos = &this->ply->sseq->data[read24(pData)];
+					int newTrack = this->ply->TrackAlloc();
+					if (newTrack != -1)
+					{
+						this->ply->tracks[newTrack].Init(newTrack, this->ply, pos, tNum);
+						this->ply->trackIds[this->ply->nTracks++] = newTrack;
+					}
+					break;
+				}
+
 				case SSEQ_CMD_REST:
 					this->wait = this->overriding.val(pData, readvl);
 					break;
@@ -595,15 +615,10 @@
 						const uint8_t *rPos = this->stack[this->stackPos - 1].dest;
 						uint8_t &nR = this->loopCount[this->stackPos - 1];
 						uint8_t prevR = nR;
-						if (!prevR)
+						if (!prevR || --nR)
 							*pData = rPos;
 						else
-						{
-							if (--nR)
-								*pData = rPos;
-							else
-								--this->stackPos;
-						}
+							--this->stackPos;
 					}
 					break;
 

--- a/src/in_ncsf/XSFConfig_NCSF.cpp
+++ b/src/in_ncsf/XSFConfig_NCSF.cpp
@@ -1,7 +1,7 @@
 /*
  * xSF - NCSF configuration
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-10-13
+ * Last modification on 2014-10-15
  *
  * Partially based on the vio*sf framework
  */
@@ -21,7 +21,7 @@
 
 unsigned XSFConfig::initSampleRate = 44100;
 std::string XSFConfig::commonName = "NCSF Decoder";
-std::string XSFConfig::versionNumber = "1.10";
+std::string XSFConfig::versionNumber = "1.10.1";
 unsigned XSFConfig_NCSF::initInterpolation = 4;
 std::string XSFConfig_NCSF::initMutes = "0000000000000000";