Browse code

[NCSF] Utilize the PLAYER blocks in the SDAT if they exist.

Backwards compatibility is kept by treating the lack of PLAYER info as
if all channels are able to be allocated.

Naram Qashat authored on 2014/10/25 23:12:53
Showing 12 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * SSEQ Player - SDAT INFO Entry structures
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-03-21
4
+ * Last modification on 2014-10-25
5 5
  *
6 6
  * Nintendo DS Nitro Composer (SDAT) Specification document found at
7 7
  * http://www.feshrine.net/hacking/doc/nds-sdat.html
... ...
@@ -9,7 +9,7 @@
9 9
 
10 10
 #include "INFOEntry.h"
11 11
 
12
-INFOEntrySEQ::INFOEntrySEQ() : fileID(0), bank(0), vol(0)
12
+INFOEntrySEQ::INFOEntrySEQ() : fileID(0), bank(0), vol(0), ply(0)
13 13
 {
14 14
 }
15 15
 
... ...
@@ -23,7 +23,7 @@ void INFOEntrySEQ::Read(PseudoFile &file)
23 23
 		this->vol = 0x7F; // Prevents nothing for volume
24 24
 	file.ReadLE<uint8_t>(); // cpr
25 25
 	file.ReadLE<uint8_t>(); // ppr
26
-	file.ReadLE<uint8_t>(); // ply
26
+	this->ply = file.ReadLE<uint8_t>();
27 27
 }
28 28
 
29 29
 INFOEntryBANK::INFOEntryBANK() : fileID(0)
... ...
@@ -45,4 +45,16 @@ INFOEntryWAVEARC::INFOEntryWAVEARC() : fileID(0)
45 45
 void INFOEntryWAVEARC::Read(PseudoFile &file)
46 46
 {
47 47
 	this->fileID = file.ReadLE<uint16_t>();
48
+	file.ReadLE<uint16_t>(); // unknown
49
+}
50
+
51
+INFOEntryPLAYER::INFOEntryPLAYER() : channelMask(0)
52
+{
53
+}
54
+
55
+void INFOEntryPLAYER::Read(PseudoFile &file)
56
+{
57
+	file.ReadLE<uint16_t>(); // maxSeqs
58
+	this->channelMask = file.ReadLE<uint16_t>();
59
+	file.ReadLE<uint32_t>(); // heapSize
48 60
 }
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * SSEQ Player - SDAT INFO Entry structures
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-08
4
+ * Last modification on 2014-10-25
5 5
  *
6 6
  * Nintendo DS Nitro Composer (SDAT) Specification document found at
7 7
  * http://www.feshrine.net/hacking/doc/nds-sdat.html
... ...
@@ -25,6 +25,7 @@ struct INFOEntrySEQ : INFOEntry
25 25
 	uint16_t fileID;
26 26
 	uint16_t bank;
27 27
 	uint8_t vol;
28
+	uint8_t ply;
28 29
 
29 30
 	INFOEntrySEQ();
30 31
 
... ...
@@ -49,3 +50,12 @@ struct INFOEntryWAVEARC : INFOEntry
49 50
 
50 51
 	void Read(PseudoFile &file);
51 52
 };
53
+
54
+struct INFOEntryPLAYER : INFOEntry
55
+{
56
+	uint16_t channelMask;
57
+
58
+	INFOEntryPLAYER();
59
+
60
+	void Read(PseudoFile &file);
61
+};
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * SSEQ Player - SDAT INFO Section structures
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-03-25
4
+ * Last modification on 2014-10-25
5 5
  *
6 6
  * Nintendo DS Nitro Composer (SDAT) Specification document found at
7 7
  * http://www.feshrine.net/hacking/doc/nds-sdat.html
... ...
@@ -28,7 +28,7 @@ template<typename T> void INFORecord<T>::Read(PseudoFile &file, uint32_t startOf
28 28
 		}
29 29
 }
30 30
 
31
-INFOSection::INFOSection() : SEQrecord(), BANKrecord(), WAVEARCrecord()
31
+INFOSection::INFOSection() : SEQrecord(), BANKrecord(), WAVEARCrecord(), PLAYERrecord()
32 32
 {
33 33
 }
34 34
 
... ...
@@ -57,4 +57,9 @@ void INFOSection::Read(PseudoFile &file)
57 57
 		file.pos = startOfINFO + recordOffsets[REC_WAVEARC];
58 58
 		this->WAVEARCrecord.Read(file, startOfINFO);
