[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.
--- a/src/in_ncsf/SSEQPlayer/INFOEntry.cpp
+++ b/src/in_ncsf/SSEQPlayer/INFOEntry.cpp
@@ -1,7 +1,7 @@
/*
* SSEQ Player - SDAT INFO Entry structures
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-03-21
+ * Last modification on 2014-10-25
*
* Nintendo DS Nitro Composer (SDAT) Specification document found at
* http://www.feshrine.net/hacking/doc/nds-sdat.html
@@ -9,7 +9,7 @@
#include "INFOEntry.h"
-INFOEntrySEQ::INFOEntrySEQ() : fileID(0), bank(0), vol(0)
+INFOEntrySEQ::INFOEntrySEQ() : fileID(0), bank(0), vol(0), ply(0)
{
}
@@ -23,7 +23,7 @@
this->vol = 0x7F; // Prevents nothing for volume
file.ReadLE<uint8_t>(); // cpr
file.ReadLE<uint8_t>(); // ppr
- file.ReadLE<uint8_t>(); // ply
+ this->ply = file.ReadLE<uint8_t>();
}
INFOEntryBANK::INFOEntryBANK() : fileID(0)
@@ -45,5 +45,17 @@
void INFOEntryWAVEARC::Read(PseudoFile &file)
{
this->fileID = file.ReadLE<uint16_t>();
+ file.ReadLE<uint16_t>(); // unknown
}
+INFOEntryPLAYER::INFOEntryPLAYER() : channelMask(0)
+{
+}
+
+void INFOEntryPLAYER::Read(PseudoFile &file)
+{
+ file.ReadLE<uint16_t>(); // maxSeqs
+ this->channelMask = file.ReadLE<uint16_t>();
+ file.ReadLE<uint32_t>(); // heapSize
+}
+
--- a/src/in_ncsf/SSEQPlayer/INFOEntry.h
+++ b/src/in_ncsf/SSEQPlayer/INFOEntry.h
@@ -1,7 +1,7 @@
/*
* SSEQ Player - SDAT INFO Entry structures
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-09-08
+ * Last modification on 2014-10-25
*
* Nintendo DS Nitro Composer (SDAT) Specification document found at
* http://www.feshrine.net/hacking/doc/nds-sdat.html
@@ -25,6 +25,7 @@
uint16_t fileID;
uint16_t bank;
uint8_t vol;
+ uint8_t ply;
INFOEntrySEQ();
@@ -50,3 +51,12 @@
void Read(PseudoFile &file);
};
+struct INFOEntryPLAYER : INFOEntry
+{
+ uint16_t channelMask;
+
+ INFOEntryPLAYER();
+
+ void Read(PseudoFile &file);
+};
+
--- a/src/in_ncsf/SSEQPlayer/INFOSection.cpp
+++ b/src/in_ncsf/SSEQPlayer/INFOSection.cpp
@@ -1,7 +1,7 @@
/*
* SSEQ Player - SDAT INFO Section structures
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-03-25
+ * Last modification on 2014-10-25
*
* Nintendo DS Nitro Composer (SDAT) Specification document found at
* http://www.feshrine.net/hacking/doc/nds-sdat.html
@@ -28,7 +28,7 @@
}
}
-INFOSection::INFOSection() : SEQrecord(), BANKrecord(), WAVEARCrecord()
+INFOSection::INFOSection() : SEQrecord(), BANKrecord(), WAVEARCrecord(), PLAYERrecord()
{
}
@@ -57,5 +57,10 @@
file.pos = startOfINFO + recordOffsets[REC_WAVEARC];
this->WAVEARCrecord.Read(file, startOfINFO);
}
+ if (recordOffsets[REC_PLAYER])
+ {
+ file.pos = startOfINFO + recordOffsets[REC_PLAYER];
+ this->PLAYERrecord.Read(file, startOfINFO);
+ }
}
--- a/src/in_ncsf/SSEQPlayer/INFOSection.h
+++ b/src/in_ncsf/SSEQPlayer/INFOSection.h
@@ -1,7 +1,7 @@
/*
* SSEQ Player - SDAT INFO Section structures
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-09-08
+ * Last modification on 2014-10-25
*
* Nintendo DS Nitro Composer (SDAT) Specification document found at
* http://www.feshrine.net/hacking/doc/nds-sdat.html
@@ -27,6 +27,7 @@
INFORecord<INFOEntrySEQ> SEQrecord;
INFORecord<INFOEntryBANK> BANKrecord;
INFORecord<INFOEntryWAVEARC> WAVEARCrecord;
+ INFORecord<INFOEntryPLAYER> PLAYERrecord;
INFOSection();
--- 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-23
+ * Last modification on 2014-10-25
*
* Adapted from source code of FeOS Sound System
* By fincs
@@ -11,7 +11,8 @@
#include "Player.h"
#include "common.h"
-Player::Player() : prio(0), nTracks(0), tempo(0), tempoCount(0), tempoRate(0), masterVol(0), sseqVol(0), sseq(nullptr), sampleRate(0), interpolation(INTERPOLATION_NONE)
+Player::Player() : prio(0), nTracks(0), tempo(0), tempoCount(0), tempoRate(0), masterVol(0), sseqVol(0), sseq(nullptr), allowedChannels(0), sampleRate(0),
+ interpolation(INTERPOLATION_NONE)
{
memset(this->trackIds, 0, sizeof(this->trackIds));
for (size_t i = 0; i < 16; ++i)
@@ -99,6 +100,8 @@
for (int i = 0; i < arraySize; ++i)
{
int thisChnNo = chnArray[i];
+ if (!this->allowedChannels[thisChnNo])
+ continue;
Channel &thisChn = this->channels[thisChnNo];
Channel &curChn = this->channels[curChnNo];
if (curChnNo != -1 && thisChn.prio >= curChn.prio)
--- a/src/in_ncsf/SSEQPlayer/Player.h
+++ b/src/in_ncsf/SSEQPlayer/Player.h
@@ -1,7 +1,7 @@
/*
* SSEQ Player - Player structure
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-10-18
+ * Last modification on 2014-10-25
*
* Adapted from source code of FeOS Sound System
* By fincs
@@ -10,6 +10,7 @@
#pragma once
+#include <bitset>
#include "SSEQ.h"
#include "Track.h"
#include "Channel.h"
@@ -26,6 +27,7 @@
uint8_t trackIds[FSS_TRACKCOUNT];
Track tracks[FSS_MAXTRACKS];
Channel channels[16];
+ std::bitset<16> allowedChannels;
int16_t variables[32];
uint32_t sampleRate;
--- a/src/in_ncsf/SSEQPlayer/SDAT.cpp
+++ b/src/in_ncsf/SSEQPlayer/SDAT.cpp
@@ -1,7 +1,7 @@
/*
* SSEQ Player - SDAT structure
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-03-21
+ * Last modification on 2014-10-25
*
* Nintendo DS Nitro Composer (SDAT) Specification document found at
* http://www.feshrine.net/hacking/doc/nds-sdat.html
@@ -14,7 +14,7 @@
#include "FATSection.h"
#include "convert.h"
-SDAT::SDAT(PseudoFile &file, uint32_t sseqToLoad) : sseq(), sbnk()
+SDAT::SDAT(PseudoFile &file, uint32_t sseqToLoad) : sseq(), sbnk(), player()
{
// Read sections
NDSStdHeader header;
@@ -89,6 +89,12 @@
}
else
this->swar[i].release();
+
+ // Get PLAYER for this SSEQ, if it exists
+ if (!infoSection.PLAYERrecord.entries.empty())
+ this->player = infoSection.PLAYERrecord.entries[this->sseq->info.ply];
+ if (!this->player.channelMask)
+ this->player.channelMask = 0xFFFF;
}
}
--- a/src/in_ncsf/SSEQPlayer/SDAT.h
+++ b/src/in_ncsf/SSEQPlayer/SDAT.h
@@ -1,7 +1,7 @@
/*
* SSEQ Player - SDAT structure
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-09-08
+ * Last modification on 2014-10-25
*
* Nintendo DS Nitro Composer (SDAT) Specification document found at
* http://www.feshrine.net/hacking/doc/nds-sdat.html
@@ -20,6 +20,7 @@
std::unique_ptr<SSEQ> sseq;
std::unique_ptr<SBNK> sbnk;
std::unique_ptr<SWAR> swar[4];
+ INFOEntryPLAYER player;
SDAT(PseudoFile &file, uint32_t sseqToLoad);
private:
--- a/src/in_ncsf/SSEQPlayer/SYMBSection.cpp
+++ b/src/in_ncsf/SSEQPlayer/SYMBSection.cpp
@@ -1,7 +1,7 @@
/*
* SSEQ Player - SDAT SYMB (Symbol/Filename) Section structures
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2013-03-25
+ * Last modification on 2014-10-25
*
* Nintendo DS Nitro Composer (SDAT) Specification document found at
* http://www.feshrine.net/hacking/doc/nds-sdat.html
@@ -27,7 +27,7 @@
}
}
-SYMBSection::SYMBSection() : SEQrecord(), BANKrecord(), WAVEARCrecord()
+SYMBSection::SYMBSection() : SEQrecord(), BANKrecord(), WAVEARCrecord(), PLAYERrecord()
{
}
@@ -56,5 +56,10 @@
file.pos = startOfSYMB + recordOffsets[REC_WAVEARC];
this->WAVEARCrecord.Read(file, startOfSYMB);
}
+ if (recordOffsets[REC_PLAYER])
+ {
+ file.pos = startOfSYMB + recordOffsets[REC_PLAYER];
+ this->PLAYERrecord.Read(file, startOfSYMB);
+ }
}
--- a/src/in_ncsf/SSEQPlayer/SYMBSection.h
+++ b/src/in_ncsf/SSEQPlayer/SYMBSection.h
@@ -1,7 +1,7 @@
/*
* SSEQ Player - SDAT SYMB (Symbol/Filename) Section structures
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-09-08
+ * Last modification on 2014-10-25
*
* Nintendo DS Nitro Composer (SDAT) Specification document found at
* http://www.feshrine.net/hacking/doc/nds-sdat.html
@@ -29,6 +29,7 @@
SYMBRecord SEQrecord;
SYMBRecord BANKrecord;
SYMBRecord WAVEARCrecord;
+ SYMBRecord PLAYERrecord;
SYMBSection();
--- 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-23
+ * Last modification on 2014-10-25
*
* 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.3";
+std::string XSFConfig::versionNumber = "1.11";
unsigned XSFConfig_NCSF::initInterpolation = 4;
std::string XSFConfig_NCSF::initMutes = "0000000000000000";
--- a/src/in_ncsf/XSFPlayer_NCSF.cpp
+++ b/src/in_ncsf/XSFPlayer_NCSF.cpp
@@ -1,7 +1,7 @@
/*
* xSF - NCSF Player
* By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
- * Last modification on 2014-10-18
+ * Last modification on 2014-10-25
*
* Partially based on the vio*sf framework
*
@@ -173,6 +173,7 @@
file.data = &this->sdatData;
this->sdat.reset(new SDAT(file, this->sseq));
auto *sseqToPlay = this->sdat->sseq.get();
+ this->player.allowedChannels = std::bitset<16>(this->sdat->player.channelMask);
this->player.sseqVol = Cnv_Scale(sseqToPlay->info.vol);
this->player.sampleRate = this->sampleRate;
this->player.Setup(sseqToPlay);