Public V0.0.1
This commit is contained in:
8
include/ctrff.hpp
Normal file
8
include/ctrff.hpp
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <ctrff/3dsx.hpp>
|
||||
#include <ctrff/bcstm.hpp>
|
||||
#include <ctrff/bcwav.hpp>
|
||||
#include <ctrff/binutil.hpp>
|
||||
#include <ctrff/lz11.hpp>
|
||||
#include <ctrff/smdh.hpp>
|
48
include/ctrff/3dsx.hpp
Normal file
48
include/ctrff/3dsx.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <ctrff/helper.hpp>
|
||||
#include <ctrff/pd_p_api.hpp>
|
||||
#include <ctrff/smdh.hpp>
|
||||
#include <pd.hpp>
|
||||
|
||||
namespace ctrff {
|
||||
class CTRFF_API _3dsx : public BinFile {
|
||||
public:
|
||||
_3dsx() {}
|
||||
~_3dsx() {}
|
||||
|
||||
void Load(const std::string& path) {
|
||||
std::fstream f(path, std::ios::in | std::ios::binary);
|
||||
Read(f);
|
||||
f.close();
|
||||
}
|
||||
|
||||
bool HasMeta() { return SMDHSize == SMDH_Size; }
|
||||
|
||||
/** Write not supported btw */
|
||||
void Write(std::fstream& f) const override;
|
||||
void Read(std::fstream& f) override;
|
||||
|
||||
PD::u32 Magic;
|
||||
PD::u16 HeaderSize;
|
||||
PD::u16 RelocHeaderSize;
|
||||
PD::u32 FormatVersion;
|
||||
PD::u32 Flags;
|
||||
// Sizes of the code, rodata and data segments +
|
||||
// size of the BSS section (uninitialized latter half of the data segment)
|
||||
PD::u32 CodeSegSize;
|
||||
PD::u32 RodataSegSize;
|
||||
PD::u32 DataSegSize;
|
||||
PD::u32 BssSize;
|
||||
/// Extended Header ///
|
||||
// smdh offset
|
||||
PD::u32 SMDHOff;
|
||||
// smdh size
|
||||
PD::u32 SMDHSize;
|
||||
// fs offset
|
||||
PD::u32 FsOff;
|
||||
SMDH Meta;
|
||||
};
|
||||
/** Probably only germen people will understand */
|
||||
using DreiDSX = _3dsx;
|
||||
} // namespace ctrff
|
241
include/ctrff/bcstm.hpp
Normal file
241
include/ctrff/bcstm.hpp
Normal file
@ -0,0 +1,241 @@
|
||||
#pragma once
|
||||
|
||||
#include <ctrff/binutil.hpp>
|
||||
#include <ctrff/pd_p_api.hpp>
|
||||
#include <pd.hpp>
|
||||
|
||||
namespace ctrff {
|
||||
class CTRFF_API BCSTM {
|
||||
public:
|
||||
BCSTM() : pReader(pFile) {}
|
||||
~BCSTM() { CleanUp(); }
|
||||
|
||||
void LoadFile(const std::string& path);
|
||||
void CleanUp();
|
||||
void ReadGotoBeginning(bool use_loop_beg = false);
|
||||
void ReadBlock(PD::u32 block, PD::u8* ref);
|
||||
PD::u32 LeseZeiger() { return pFile.tellg(); }
|
||||
|
||||
/** Some useful Getters */
|
||||
PD::u8 GetNumChannels() const { return pInfoBlock.StreamInfo.ChannelCount; }
|
||||
PD::u32 GetSampleRate() const { return pInfoBlock.StreamInfo.SampleRate; }
|
||||
PD::u32 GetBlockSize() const { return pInfoBlock.StreamInfo.SampleBlockSize; }
|
||||
PD::u32 GetNumBlocks() const { return pInfoBlock.StreamInfo.SampleBlockNum; }
|
||||
PD::u32 GetBlockSamples() const {
|
||||
return pInfoBlock.StreamInfo.SampleBlockSampleNum;
|
||||
}
|
||||
PD::u32 GetLastBlockSamples() const {
|
||||
return pInfoBlock.StreamInfo.LastSampleBlockSampleNum;
|
||||
}
|
||||
bool IsLooping() const { return pInfoBlock.StreamInfo.Loop; }
|
||||
PD::u32 GetLoopStart() const {
|
||||
return pInfoBlock.StreamInfo.LoopStartFrame / GetNumBlocks();
|
||||
}
|
||||
PD::u32 GetLoopEnd() const {
|
||||
/** Get temp references for better readability */
|
||||
const PD::u32& loop_end = pInfoBlock.StreamInfo.LoopEndFrame;
|
||||
const PD::u32& block_samples = GetNumBlocks();
|
||||
return (loop_end % block_samples ? block_samples
|
||||
: loop_end / block_samples);
|
||||
}
|
||||
|
||||
/** Internal Data (can be made private with private: but public by default) */
|
||||
enum Endianness : PD::u16 {
|
||||
Big = 0xfffe, ///< Big Endian
|
||||
Little = 0xfeff, ///< Little Endian
|
||||
};
|
||||
|
||||
enum ReferenceTypes : PD::u16 {
|
||||
Ref_ByteTable = 0x0100,
|
||||
Ref_ReferenceTable = 0x0101,
|
||||
Ref_DSP_ADPCM_Info = 0x0300,
|
||||
Ref_IMA_ADPCM_Info = 0x0301,
|
||||
Ref_SampleData = 0x1f00,
|
||||
Ref_InfoBlock = 0x4000,
|
||||
Ref_SeekBlock = 0x4001,
|
||||
Ref_DataBlock = 0x4002,
|
||||
Ref_StreamInfo = 0x4100,
|
||||
Ref_TrackInfo = 0x4101,
|
||||
Ref_ChannelInfo = 0x4102,
|
||||
};
|
||||
|
||||
enum Encoding : PD::u8 {
|
||||
PCM8 = 0,
|
||||
PCM16 = 1,
|
||||
/** Only supported encoding in BCSTM-Player */
|
||||
DSP_ADPCM = 2,
|
||||
IMA_ADPCM = 3,
|
||||
};
|
||||
|
||||
struct Reference {
|
||||
PD::u16 TypeID;
|
||||
PD::u16 Padding;
|
||||
PD::u32 Offset; /** null -> uint32_max */
|
||||
};
|
||||
|
||||
struct ReferenceTable {
|
||||
PD::u32 Count;
|
||||
PD::Vec<Reference> Refs;
|
||||
};
|
||||
|
||||
struct SizedReference {
|
||||
Reference Ref;
|
||||
PD::u32 Size;
|
||||
};
|
||||
|
||||
struct StreamInfo {
|
||||
PD::u8 Encoding;
|
||||
PD::u8 Loop;
|
||||
PD::u8 ChannelCount;
|
||||
PD::u8 Padding;
|
||||
PD::u32 SampleRate;
|
||||
PD::u32 LoopStartFrame;
|
||||
PD::u32 LoopEndFrame;
|
||||
PD::u32 SampleBlockNum;
|
||||
PD::u32 SampleBlockSize;
|
||||
PD::u32 SampleBlockSampleNum;
|
||||
PD::u32 LastSampleBlockSize;
|
||||
PD::u32 LastSampleBlockSampleNum;
|
||||
PD::u32 LastSampleBlockPaddedSize;
|
||||
PD::u32 SeekDataSize;
|
||||
PD::u32 SeekIntervalSampleNum;
|
||||
Reference SampleDataRef;
|
||||
};
|
||||
|
||||
struct BlockHeader {
|
||||
PD::u32 Magic;
|
||||
PD::u32 Size;
|
||||
};
|
||||
|
||||
struct InfoBlock {
|
||||
BlockHeader Header;
|
||||
Reference StreamInfoRef;
|
||||
Reference TrackInfoTabRef;
|
||||
Reference ChannelInfoTabRef;
|
||||
BCSTM::StreamInfo StreamInfo;
|
||||
ReferenceTable TrackInfoTab;
|
||||
ReferenceTable ChannelInfoTab;
|
||||
PD::Vec<Reference> ChannelInfoRefs; /** The refs of the refs ?? */
|
||||
};
|
||||
|
||||
/** SeekDataBlock cause they are the same struct */
|
||||
struct SD_Block {
|
||||
BlockHeader Header;
|
||||
PD::Vec<PD::u8> Data;
|
||||
};
|
||||
|
||||
struct DSP_ADPCM_Param {
|
||||
PD::u16 Coefficients[0x10];
|
||||
};
|
||||
struct DSP_ADPCM_Context {
|
||||
PD::u8 PredictorScale;
|
||||
PD::u8 Reserved;
|
||||
PD::u16 PreviousSample;
|
||||
PD::u16 SecondPreviousSample;
|
||||
};
|
||||
|
||||
struct DSP_ADPCM_Info {
|
||||
DSP_ADPCM_Param Param;
|
||||
DSP_ADPCM_Context Context;
|
||||
DSP_ADPCM_Context LoopContext;
|
||||
PD::u16 Padding;
|
||||
};
|
||||
|
||||
struct ByteTable {
|
||||
PD::u32 Size;
|
||||
PD::Vec<PD::u8> Table;
|
||||
};
|
||||
|
||||
struct TrackInfo {
|
||||
PD::u8 Volume;
|
||||
PD::u8 Pan;
|
||||
PD::u16 Padding;
|
||||
Reference ChennelIndexTabRef;
|
||||
ByteTable ChannelIndexTab;
|
||||
};
|
||||
|
||||
struct Header {
|
||||
PD::u32 Magic; /** CSTM */
|
||||
PD::u16 Endianness = Little; /** Default */
|
||||
PD::u16 HeaderSize; /** Header Size probably */
|
||||
PD::u32 Version; /** Format Version? */
|
||||
PD::u32 FileSize; /** File Size */
|
||||
PD::u16 NumBlocks; /** Number of blocks */
|
||||
PD::u16 Reserved; /** Reserved */
|
||||
};
|
||||
|
||||
Header pHeader;
|
||||
SizedReference pInfoBlockRef;
|
||||
SizedReference pSeekBlockRef;
|
||||
SizedReference pDataBlockRef;
|
||||
InfoBlock pInfoBlock;
|
||||
SD_Block pSeekBlock;
|
||||
SD_Block pDataBlock;
|
||||
PD::Vec<DSP_ADPCM_Info> pDSP_ADPCM_Info;
|
||||
/** File Stream */
|
||||
std::fstream pFile;
|
||||
/** Endianness based reader */
|
||||
BinUtil pReader;
|
||||
|
||||
void ReadReference(Reference& ref);
|
||||
void ReadSizedReference(SizedReference& ref);
|
||||
void ReadInfoBlock(InfoBlock& block);
|
||||
void ReadSeekBlock(SD_Block& block);
|
||||
void ReadReferenceTab(ReferenceTable& tab);
|
||||
|
||||
static std::string Endianness2String(const Endianness& e) {
|
||||
switch (e) {
|
||||
case Little:
|
||||
return "Little";
|
||||
case Big:
|
||||
return "Big";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static std::string ReferenceType2String(const ReferenceTypes& e) {
|
||||
switch (e) {
|
||||
case Ref_ByteTable:
|
||||
return "ByteTable";
|
||||
case Ref_ReferenceTable:
|
||||
return "ReferenceTable";
|
||||
case Ref_DSP_ADPCM_Info:
|
||||
return "DSP_ADPCM_Info";
|
||||
case Ref_IMA_ADPCM_Info:
|
||||
return "IMA_ADPCM_Info";
|
||||
case Ref_SampleData:
|
||||
return "SampleData";
|
||||
case Ref_InfoBlock:
|
||||
return "InfoBlock";
|
||||
case Ref_SeekBlock:
|
||||
return "SeekBlock";
|
||||
case Ref_DataBlock:
|
||||
return "DataBlock";
|
||||
case Ref_StreamInfo:
|
||||
return "StreamInfo";
|
||||
case Ref_TrackInfo:
|
||||
return "TrackInfo";
|
||||
case Ref_ChannelInfo:
|
||||
return "ChannelInfo";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static std::string Encoding2String(const Encoding& e) {
|
||||
switch (e) {
|
||||
case PCM8:
|
||||
return "PCM8";
|
||||
case PCM16:
|
||||
return "PCM16";
|
||||
case DSP_ADPCM:
|
||||
return "DSP ADPCM";
|
||||
case IMA_ADPCM:
|
||||
return "IMA ADPCM";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace ctrff
|
188
include/ctrff/bcwav.hpp
Normal file
188
include/ctrff/bcwav.hpp
Normal file
@ -0,0 +1,188 @@
|
||||
#pragma once
|
||||
|
||||
#include <ctrff/binutil.hpp>
|
||||
#include <ctrff/pd_p_api.hpp>
|
||||
#include <pd.hpp>
|
||||
|
||||
namespace ctrff {
|
||||
class CTRFF_API BCWAV {
|
||||
public:
|
||||
BCWAV() : pReader(pFile) {}
|
||||
~BCWAV() { CleanUp(); }
|
||||
|
||||
void LoadFile(const std::string& path);
|
||||
void CleanUp();
|
||||
void ReadGotoBeginning(bool use_loop_beg = false);
|
||||
void ReadBlock(PD::u32 block, PD::u8* ref);
|
||||
|
||||
/** Internal Data (can be made private with private: but public by default) */
|
||||
enum Endianness : PD::u16 {
|
||||
Big = 0xfffe, ///< Big Endian
|
||||
Little = 0xfeff, ///< Little Endian
|
||||
};
|
||||
|
||||
enum ReferenceTypes : PD::u16 {
|
||||
Ref_DSP_ADPCM_Info = 0x0300,
|
||||
Ref_IMA_ADPCM_Info = 0x0301,
|
||||
Ref_SampleData = 0x1f00,
|
||||
Ref_InfoBlock = 0x7000,
|
||||
Ref_DataBlock = 0x7001,
|
||||
Ref_ChannelInfo = 0x7100,
|
||||
};
|
||||
|
||||
enum Encoding : PD::u8 {
|
||||
PCM8 = 0,
|
||||
PCM16 = 1,
|
||||
/** Only supported encoding in BCSTM-Player */
|
||||
DSP_ADPCM = 2,
|
||||
IMA_ADPCM = 3,
|
||||
};
|
||||
|
||||
struct Reference {
|
||||
PD::u16 TypeID;
|
||||
PD::u16 Padding;
|
||||
PD::u32 Offset; /** null -> uint32_max */
|
||||
};
|
||||
|
||||
struct ReferenceTable {
|
||||
PD::u32 Count;
|
||||
PD::Vec<Reference> Refs;
|
||||
};
|
||||
|
||||
struct SizedReference {
|
||||
Reference Ref;
|
||||
PD::u32 Size;
|
||||
};
|
||||
|
||||
struct StreamInfo {
|
||||
PD::u8 Encoding;
|
||||
PD::u8 Loop;
|
||||
PD::u8 ChannelCount;
|
||||
PD::u8 Padding;
|
||||
PD::u32 SampleRate;
|
||||
PD::u32 LoopStartFrame;
|
||||
PD::u32 LoopEndFrame;
|
||||
PD::u32 SampleBlockNum;
|
||||
PD::u32 SampleBlockSize;
|
||||
PD::u32 SampleBlockSampleNum;
|
||||
PD::u32 LastSampleBlockSize;
|
||||
PD::u32 LastSampleBlockSampleNum;
|
||||
PD::u32 LastSampleBlockPaddedSize;
|
||||
PD::u32 SeekDataSize;
|
||||
PD::u32 SeekIntervalSampleNum;
|
||||
Reference SampleDataRef;
|
||||
};
|
||||
|
||||
struct BlockHeader {
|
||||
PD::u32 Magic;
|
||||
PD::u32 Size;
|
||||
};
|
||||
|
||||
struct InfoBlock {
|
||||
BlockHeader Header;
|
||||
PD::u8 Encoding;
|
||||
PD::u8 Loop;
|
||||
PD::u16 Padding;
|
||||
PD::u32 SampleRate;
|
||||
PD::u32 LoopStartFrame;
|
||||
PD::u32 LoopEndFrame;
|
||||
PD::u32 Reserved;
|
||||
ReferenceTable ChannelInfoTab;
|
||||
PD::Vec<Reference> ChannelInfoRefs; /** The refs of the refs ?? */
|
||||
};
|
||||
|
||||
struct DataBlock {
|
||||
BlockHeader Header;
|
||||
PD::u32 Padding[3];
|
||||
PD::Vec<PD::u8> Data;
|
||||
};
|
||||
|
||||
struct DSP_ADPCM_Param {
|
||||
PD::u16 Coefficients[0x10];
|
||||
};
|
||||
struct DSP_ADPCM_Context {
|
||||
PD::u8 PredictorScale;
|
||||
PD::u8 Reserved;
|
||||
PD::u16 PreviousSample;
|
||||
PD::u16 SecondPreviousSample;
|
||||
};
|
||||
|
||||
struct DSP_ADPCM_Info {
|
||||
DSP_ADPCM_Param Param;
|
||||
DSP_ADPCM_Context Context;
|
||||
DSP_ADPCM_Context LoopContext;
|
||||
PD::u16 Padding;
|
||||
};
|
||||
|
||||
struct Header {
|
||||
PD::u32 Magic; /** CWAV */
|
||||
PD::u16 Endianness = Little; /** Default */
|
||||
PD::u16 HeaderSize; /** Header Size probably */
|
||||
PD::u32 Version; /** Format Version? */
|
||||
PD::u32 FileSize; /** File Size */
|
||||
PD::u16 NumBlocks; /** Number of blocks */
|
||||
PD::u16 Reserved; /** Reserved */
|
||||
};
|
||||
|
||||
Header pHeader;
|
||||
SizedReference pInfoBlockRef;
|
||||
SizedReference pDataBlockRef;
|
||||
InfoBlock pInfoBlock;
|
||||
DataBlock pDataBlock;
|
||||
PD::Vec<DSP_ADPCM_Info> pDSP_ADPCM_Info;
|
||||
/** File Stream */
|
||||
std::fstream pFile;
|
||||
/** Endianness based reader */
|
||||
BinUtil pReader;
|
||||
|
||||
void ReadReference(Reference& ref);
|
||||
void ReadSizedReference(SizedReference& ref);
|
||||
void ReadInfoBlock(InfoBlock& block);
|
||||
void ReadReferenceTab(ReferenceTable& tab);
|
||||
|
||||
static std::string Endianness2String(const Endianness& e) {
|
||||
switch (e) {
|
||||
case Little:
|
||||
return "Little";
|
||||
case Big:
|
||||
return "Big";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static std::string ReferenceType2String(const ReferenceTypes& e) {
|
||||
switch (e) {
|
||||
case Ref_DSP_ADPCM_Info:
|
||||
return "DSP_ADPCM_Info";
|
||||
case Ref_IMA_ADPCM_Info:
|
||||
return "IMA_ADPCM_Info";
|
||||
case Ref_SampleData:
|
||||
return "SampleData";
|
||||
case Ref_InfoBlock:
|
||||
return "InfoBlock";
|
||||
case Ref_DataBlock:
|
||||
return "DataBlock";
|
||||
case Ref_ChannelInfo:
|
||||
return "ChannelInfo";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static std::string Encoding2String(const Encoding& e) {
|
||||
switch (e) {
|
||||
case PCM8:
|
||||
return "PCM8";
|
||||
case PCM16:
|
||||
return "PCM16";
|
||||
case DSP_ADPCM:
|
||||
return "DSP ADPCM";
|
||||
case IMA_ADPCM:
|
||||
return "IMA ADPCM";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace ctrff
|
43
include/ctrff/binutil.hpp
Normal file
43
include/ctrff/binutil.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <ctrff/pd_p_api.hpp>
|
||||
#include <pd.hpp>
|
||||
|
||||
namespace ctrff {
|
||||
class BinFile {
|
||||
public:
|
||||
BinFile() = default;
|
||||
~BinFile() = default;
|
||||
|
||||
virtual void Write(std::fstream& s) const = 0;
|
||||
virtual void Read(std::fstream& s) = 0;
|
||||
};
|
||||
|
||||
class CTRFF_API BinUtil {
|
||||
public:
|
||||
BinUtil(std::fstream& f, bool big = false) : m_file(f), m_big(big) {}
|
||||
~BinUtil() = default;
|
||||
|
||||
void SetEndianess(bool big) { m_big = big; }
|
||||
|
||||
template <typename T>
|
||||
void Read(T& v);
|
||||
template <typename T>
|
||||
void Write(const T& v);
|
||||
/** Note that this func ignores Endianness */
|
||||
template <typename T>
|
||||
void ReadEx(T& v) {
|
||||
static_assert(std::is_trivially_copyable_v<T>, "Cannot Read type T");
|
||||
m_file.read(reinterpret_cast<char*>(&v), sizeof(T));
|
||||
}
|
||||
/** Note that this func ignores Endianness */
|
||||
template <typename T>
|
||||
void WriteEx(T& v) {
|
||||
m_file.write(reinterpret_cast<const char*>(&v), sizeof(T));
|
||||
}
|
||||
|
||||
private:
|
||||
std::fstream& m_file;
|
||||
bool m_big;
|
||||
};
|
||||
} // namespace ctrff
|
16
include/ctrff/helper.hpp
Normal file
16
include/ctrff/helper.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <ctrff/pd_p_api.hpp>
|
||||
#include <pd.hpp>
|
||||
|
||||
namespace ctrff {
|
||||
CTRFF_API void String2U16(PD::u16 *res, const std::string &src, size_t max);
|
||||
CTRFF_API std::string U16toU8(PD::u16 *in, size_t max);
|
||||
CTRFF_API void RGB565toRGBA(std::vector<PD::u8> &img, PD::u16 *icon,
|
||||
const int &w, const int &h);
|
||||
// Image can only be rgba8888
|
||||
CTRFF_API void RGBA2RGB565(PD::u16 *out, const std::vector<PD::u8> &img,
|
||||
const int &w, const int &h);
|
||||
CTRFF_API std::vector<PD::u8> DownscaleImage(const std::vector<PD::u8> &img,
|
||||
int w, int h, int scale);
|
||||
} // namespace ctrff
|
10
include/ctrff/lz11.hpp
Normal file
10
include/ctrff/lz11.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <ctrff/pd_p_api.hpp>
|
||||
#include <pd.hpp>
|
||||
|
||||
namespace ctrff {
|
||||
namespace LZ11 {
|
||||
CTRFF_API std::vector<PD::u8> Compress(const std::vector<PD::u8>& in);
|
||||
}
|
||||
} // namespace ctrff
|
50
include/ctrff/pd_p_api.hpp
Normal file
50
include/ctrff/pd_p_api.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 - 2025 tobid7
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32 // Windows (MSVC Tested)
|
||||
#ifdef CTRFF_BUILD_SHARED
|
||||
#define CTRFF_API __declspec(dllexport)
|
||||
#else
|
||||
#define CTRFF_API __declspec(dllimport)
|
||||
#endif
|
||||
#elif defined(__APPLE__) // macOS (untested yet)
|
||||
#ifdef CTRFF_BUILD_SHARED
|
||||
#define CTRFF_API __attribute__((visibility("default")))
|
||||
#else
|
||||
#define CTRFF_API
|
||||
#endif
|
||||
#elif defined(__linux__) // Linux (untested yet)
|
||||
#ifdef CTRFF_BUILD_SHARED
|
||||
#define CTRFF_API __attribute__((visibility("default")))
|
||||
#else
|
||||
#define CTRFF_API
|
||||
#endif
|
||||
#elif defined(__3DS__) // 3ds Specific
|
||||
// Only Static supported
|
||||
#define CTRFF_API
|
||||
#else
|
||||
#define CTRFF_API
|
||||
#endif
|
143
include/ctrff/smdh.hpp
Normal file
143
include/ctrff/smdh.hpp
Normal file
@ -0,0 +1,143 @@
|
||||
#pragma once
|
||||
|
||||
#include <ctrff/binutil.hpp>
|
||||
#include <ctrff/helper.hpp>
|
||||
#include <ctrff/pd_p_api.hpp>
|
||||
#include <pd.hpp>
|
||||
|
||||
// Basic Info
|
||||
// language_slots: 16
|
||||
// valid_language_slots: 12
|
||||
// rating_slots: 16
|
||||
// small_icon: 24
|
||||
// large_icon = 48
|
||||
|
||||
namespace ctrff {
|
||||
// SMDH Size (Note that this needs to be declared here as
|
||||
// a sizeof(SMDH) will not return the expected size due to
|
||||
// use of Serializable)
|
||||
constexpr PD::u32 SMDH_Size = 0x36C0;
|
||||
struct CTRFF_API SMDH {
|
||||
SMDH() {
|
||||
std::fill_n(Magic, PD::ArraySize(Magic), 0);
|
||||
std::fill_n(IconSmall, PD::ArraySize(IconSmall), 0);
|
||||
std::fill_n(IconLarge, PD::ArraySize(IconLarge), 0);
|
||||
}
|
||||
~SMDH() = default;
|
||||
static SMDH Default();
|
||||
PD_SMART_CTOR(SMDH);
|
||||
|
||||
enum Language {
|
||||
Language_Japanese,
|
||||
Language_English,
|
||||
Language_French,
|
||||
Language_German,
|
||||
Language_Italian,
|
||||
Language_Spanish,
|
||||
Language_Chinese_Simplified,
|
||||
Language_Korean,
|
||||
Language_Dutch,
|
||||
Language_Portuguese,
|
||||
Language_Russian,
|
||||
Language_Chinese_Traditional,
|
||||
// To Overrite Aall Languages
|
||||
// returns japanese on get funcs
|
||||
Language_All = 0x47,
|
||||
};
|
||||
enum Rating {
|
||||
Rating_CERO = 0,
|
||||
Rating_ESRB = 1,
|
||||
Rating_USK = 3,
|
||||
Rating_PEGI_GEN = 4,
|
||||
Rating_PEGI_PTR = 6,
|
||||
Rating_PEGI_BBFC = 7,
|
||||
Rating_COB = 8,
|
||||
Rating_GRB = 9,
|
||||
Rating_CGSRR = 10,
|
||||
};
|
||||
enum Region {
|
||||
Region_JAPAN = 1 << 0,
|
||||
Region_NORTH_AMERICA = 1 << 1,
|
||||
Region_EUROPE = 1 << 2,
|
||||
Region_AUSTRALIA = 1 << 3,
|
||||
Region_CHINA = 1 << 4,
|
||||
Region_KOREA = 1 << 5,
|
||||
Region_TAIWAN = 1 << 6,
|
||||
// Not a bitmask, but a value.
|
||||
Region_FREE = 0x7FFFFFFF,
|
||||
};
|
||||
|
||||
enum Flag {
|
||||
Flag_VISIBLE = 1 << 0,
|
||||
Flag_AUTO_BOOT = 1 << 1,
|
||||
Flag_ALLOW_3D = 1 << 2,
|
||||
Flag_REQUIRE_EULA = 1 << 3,
|
||||
Flag_AUTO_SAVE_ON_EXIT = 1 << 4,
|
||||
Flag_USE_EXTENDED_BANNER = 1 << 5,
|
||||
Flag_RATING_REQUIED = 1 << 6,
|
||||
Flag_USE_SAVE_DATA = 1 << 7,
|
||||
Flag_RECORD_USAGE = 1 << 8,
|
||||
Flag_DISABLE_SAVE_BACKUPS = 1 << 10,
|
||||
Flag_NEW_3DS = 1 << 12,
|
||||
Flag_DEFAULT = Flag_VISIBLE | Flag_ALLOW_3D | Flag_RECORD_USAGE,
|
||||
};
|
||||
|
||||
void Load(const std::string &path) {
|
||||
std::fstream f(path, std::ios::in | std::ios::binary);
|
||||
Read(f);
|
||||
f.close();
|
||||
}
|
||||
|
||||
void Save(const std::string &path) {
|
||||
std::fstream f(path, std::ios::out | std::ios::binary);
|
||||
Write(f);
|
||||
f.close();
|
||||
}
|
||||
|
||||
void Write(std::fstream &f) const;
|
||||
void Read(std::fstream &f);
|
||||
|
||||
void SetIcon(const std::vector<PD::u8> &buf);
|
||||
std::vector<PD::u8> GetIcon();
|
||||
void SetShortTitle(const std::string &t, Language l = Language_All);
|
||||
void SetLongTitle(const std::string &t, Language l = Language_All);
|
||||
void SetAuthor(const std::string &t, Language l = Language_All);
|
||||
std::string GetShortTitle(Language l = Language_All);
|
||||
std::string GetLongTitle(Language l = Language_All);
|
||||
std::string GetAuthor(Language l = Language_All);
|
||||
|
||||
struct CTRFF_API Title {
|
||||
Title() {
|
||||
std::fill_n(ShortTitle, PD::ArraySize(ShortTitle), 0);
|
||||
std::fill_n(LongTitle, PD::ArraySize(LongTitle), 0);
|
||||
std::fill_n(Author, PD::ArraySize(Author), 0);
|
||||
};
|
||||
|
||||
PD::u16 ShortTitle[0x40];
|
||||
PD::u16 LongTitle[0x80];
|
||||
PD::u16 Author[0x40];
|
||||
};
|
||||
|
||||
struct CTRFF_API Settings {
|
||||
Settings() { std::fill_n(Ratings, PD::ArraySize(Ratings), 0); };
|
||||
PD::u8 Ratings[16];
|
||||
PD::u32 RegionLock = 0;
|
||||
PD::u32 MatchmakerID = 0;
|
||||
PD::u64 MatchmakerBitID = 0;
|
||||
PD::u32 Flags = 0;
|
||||
PD::u16 EulaVersion = 0;
|
||||
PD::u16 Reserved = 0;
|
||||
PD::u32 OptimalBannerFrame = 0;
|
||||
PD::u32 StreetpassID = 0;
|
||||
};
|
||||
|
||||
char Magic[4];
|
||||
PD::u16 Version = 0;
|
||||
PD::u16 Reserved = 0;
|
||||
Title Titles[16];
|
||||
Settings Settings;
|
||||
PD::u64 Reserved1 = 0;
|
||||
PD::u16 IconSmall[0x240]; // 24x24
|
||||
PD::u16 IconLarge[0x900]; // 48x48
|
||||
};
|
||||
} // namespace ctrff
|
Reference in New Issue
Block a user