3 Commits

Author SHA1 Message Date
0ab0929746 started some work on cia/ncch 2025-11-28 17:49:05 +01:00
8c1a48a527 updated to newer palladium 2025-11-28 17:48:54 +01:00
6242a7565e fixes 2025-11-28 17:48:27 +01:00
8 changed files with 105 additions and 89 deletions

View File

@@ -14,6 +14,7 @@ class CTRFF_API BCSTM {
void CleanUp(); void CleanUp();
void ReadGotoBeginning(bool use_loop_beg = false); void ReadGotoBeginning(bool use_loop_beg = false);
void ReadBlock(PD::u32 block, PD::u8* ref); void ReadBlock(PD::u32 block, PD::u8* ref);
PD::u32 LeseZeiger() { return pFile.tellg(); }
/** Some useful Getters */ /** Some useful Getters */
PD::u8 GetNumChannels() const { return pInfoBlock.StreamInfo.ChannelCount; } PD::u8 GetNumChannels() const { return pInfoBlock.StreamInfo.ChannelCount; }
@@ -28,13 +29,13 @@ class CTRFF_API BCSTM {
} }
bool IsLooping() const { return pInfoBlock.StreamInfo.Loop; } bool IsLooping() const { return pInfoBlock.StreamInfo.Loop; }
PD::u32 GetLoopStart() const { PD::u32 GetLoopStart() const {
return pInfoBlock.StreamInfo.LoopStartFrame / GetBlockSamples(); return pInfoBlock.StreamInfo.LoopStartFrame / GetNumBlocks();
} }
PD::u32 GetLoopEnd() const { PD::u32 GetLoopEnd() const {
/** Get temp references for better readability */ /** Get temp references for better readability */
const PD::u32& loop_end = pInfoBlock.StreamInfo.LoopEndFrame; const PD::u32& loop_end = pInfoBlock.StreamInfo.LoopEndFrame;
const PD::u32& block_samples = GetBlockSamples(); const PD::u32& block_samples = GetNumBlocks();
return (loop_end % block_samples ? GetNumBlocks() return (loop_end % block_samples ? block_samples
: loop_end / block_samples); : loop_end / block_samples);
} }
@@ -67,28 +68,22 @@ class CTRFF_API BCSTM {
}; };
struct Reference { struct Reference {
Reference() : TypeID(0), Padding(0), Offset(0) {}
Reference(PD::u16 t, PD::u16 p, PD::u32 o)
: TypeID(t), Padding(p), Offset(o) {}
PD::u16 TypeID; PD::u16 TypeID;
PD::u16 Padding; PD::u16 Padding;
PD::u32 Offset; /** null -> uint32_max */ PD::u32 Offset; /** null -> uint32_max */
}; };
struct ReferenceTable { struct ReferenceTable {
ReferenceTable() : Count(0) {}
PD::u32 Count; PD::u32 Count;
std::vector<Reference> Refs; PD::Vec<Reference> Refs;
}; };
struct SizedReference { struct SizedReference {
SizedReference() : Size(0) {}
Reference Ref; Reference Ref;
PD::u32 Size; PD::u32 Size;
}; };
struct StreamInfo { struct StreamInfo {
StreamInfo();
PD::u8 Encoding; PD::u8 Encoding;
PD::u8 Loop; PD::u8 Loop;
PD::u8 ChannelCount; PD::u8 ChannelCount;
@@ -108,14 +103,11 @@ class CTRFF_API BCSTM {
}; };
struct BlockHeader { struct BlockHeader {
BlockHeader() : Magic(0), Size(0) {}
BlockHeader(PD::u32 m, PD::u32 s) : Magic(m), Size(s) {}
PD::u32 Magic; PD::u32 Magic;
PD::u32 Size; PD::u32 Size;
}; };
struct InfoBlock { struct InfoBlock {
InfoBlock() = default;
BlockHeader Header; BlockHeader Header;
Reference StreamInfoRef; Reference StreamInfoRef;
Reference TrackInfoTabRef; Reference TrackInfoTabRef;
@@ -123,27 +115,19 @@ class CTRFF_API BCSTM {
BCSTM::StreamInfo StreamInfo; BCSTM::StreamInfo StreamInfo;
ReferenceTable TrackInfoTab; ReferenceTable TrackInfoTab;
ReferenceTable ChannelInfoTab; ReferenceTable ChannelInfoTab;
std::vector<Reference> ChannelInfoRefs; /** The refs of the refs ?? */ PD::Vec<Reference> ChannelInfoRefs; /** The refs of the refs ?? */
}; };
/** SeekDataBlock cause they are the same struct */ /** SeekDataBlock cause they are the same struct */
struct SD_Block { struct SD_Block {
SD_Block() {}
BlockHeader Header; BlockHeader Header;
std::vector<PD::u8> Data; PD::Vec<PD::u8> Data;
}; };
struct DSP_ADPCM_Param { struct DSP_ADPCM_Param {
// Lets keep this not clean here :/
DSP_ADPCM_Param() {}
PD::u16 Coefficients[0x10]; PD::u16 Coefficients[0x10];
}; };
struct DSP_ADPCM_Context { struct DSP_ADPCM_Context {
DSP_ADPCM_Context()
: PredictorScale(0),
Reserved(0),
PreviousSample(0),
SecondPreviousSample(0) {}
PD::u8 PredictorScale; PD::u8 PredictorScale;
PD::u8 Reserved; PD::u8 Reserved;
PD::u16 PreviousSample; PD::u16 PreviousSample;
@@ -151,7 +135,6 @@ class CTRFF_API BCSTM {
}; };
struct DSP_ADPCM_Info { struct DSP_ADPCM_Info {
DSP_ADPCM_Info() : Padding(0) {}
DSP_ADPCM_Param Param; DSP_ADPCM_Param Param;
DSP_ADPCM_Context Context; DSP_ADPCM_Context Context;
DSP_ADPCM_Context LoopContext; DSP_ADPCM_Context LoopContext;
@@ -159,13 +142,11 @@ class CTRFF_API BCSTM {
}; };
struct ByteTable { struct ByteTable {
ByteTable(PD::u32 size = 0) : Size(size) {}
PD::u32 Size; PD::u32 Size;
std::vector<PD::u8> Table; PD::Vec<PD::u8> Table;
}; };
struct TrackInfo { struct TrackInfo {
TrackInfo() : Volume(0), Pan(0), Padding(0) {}
PD::u8 Volume; PD::u8 Volume;
PD::u8 Pan; PD::u8 Pan;
PD::u16 Padding; PD::u16 Padding;
@@ -174,15 +155,6 @@ class CTRFF_API BCSTM {
}; };
struct Header { struct Header {
// Warum sieht dass so ~~nicht~~ gut aus...
Header()
: Magic(0),
Endianness(Little),
HeaderSize(0),
Version(0),
FileSize(0),
NumBlocks(0),
Reserved(0) {}
PD::u32 Magic; /** CSTM */ PD::u32 Magic; /** CSTM */
PD::u16 Endianness = Little; /** Default */ PD::u16 Endianness = Little; /** Default */
PD::u16 HeaderSize; /** Header Size probably */ PD::u16 HeaderSize; /** Header Size probably */
@@ -199,7 +171,7 @@ class CTRFF_API BCSTM {
InfoBlock pInfoBlock; InfoBlock pInfoBlock;
SD_Block pSeekBlock; SD_Block pSeekBlock;
SD_Block pDataBlock; SD_Block pDataBlock;
std::vector<DSP_ADPCM_Info> pDSP_ADPCM_Info; PD::Vec<DSP_ADPCM_Info> pDSP_ADPCM_Info;
/** File Stream */ /** File Stream */
std::fstream pFile; std::fstream pFile;
/** Endianness based reader */ /** Endianness based reader */

View File

@@ -46,7 +46,7 @@ class CTRFF_API BCWAV {
struct ReferenceTable { struct ReferenceTable {
PD::u32 Count; PD::u32 Count;
std::vector<Reference> Refs; PD::Vec<Reference> Refs;
}; };
struct SizedReference { struct SizedReference {
@@ -88,13 +88,13 @@ class CTRFF_API BCWAV {
PD::u32 LoopEndFrame; PD::u32 LoopEndFrame;
PD::u32 Reserved; PD::u32 Reserved;
ReferenceTable ChannelInfoTab; ReferenceTable ChannelInfoTab;
std::vector<Reference> ChannelInfoRefs; /** The refs of the refs ?? */ PD::Vec<Reference> ChannelInfoRefs; /** The refs of the refs ?? */
}; };
struct DataBlock { struct DataBlock {
BlockHeader Header; BlockHeader Header;
PD::u32 Padding[3]; PD::u32 Padding[3];
std::vector<PD::u8> Data; PD::Vec<PD::u8> Data;
}; };
struct DSP_ADPCM_Param { struct DSP_ADPCM_Param {
@@ -129,7 +129,7 @@ class CTRFF_API BCWAV {
SizedReference pDataBlockRef; SizedReference pDataBlockRef;
InfoBlock pInfoBlock; InfoBlock pInfoBlock;
DataBlock pDataBlock; DataBlock pDataBlock;
std::vector<DSP_ADPCM_Info> pDSP_ADPCM_Info; PD::Vec<DSP_ADPCM_Info> pDSP_ADPCM_Info;
/** File Stream */ /** File Stream */
std::fstream pFile; std::fstream pFile;
/** Endianness based reader */ /** Endianness based reader */

24
include/ctrff/cia.hpp Normal file
View File

@@ -0,0 +1,24 @@
#pragma once
#include <ctrff/helper.hpp>
#include <ctrff/pd_p_api.hpp>
#include <ctrff/smdh.hpp>
#include <pd.hpp>
namespace ctrff {
class Cia : public BinFile {
public:
Cia() {}
~Cia() {}
PD::u32 HeaderSize;
PD::u16 Type;
PD::u16 Version;
PD::u32 CertChainSize;
PD::u32 TikSize;
PD::u32 TmdFileSize;
PD::u32 MetaSize;
PD::u64 ContentSize;
PD::u8 ContentIndex[0x2000];
};
} // namespace ctrff

44
include/ctrff/ncch.hpp Normal file
View File

@@ -0,0 +1,44 @@
#pragma once
#include <ctrff/helper.hpp>
#include <ctrff/pd_p_api.hpp>
#include <ctrff/smdh.hpp>
#include <pd.hpp>
namespace ctrff {
class NCCH : public BinFile {
public:
NCCH() {}
~NCCH() {}
PD::u8 Sig[0x100];
PD::u32 Magic;
PD::u32 ContentLen; // 1 (Media Unit) = 0x200 bytes
PD::u64 PartitionID;
PD::u16 MarkerCode;
PD::u16 Version;
PD::u32 Wtf;
PD::u64 ProgramID;
PD::u8 Reserved[0x10];
PD::u8 LogoHash[0x20]; // Firm 5.0.0-11+
PD::u8 ProdCode[0x10];
PD::u8 ExHeaderHash[0x20];
PD::u32 ExHeaderLen;
PD::u32 Reserved1;
PD::u64 Flags;
PD::u32 PlainRegionOff; // In Media Units
PD::u32 PlainRegionSize;
PD::u32 LogoRegionOff;
PD::u32 LogoRegionSize;
PD::u32 ExeFsOff;
PD::u32 ExeFsSize;
PD::u32 ExeFsHashRegionSize;
PD::u32 Reserved2;
PD::u32 RomFsOff;
PD::u32 RomFsSize;
PD::u32 RomFsHashRegionSize;
PD::u32 Reserved;
PD::u8 ExeFsSuperBlockHash[0x20];
PD::u8 RomFsSuperBlockHash[0x20];
};
} // namespace ctrff

View File

@@ -97,9 +97,9 @@ CTRFF_API void BCSTM::ReadInfoBlock(InfoBlock& block) {
std::ios::beg); std::ios::beg);
Reference r; Reference r;
ReadReference(r); ReadReference(r);
block.ChannelInfoRefs.push_back(r); block.ChannelInfoRefs.Add(r);
} }
for (size_t i = 0; i < block.ChannelInfoRefs.size(); i++) { for (size_t i = 0; i < block.ChannelInfoRefs.Size(); i++) {
size_t off = pInfoBlockRef.Ref.Offset; size_t off = pInfoBlockRef.Ref.Offset;
off += sizeof(BlockHeader); off += sizeof(BlockHeader);
off += block.ChannelInfoTabRef.Offset; off += block.ChannelInfoTabRef.Offset;
@@ -108,7 +108,7 @@ CTRFF_API void BCSTM::ReadInfoBlock(InfoBlock& block) {
pFile.seekg(off, std::ios::beg); pFile.seekg(off, std::ios::beg);
DSP_ADPCM_Info t; /** temp */ DSP_ADPCM_Info t; /** temp */
pReader.ReadEx(t); /** This Section gets read normally */ pReader.ReadEx(t); /** This Section gets read normally */
pDSP_ADPCM_Info.push_back(t); pDSP_ADPCM_Info.Add(t);
} }
} }
@@ -119,23 +119,23 @@ CTRFF_API void BCSTM::ReadSeekBlock(SD_Block& block) {
throw std::runtime_error("BCSTM: SeekBlock Size is not 0x20 aligned!"); throw std::runtime_error("BCSTM: SeekBlock Size is not 0x20 aligned!");
} }
pSeekBlock.Data.reserve(pSeekBlock.Header.Size + 1); pSeekBlock.Data.Reserve(pSeekBlock.Header.Size + 1);
for (PD::u32 i = 0; i < pSeekBlock.Header.Size; i++) { for (PD::u32 i = 0; i < pSeekBlock.Header.Size; i++) {
PD::u8 v; PD::u8 v;
pReader.Read(v); pReader.Read(v);
pSeekBlock.Data.push_back(v); pSeekBlock.Data.Add(v);
} }
} }
CTRFF_API void BCSTM::ReadReferenceTab(ReferenceTable& tab) { CTRFF_API void BCSTM::ReadReferenceTab(ReferenceTable& tab) {
pReader.Read(tab.Count); pReader.Read(tab.Count);
tab.Refs.reserve(tab.Count + 1); tab.Refs.Reserve(tab.Count + 1);
for (PD::u32 i = 0; i < tab.Count; i++) { for (PD::u32 i = 0; i < tab.Count; i++) {
Reference r; Reference r;
pReader.Read(r.TypeID); pReader.Read(r.TypeID);
pReader.Read(r.Padding); pReader.Read(r.Padding);
pReader.Read(r.Offset); pReader.Read(r.Offset);
tab.Refs.push_back(r); tab.Refs.Add(r);
} }
} }
@@ -162,12 +162,9 @@ CTRFF_API void BCSTM::ReadGotoBeginning(bool use_loop_beg) {
} }
CTRFF_API void BCSTM::ReadBlock(PD::u32 block, PD::u8* ref) { CTRFF_API void BCSTM::ReadBlock(PD::u32 block, PD::u8* ref) {
if (!ref) {
throw std::runtime_error("BCSTM: pointer ref is nullptr!");
}
if (pFile.tellg() > pHeader.FileSize || block >= GetNumBlocks()) { if (pFile.tellg() > pHeader.FileSize || block >= GetNumBlocks()) {
throw std::runtime_error(std::format( throw std::runtime_error(std::format(
"BCSTM: Decode block out of range! ({}/{})", block, GetNumBlocks())); "BCSTM: Decode block Out of range! ({} > {})", block, GetNumBlocks()));
} }
pFile.read( pFile.read(
reinterpret_cast<char*>(ref), reinterpret_cast<char*>(ref),
@@ -183,32 +180,11 @@ CTRFF_API void BCSTM::CleanUp() {
throw std::runtime_error(e.what()); throw std::runtime_error(e.what());
} }
} }
pInfoBlock = InfoBlock(); pInfoBlock.ChannelInfoRefs.Clear();
pHeader = Header(); pInfoBlock.ChannelInfoTab.Refs.Clear();
pInfoBlockRef = SizedReference(); pInfoBlock.ChannelInfoTab.Count = 0;
pSeekBlockRef = SizedReference(); pInfoBlock.TrackInfoTab.Refs.Clear();
pDataBlockRef = SizedReference(); pInfoBlock.TrackInfoTab.Count = 0;
pInfoBlock = InfoBlock(); pDSP_ADPCM_Info.Clear();
pSeekBlock = SD_Block();
pDataBlock = SD_Block();
pDSP_ADPCM_Info.clear();
}
CTRFF_API BCSTM::StreamInfo::StreamInfo() {
ChannelCount = 0;
Encoding = 0;
LastSampleBlockPaddedSize = 0;
LastSampleBlockSampleNum = 0;
LastSampleBlockSize = 0;
Loop = 0;
LoopEndFrame = 0;
LoopStartFrame = 0;
Padding = 0;
SampleBlockNum = 0;
SampleBlockSampleNum = 0;
SampleBlockSize = 0;
SampleRate = 0;
SeekDataSize = 0;
SeekIntervalSampleNum = 0;
} }
} // namespace ctrff } // namespace ctrff

View File

@@ -67,9 +67,9 @@ CTRFF_API void BCWAV::ReadInfoBlock(InfoBlock& block) {
std::ios::beg); std::ios::beg);
Reference r; Reference r;
ReadReference(r); ReadReference(r);
block.ChannelInfoRefs.push_back(r); block.ChannelInfoRefs.Add(r);
} }
for (size_t i = 0; i < block.ChannelInfoRefs.size(); i++) { for (size_t i = 0; i < block.ChannelInfoRefs.Size(); i++) {
size_t off = pInfoBlockRef.Ref.Offset; size_t off = pInfoBlockRef.Ref.Offset;
off += sizeof(BlockHeader); off += sizeof(BlockHeader);
off += block.ChannelInfoTab.Refs[i].Offset; off += block.ChannelInfoTab.Refs[i].Offset;
@@ -77,19 +77,19 @@ CTRFF_API void BCWAV::ReadInfoBlock(InfoBlock& block) {
pFile.seekg(off, std::ios::beg); pFile.seekg(off, std::ios::beg);
DSP_ADPCM_Info t; /** temp */ DSP_ADPCM_Info t; /** temp */
pReader.ReadEx(t); /** This Section gets read normally */ pReader.ReadEx(t); /** This Section gets read normally */
pDSP_ADPCM_Info.push_back(t); pDSP_ADPCM_Info.Add(t);
} }
} }
CTRFF_API void BCWAV::ReadReferenceTab(ReferenceTable& tab) { CTRFF_API void BCWAV::ReadReferenceTab(ReferenceTable& tab) {
pReader.Read(tab.Count); pReader.Read(tab.Count);
tab.Refs.reserve(tab.Count + 1); tab.Refs.Reserve(tab.Count + 1);
for (PD::u32 i = 0; i < tab.Count; i++) { for (PD::u32 i = 0; i < tab.Count; i++) {
Reference r; Reference r;
pReader.Read(r.TypeID); pReader.Read(r.TypeID);
pReader.Read(r.Padding); pReader.Read(r.Padding);
pReader.Read(r.Offset); pReader.Read(r.Offset);
tab.Refs.push_back(r); tab.Refs.Add(r);
} }
} }
@@ -134,9 +134,9 @@ CTRFF_API void BCWAV::CleanUp() {
throw std::runtime_error(e.what()); throw std::runtime_error(e.what());
} }
} }
pInfoBlock.ChannelInfoRefs.clear(); pInfoBlock.ChannelInfoRefs.Clear();
pInfoBlock.ChannelInfoTab.Refs.clear(); pInfoBlock.ChannelInfoTab.Refs.Clear();
pInfoBlock.ChannelInfoTab.Count = 0; pInfoBlock.ChannelInfoTab.Count = 0;
pDSP_ADPCM_Info.clear(); pDSP_ADPCM_Info.Clear();
} }
} // namespace ctrff } // namespace ctrff

View File

@@ -38,4 +38,4 @@ void BinUtil::Write(const T& v) {
// Write buffer into file // Write buffer into file
m_file.write(reinterpret_cast<const char*>(buf.data()), sizeof(T)); m_file.write(reinterpret_cast<const char*>(buf.data()), sizeof(T));
} }
} // namespace ctrff } // namespace ctrff

View File

@@ -156,4 +156,4 @@ CTRFF_API std::string ctrff::U16toU8(PD::u16 *in, size_t max) {
} }
return result; return result;
} }