59 59
 	}
60
+	if (recordOffsets[REC_PLAYER])
61
+	{
62
+		file.pos = startOfINFO + recordOffsets[REC_PLAYER];
63
+		this->PLAYERrecord.Read(file, startOfINFO);
64
+	}
60 65
 }
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * SSEQ Player - SDAT INFO Section structures
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-08
4
+ * Last modification on 2014-10-25
5 5
  *
6 6
  * Nintendo DS Nitro Composer (SDAT) Specification document found at
7 7
  * http://www.feshrine.net/hacking/doc/nds-sdat.html
... ...
@@ -27,6 +27,7 @@ struct INFOSection
27 27
 	INFORecord<INFOEntrySEQ> SEQrecord;
28 28
 	INFORecord<INFOEntryBANK> BANKrecord;
29 29
 	INFORecord<INFOEntryWAVEARC> WAVEARCrecord;
30
+	INFORecord<INFOEntryPLAYER> PLAYERrecord;
30 31
 
31 32
 	INFOSection();
32 33
 
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * SSEQ Player - Player structure
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-10-23
4
+ * Last modification on 2014-10-25
5 5
  *
6 6
  * Adapted from source code of FeOS Sound System
7 7
  * By fincs
... ...
@@ -11,7 +11,8 @@
11 11
 #include "Player.h"
12 12
 #include "common.h"
13 13
 
14
-Player::Player() : prio(0), nTracks(0), tempo(0), tempoCount(0), tempoRate(0), masterVol(0), sseqVol(0), sseq(nullptr), sampleRate(0), interpolation(INTERPOLATION_NONE)
14
+Player::Player() : prio(0), nTracks(0), tempo(0), tempoCount(0), tempoRate(0), masterVol(0), sseqVol(0), sseq(nullptr), allowedChannels(0), sampleRate(0),
15
+	interpolation(INTERPOLATION_NONE)
15 16
 {
16 17
 	memset(this->trackIds, 0, sizeof(this->trackIds));
17 18
 	for (size_t i = 0; i < 16; ++i)
... ...
@@ -99,6 +100,8 @@ int Player::ChannelAlloc(int type, int priority)
99 100
 	for (int i = 0; i < arraySize; ++i)
100 101
 	{
101 102
 		int thisChnNo = chnArray[i];
103
+		if (!this->allowedChannels[thisChnNo])
104
+			continue;
102 105
 		Channel &thisChn = this->channels[thisChnNo];
103 106
 		Channel &curChn = this->channels[curChnNo];
104 107
 		if (curChnNo != -1 && thisChn.prio >= curChn.prio)
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * SSEQ Player - Player structure
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-10-18
4
+ * Last modification on 2014-10-25
5 5
  *
6 6
  * Adapted from source code of FeOS Sound System
7 7
  * By fincs
... ...
@@ -10,6 +10,7 @@
10 10
 
11 11
 #pragma once
12 12
 
13
+#include <bitset>
13 14
 #include "SSEQ.h"
14 15
 #include "Track.h"
15 16
 #include "Channel.h"
... ...
@@ -26,6 +27,7 @@ struct Player
26 27
 	uint8_t trackIds[FSS_TRACKCOUNT];
27 28
 	Track tracks[FSS_MAXTRACKS];
28 29
 	Channel channels[16];
30
+	std::bitset<16> allowedChannels;
29 31
 	int16_t variables[32];
30 32
 
31 33
 	uint32_t sampleRate;
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * SSEQ Player - SDAT structure
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-03-21
4
+ * Last modification on 2014-10-25
5 5
  *
6 6
  * Nintendo DS Nitro Composer (SDAT) Specification document found at
7 7
  * http://www.feshrine.net/hacking/doc/nds-sdat.html
... ...
@@ -14,7 +14,7 @@
14 14
 #include "FATSection.h"
15 15
 #include "convert.h"
16 16
 
17
-SDAT::SDAT(PseudoFile &file, uint32_t sseqToLoad) : sseq(), sbnk()
17
+SDAT::SDAT(PseudoFile &file, uint32_t sseqToLoad) : sseq(), sbnk(), player()
18 18
 {
19 19
 	// Read sections
20 20
 	NDSStdHeader header;
... ...
@@ -89,5 +89,11 @@ SDAT::SDAT(PseudoFile &file, uint32_t sseqToLoad) : sseq(), sbnk()
89 89
 			}
90 90
 			else
91 91
 				this->swar[i].release();
92
+
93
+		// Get PLAYER for this SSEQ, if it exists
94
+		if (!infoSection.PLAYERrecord.entries.empty())
95
+			this->player = infoSection.PLAYERrecord.entries[this->sseq->info.ply];
96
+		if (!this->player.channelMask)
97
+			this->player.channelMask = 0xFFFF;
92 98
 	}
93 99
 }
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * SSEQ Player - SDAT structure
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-08
4
+ * Last modification on 2014-10-25
5 5
  *
