Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Custom Music Support, with new way of shuffling music by recreating the sound archive #641

Merged
merged 3 commits into from
Feb 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ CFLAGS := -g -Wall -O2 -mword-relocations \

CFLAGS += $(INCLUDE) -D__3DS__

CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -fno-var-tracking-assignments -std=gnu++17 -Wreorder
CXXFLAGS := $(CFLAGS) -fno-exceptions -fno-var-tracking-assignments -std=gnu++17 -Wreorder

ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
Expand Down
7 changes: 7 additions & 0 deletions code/src/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,13 @@ typedef enum {
STARTINGBGS_BIGGORON_SWORD,
} StartingBiggoronSwordSetting;

typedef enum {
SHUFFLEMUSIC_OFF,
SHUFFLEMUSIC_MIXED,
SHUFFLEMUSIC_GROUPED,
SHUFFLEMUSIC_OWN,
} ShuffleMusicSetting;

typedef enum {
SHUFFLESFX_OFF,
SHUFFLESFX_ALL,
Expand Down
154 changes: 154 additions & 0 deletions source/custom_music/common_structures.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
#pragma once

#include <3ds.h>

// Code ported from Gota7's Citric Composer

class ReferenceTypes {
public:
// Base types.
static const u16 Tables = 0x100;
static const u16 Parameters = 0x200;
static const u16 Codecs = 0x300;
static const u16 General = 0x1F00;

static const u16 SAR_Blocks = 0x2000;
static const u16 SAR_InfoSections = 0x2100;
static const u16 SAR_ItemInfos = 0x2200;
static const u16 SAR_Parameters = 0x2300;
static const u16 SAR_General = 0x2400;

static const u16 STRM_Blocks = 0x4000;
static const u16 STRM_ItemInfos = 0x4100;

static const u16 WSF_Blocks = 0x4800;
static const u16 WSF_ItemInfos = 0x4900;

static const u16 SEQ_Blocks = 0x5000;
static const u16 SEQ_ItemInfos = 0x5100;

static const u16 BNK_Blocks = 0x5800;
static const u16 BNK_Items = 0x5900;
static const u16 BNK_ItemTables = 0x6000;

static const u16 WAR_Blocks = 0x6800;

static const u16 WAV_Blocks = 0x7000;
static const u16 WAV_ItemInfos = 0x7100;

static const u16 GRP_Blocks = 0x7800;
static const u16 GRP_ItemInfos = 0x7900;

static const u16 ASF_Blocks = 0x8000;
static const u16 ASF_Items = 0x8100;

// Common sound.
static const u16 Table_Embedding = Tables;
static const u16 Table_Reference = Tables + 1;
static const u16 Table_ReferenceWithSize = Tables + 2;

static const u16 Param_Sound3D = Parameters;
static const u16 Param_Sends = Parameters + 1;
static const u16 Param_Envelope = Parameters + 2;
static const u16 Param_AdshrEnvelop = Parameters + 3;

static const u16 Codec_DspAdpcmInfo = Codecs;
static const u16 Codec_ImaAdpcmInfo = Codecs + 1;

static const u16 General_ByteStream = General;
static const u16 String = General + 1;

// Sound archive file.
static const u16 SAR_Block_String = SAR_Blocks;
static const u16 SAR_Block_Info = SAR_Blocks + 1;
static const u16 SAR_Block_File = SAR_Blocks + 2;

static const u16 SAR_Section_SoundInfo = SAR_InfoSections;
static const u16 SAR_Section_BankInfo = SAR_InfoSections + 1;
static const u16 SAR_Section_PlayerInfo = SAR_InfoSections + 2;
static const u16 SAR_Section_WaveArchiveInfo = SAR_InfoSections + 3;
static const u16 SAR_Section_SoundGroupInfo = SAR_InfoSections + 4;
static const u16 SAR_Section_GroupInfo = SAR_InfoSections + 5;
static const u16 SAR_Section_FileInfo = SAR_InfoSections + 6;

static const u16 SAR_Info_Sound = SAR_ItemInfos;
static const u16 SAR_Info_StreamSound = SAR_ItemInfos + 1;
static const u16 SAR_Info_WaveSound = SAR_ItemInfos + 2;
static const u16 SAR_Info_SequenceSound = SAR_ItemInfos + 3;
static const u16 SAR_Info_SoundGroup = SAR_ItemInfos + 4;
static const u16 SAR_Info_WaveSoundGroup = SAR_ItemInfos + 5;
static const u16 SAR_Info_Bank = SAR_ItemInfos + 6;
static const u16 SAR_Info_WaveArchive = SAR_ItemInfos + 7;
static const u16 SAR_Info_Group = SAR_ItemInfos + 8;
static const u16 SAR_Info_Player = SAR_ItemInfos + 9;
static const u16 SAR_Info_File = SAR_ItemInfos + 10;
static const u16 SAR_Info_Project = SAR_ItemInfos + 11;
static const u16 SAR_Info_InternalFile = SAR_ItemInfos + 12;
static const u16 SAR_Info_ExternalFile = SAR_ItemInfos + 13;
static const u16 SAR_Info_StreamSoundTrack = SAR_ItemInfos + 14;
static const u16 SAR_Info_Send = SAR_ItemInfos + 15;
static const u16 SAR_Info_StreamSoundExtension = SAR_ItemInfos + 16;

static const u16 SAR_StringTable = SAR_General;
static const u16 SAR_PatriciaTree = SAR_General + 1;

// Stream file.
static const u16 STRM_Block_Info = STRM_Blocks;
static const u16 STRM_Block_Seek = STRM_Blocks + 1;
static const u16 STRM_Block_Data = STRM_Blocks + 2;
static const u16 STRM_Block_Region = STRM_Blocks + 3;
static const u16 STRM_Block_PrefetchData = STRM_Blocks + 4;

static const u16 STRM_Info_StreamSound = STRM_ItemInfos;
static const u16 STRM_Info_Track = STRM_ItemInfos + 1;
static const u16 STRM_Info_Channel = STRM_ItemInfos + 2;

// Wave sound file.
static const u16 WSF_Block_Info = WSF_Blocks;

static const u16 WSF_WaveSoundMetaData = WSF_ItemInfos;
static const u16 WSF_WaveSoundInfo = WSF_ItemInfos + 1;
static const u16 WSF_NoteInfo = WSF_ItemInfos + 2;
static const u16 WSF_TrackInfo = WSF_ItemInfos + 3;
static const u16 WSF_NoteEvent = WSF_ItemInfos + 4;

// Wave archive file.
static const u16 WAR_Block_Info = WAR_Blocks;
static const u16 WAR_Block_File = WAR_Blocks + 1;

// Wave file.
static const u16 WAV_Block_Info = WAV_Blocks;
static const u16 WAV_Block_Data = WAV_Blocks + 1;

static const u16 WAV_ChannelInfo = WAV_ItemInfos;

// Sequence file.
static const u16 SEQ_Block_Data = SEQ_Blocks;
static const u16 SEQ_Block_Label = SEQ_Blocks + 1;

static const u16 SEQ_LabelInfo = SEQ_ItemInfos;

// Bank file.
static const u16 BNK_Block_Info = BNK_Blocks;

static const u16 BNK_Info_Instrument = BNK_Items;
static const u16 BNK_Info_KeyRegion = BNK_Items + 1;
static const u16 BNK_Info_VelocityRegion = BNK_Items + 2;
static const u16 BNK_Info_Null = BNK_Items + 3;

static const u16 BNK_RefTable_Direct = BNK_ItemTables;
static const u16 BNK_RefTable_Index = BNK_ItemTables + 1;
static const u16 BNK_RefTable_Range = BNK_ItemTables + 2;

// Group file.
static const u16 GRP_Block_Info = GRP_Blocks;
static const u16 GRP_Block_File = GRP_Blocks + 1;
static const u16 GRP_Block_Infx = GRP_Blocks + 2;

static const u16 GRP_Info_Item = GRP_ItemInfos;
static const u16 GRP_Infx_Item = GRP_ItemInfos + 1;

// Animation sound file.
static const u16 ASF_Block_Data = ASF_Blocks;
static const u16 ASF_EventInfo = ASF_Items;
};
151 changes: 151 additions & 0 deletions source/custom_music/ctr_binary_data.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#include "ctr_binary_data.hpp"

// Handler

BinaryDataHandler::BinaryDataHandler() {
}

BinaryDataHandler::~BinaryDataHandler() = default;

void BinaryDataHandler::Close() {
FSFILE_Close(fsHandle);
}

bool BinaryDataHandler::SuccessfullyInitialized() {
return init;
}

// Reader

BinaryDataReader::BinaryDataReader(FS_Archive archive_, std::string filePath_) {
if (!R_SUCCEEDED(FSUSER_OpenFile(&fsHandle, archive_, fsMakePath(PATH_ASCII, filePath_.c_str()), FS_OPEN_READ,
FS_ATTRIBUTE_ARCHIVE))) {
return;
}
FSFILE_GetSize(fsHandle, &fileSize);
init = true;
}

BinaryDataReader::~BinaryDataReader() = default;

u64 BinaryDataReader::GetFileSize() {
return fileSize;
}

u8 BinaryDataReader::ReadByte() {
u32 bytesRead = 0;
u8 value = 0;

FSFILE_Read(fsHandle, &bytesRead, position, &value, sizeof(u8));
BinaryDataReader::position += sizeof(u8);

return value;
}

std::vector<char> BinaryDataReader::ReadChars(u32 count) {
u32 bytesRead = 0;
std::vector<char> chars(count, 0);

FSFILE_Read(fsHandle, &bytesRead, position, &chars[0], count);
position += bytesRead;

return chars;
}

std::vector<u8> BinaryDataReader::ReadBytes(u32 count) {
u32 bytesRead = 0;
std::vector<u8> bytes(count, 0);

FSFILE_Read(fsHandle, &bytesRead, position, &bytes[0], count);
position += bytesRead;

return bytes;
}

s16 BinaryDataReader::ReadS16() {
u32 bytesRead = 0;
s16 value = 0;

FSFILE_Read(fsHandle, &bytesRead, position, &value, sizeof(s16));
BinaryDataReader::position += sizeof(s16);

return value;
}

u16 BinaryDataReader::ReadU16() {
return (u16)ReadS16();
}

s32 BinaryDataReader::ReadS32() {
u32 bytesRead = 0;
u32 value = 0;

FSFILE_Read(fsHandle, &bytesRead, position, &value, sizeof(s32));
BinaryDataReader::position += sizeof(s32);

return value;
}

u32 BinaryDataReader::ReadU32() {
return (u32)ReadS32();
}

std::vector<u8> BinaryDataReader::ReadAll() {
position = 0;
FSFILE_GetSize(fsHandle, &fileSize);
return ReadBytes(fileSize);
}

// Writer

BinaryDataWriter::BinaryDataWriter(FS_Archive archive_, std::string filePath_) {
if (!R_SUCCEEDED(FSUSER_OpenFile(&fsHandle, archive_, fsMakePath(PATH_ASCII, filePath_.c_str()),
FS_OPEN_WRITE | FS_OPEN_CREATE, FS_ATTRIBUTE_ARCHIVE))) {
return;
}
init = true;
}

BinaryDataWriter::~BinaryDataWriter() = default;

void BinaryDataWriter::Write(char buf) {
Write((u8)buf);
}

void BinaryDataWriter::Write(u8 buf) {
u32 bytesWritten = 0;
FSFILE_Write(fsHandle, &bytesWritten, position, &buf, sizeof(buf), FS_WRITE_UPDATE_TIME);
position += bytesWritten;
}

void BinaryDataWriter::Write(std::vector<char> buf) {
u32 bytesWritten = 0;
FSFILE_Write(fsHandle, &bytesWritten, position, &buf[0], buf.size(), FS_WRITE_UPDATE_TIME);
position += bytesWritten;
}

void BinaryDataWriter::Write(std::vector<u8> buf) {
u32 bytesWritten = 0;
FSFILE_Write(fsHandle, &bytesWritten, position, &buf[0], buf.size(), FS_WRITE_UPDATE_TIME);
position += bytesWritten;
}

void BinaryDataWriter::Write(s16 buf) {
u32 bytesWritten = 0;
FSFILE_Write(fsHandle, &bytesWritten, position, &buf, sizeof(buf), FS_WRITE_UPDATE_TIME);
position += bytesWritten;
}

void BinaryDataWriter::Write(u16 buf) {
Write((s16)buf);
}

void BinaryDataWriter::Write(s32 buf) {
u32 bytesWritten = 0;
FSFILE_Write(fsHandle, &bytesWritten, position, &buf, sizeof(buf), FS_WRITE_UPDATE_TIME);
position += bytesWritten;
}

void BinaryDataWriter::Write(u32 buf) {
Write((s32)buf);
}
59 changes: 59 additions & 0 deletions source/custom_music/ctr_binary_data.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#pragma once

#include <3ds.h>
#include <string>
#include <vector>

class BinaryDataHandler {
public:
void Close();
bool SuccessfullyInitialized();

u32 position = 0;

protected:
BinaryDataHandler();
~BinaryDataHandler();

bool init = false;

Handle fsHandle = 0;
};

class BinaryDataReader : public BinaryDataHandler {
public:
BinaryDataReader(FS_Archive archive_, std::string filePath_);
~BinaryDataReader();

u64 GetFileSize();

u8 ReadByte();
std::vector<char> ReadChars(u32 count);
std::vector<u8> ReadBytes(u32 count);
s16 ReadS16();
u16 ReadU16();
s32 ReadS32();
u32 ReadU32();

std::vector<u8> ReadAll();

private:
u64 fileSize;
};

class BinaryDataWriter : public BinaryDataHandler {
public:
BinaryDataWriter(FS_Archive archive_, std::string filePath_);
~BinaryDataWriter();

void Write(char buf);
void Write(u8 buf);
void Write(std::vector<char> buf);
void Write(std::vector<u8> buf);
void Write(s16 buf);
void Write(u16 buf);
void Write(s32 buf);
void Write(u32 buf);

private:
};
Loading