6 6
  * Nintendo DS Nitro Composer (SDAT) Specification document found at
7 7
  * http://www.feshrine.net/hacking/doc/nds-sdat.html
... ...
@@ -20,6 +20,7 @@ struct SDAT
20 20
 	std::unique_ptr<SSEQ> sseq;
21 21
 	std::unique_ptr<SBNK> sbnk;
22 22
 	std::unique_ptr<SWAR> swar[4];
23
+	INFOEntryPLAYER player;
23 24
 
24 25
 	SDAT(PseudoFile &file, uint32_t sseqToLoad);
25 26
 private:
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * SSEQ Player - SDAT SYMB (Symbol/Filename) Section structures
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-03-25
4
+ * Last modification on 2014-10-25
5 5
  *
6 6
  * Nintendo DS Nitro Composer (SDAT) Specification document found at
7 7
  * http://www.feshrine.net/hacking/doc/nds-sdat.html
... ...
@@ -27,7 +27,7 @@ void SYMBRecord::Read(PseudoFile &file, uint32_t startOffset)
27 27
 		}
28 28
 }
29 29
 
30
-SYMBSection::SYMBSection() : SEQrecord(), BANKrecord(), WAVEARCrecord()
30
+SYMBSection::SYMBSection() : SEQrecord(), BANKrecord(), WAVEARCrecord(), PLAYERrecord()
31 31
 {
32 32
 }
33 33
 
... ...
@@ -56,4 +56,9 @@ void SYMBSection::Read(PseudoFile &file)
56 56
 		file.pos = startOfSYMB + recordOffsets[REC_WAVEARC];
57 57
 		this->WAVEARCrecord.Read(file, startOfSYMB);
58 58
 	}
59
+	if (recordOffsets[REC_PLAYER])
60
+	{
61
+		file.pos = startOfSYMB + recordOffsets[REC_PLAYER];
62
+		this->PLAYERrecord.Read(file, startOfSYMB);
63
+	}
59 64
 }
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * SSEQ Player - SDAT SYMB (Symbol/Filename) Section structures
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-08
4
+ * Last modification on 2014-10-25
5 5
  *
6 6
  * Nintendo DS Nitro Composer (SDAT) Specification document found at
7 7
  * http://www.feshrine.net/hacking/doc/nds-sdat.html
... ...
@@ -29,6 +29,7 @@ struct SYMBSection
29 29
 	SYMBRecord SEQrecord;
30 30
 	SYMBRecord BANKrecord;
31 31
 	SYMBRecord WAVEARCrecord;
32
+	SYMBRecord PLAYERrecord;
32 33
 
33 34
 	SYMBSection();
34 35
 
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - NCSF configuration
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-10-23
4
+ * Last modification on 2014-10-25
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -21,7 +21,7 @@ enum
21 21
 
22 22
 unsigned XSFConfig::initSampleRate = 44100;
23 23
 std::string XSFConfig::commonName = "NCSF Decoder";
24
-std::string XSFConfig::versionNumber = "1.10.3";
24
+std::string XSFConfig::versionNumber = "1.11";
25 25
 unsigned XSFConfig_NCSF::initInterpolation = 4;
26 26
 std::string XSFConfig_NCSF::initMutes = "0000000000000000";
27 27
 
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - NCSF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-10-18
4
+ * Last modification on 2014-10-25
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  *
... ...
@@ -173,6 +173,7 @@ bool XSFPlayer_NCSF::Load()
173 173
 	file.data = &this->sdatData;
174 174
 	this->sdat.reset(new SDAT(file, this->sseq));
175 175
 	auto *sseqToPlay = this->sdat->sseq.get();
176
+	this->player.allowedChannels = std::bitset<16>(this->sdat->player.channelMask);
176 177
 	this->player.sseqVol = Cnv_Scale(sseqToPlay->info.vol);
177 178
 	this->player.sampleRate = this->sampleRate;
178 179
 	this->player.Setup(sseqToPlay);