mirror of
https://github.com/AxioDL/amuse.git
synced 2025-12-08 13:14:58 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
055e73183a | ||
|
|
a048605011 | ||
|
|
260ec5bb93 | ||
|
|
2a2a16fd17 |
@@ -1,7 +1,14 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.0)
|
||||||
project(amuse)
|
project(amuse)
|
||||||
|
|
||||||
if(EXISTS boo)
|
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/boo AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/athena)
|
||||||
|
message(STATUS "Preparing standalone build")
|
||||||
|
if (NOT MSVC)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wno-narrowing")
|
||||||
|
endif()
|
||||||
add_subdirectory(boo)
|
add_subdirectory(boo)
|
||||||
|
add_subdirectory(athena)
|
||||||
|
include_directories(athena/include)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
|
|||||||
@@ -76,8 +76,8 @@ class AudioGroupProject
|
|||||||
std::unique_ptr<SongGroupIndex::PageEntry[]> m_convNormalPages;
|
std::unique_ptr<SongGroupIndex::PageEntry[]> m_convNormalPages;
|
||||||
std::unique_ptr<SongGroupIndex::PageEntry[]> m_convDrumPages;
|
std::unique_ptr<SongGroupIndex::PageEntry[]> m_convDrumPages;
|
||||||
std::unique_ptr<std::array<SongGroupIndex::MIDISetup, 16>[]> m_convMidiSetups;
|
std::unique_ptr<std::array<SongGroupIndex::MIDISetup, 16>[]> m_convMidiSetups;
|
||||||
void _allocateConvBuffers(const unsigned char* data, bool absOffs, N64DataTag);
|
void _allocateConvBuffers(const unsigned char* data, N64DataTag);
|
||||||
void _allocateConvBuffers(const unsigned char* data, bool absOffs, PCDataTag);
|
void _allocateConvBuffers(const unsigned char* data, PCDataTag);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AudioGroupProject(const unsigned char* data, GCNDataTag);
|
AudioGroupProject(const unsigned char* data, GCNDataTag);
|
||||||
|
|||||||
@@ -21,8 +21,7 @@ public:
|
|||||||
MetroidPrime2,
|
MetroidPrime2,
|
||||||
RogueSquadronPC,
|
RogueSquadronPC,
|
||||||
RogueSquadronN64,
|
RogueSquadronN64,
|
||||||
BattleForNabooPC,
|
Factor5N64Rev,
|
||||||
BattleForNabooN64,
|
|
||||||
RogueSquadron2,
|
RogueSquadron2,
|
||||||
RogueSquadron3
|
RogueSquadron3
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
State m_phase = State::Attack; /**< Current envelope state */
|
State m_phase = State::Attack; /**< Current envelope state */
|
||||||
double m_attackTime = 0.0; /**< Time of attack in seconds */
|
double m_attackTime = 0.01; /**< Time of attack in seconds */
|
||||||
double m_decayTime = 0.0; /**< Time of decay in seconds */
|
double m_decayTime = 0.0; /**< Time of decay in seconds */
|
||||||
double m_sustainFactor = 1.0; /**< Evaluated sustain percentage */
|
double m_sustainFactor = 1.0; /**< Evaluated sustain percentage */
|
||||||
double m_releaseTime = 0.0; /**< Time of release in seconds */
|
double m_releaseTime = 0.01; /**< Time of release in seconds */
|
||||||
double m_releaseStartFactor = 0.0; /**< Level at whenever release event occurs */
|
double m_releaseStartFactor = 0.0; /**< Level at whenever release event occurs */
|
||||||
double m_curTime = 0.0; /**< Current time of envelope stage in seconds */
|
double m_curTime = 0.0; /**< Current time of envelope stage in seconds */
|
||||||
bool m_adsrSet = false;
|
bool m_adsrSet = false;
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ struct MusyX1MIDISetup
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool absOffs, N64DataTag)
|
void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, N64DataTag)
|
||||||
{
|
{
|
||||||
size_t normPageCount = 0;
|
size_t normPageCount = 0;
|
||||||
size_t drumPageCount = 0;
|
size_t drumPageCount = 0;
|
||||||
@@ -161,7 +161,7 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool abs
|
|||||||
const GroupHeader* group = reinterpret_cast<const GroupHeader*>(data);
|
const GroupHeader* group = reinterpret_cast<const GroupHeader*>(data);
|
||||||
while (group->groupEndOff != 0xffffffff)
|
while (group->groupEndOff != 0xffffffff)
|
||||||
{
|
{
|
||||||
const unsigned char* subData = absOffs ? data : data + 8;
|
const unsigned char* subData = data + 8;
|
||||||
GroupHeader header = *group;
|
GroupHeader header = *group;
|
||||||
header.swapBig();
|
header.swapBig();
|
||||||
|
|
||||||
@@ -187,21 +187,17 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool abs
|
|||||||
|
|
||||||
/* MIDI setups */
|
/* MIDI setups */
|
||||||
const uint8_t* setupData = subData + header.midiSetupsOff;
|
const uint8_t* setupData = subData + header.midiSetupsOff;
|
||||||
while (*reinterpret_cast<const uint32_t*>(setupData) != 0xffffffff)
|
const uint8_t* setupEnd = subData + header.groupEndOff;
|
||||||
|
while (setupData < setupEnd)
|
||||||
{
|
{
|
||||||
++midiSetupCount;
|
++midiSetupCount;
|
||||||
setupData += 8 * 16 + 4;
|
setupData += 8 * 16 + 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (absOffs)
|
|
||||||
group = reinterpret_cast<const GroupHeader*>(data + header.groupEndOff);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
data += header.groupEndOff;
|
data += header.groupEndOff;
|
||||||
group = reinterpret_cast<const GroupHeader*>(data);
|
group = reinterpret_cast<const GroupHeader*>(data);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (normPageCount)
|
if (normPageCount)
|
||||||
m_convNormalPages.reset(new SongGroupIndex::PageEntry[normPageCount]);
|
m_convNormalPages.reset(new SongGroupIndex::PageEntry[normPageCount]);
|
||||||
@@ -213,7 +209,8 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool abs
|
|||||||
|
|
||||||
AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, N64DataTag)
|
AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, N64DataTag)
|
||||||
{
|
{
|
||||||
_allocateConvBuffers(data, absOffs, N64DataTag{});
|
if (!absOffs)
|
||||||
|
_allocateConvBuffers(data, N64DataTag{});
|
||||||
SongGroupIndex::PageEntry* normPagesBuf = m_convNormalPages.get();
|
SongGroupIndex::PageEntry* normPagesBuf = m_convNormalPages.get();
|
||||||
SongGroupIndex::PageEntry* drumPagesBuf = m_convDrumPages.get();
|
SongGroupIndex::PageEntry* drumPagesBuf = m_convDrumPages.get();
|
||||||
std::array<SongGroupIndex::MIDISetup, 16>* midiSetupsBuf = m_convMidiSetups.get();
|
std::array<SongGroupIndex::MIDISetup, 16>* midiSetupsBuf = m_convMidiSetups.get();
|
||||||
@@ -232,6 +229,39 @@ AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, N6
|
|||||||
SongGroupIndex& idx = m_songGroups[header.groupId];
|
SongGroupIndex& idx = m_songGroups[header.groupId];
|
||||||
bIdx = &idx;
|
bIdx = &idx;
|
||||||
|
|
||||||
|
if (absOffs)
|
||||||
|
{
|
||||||
|
/* Normal pages */
|
||||||
|
const SongGroupIndex::PageEntry* normEntries =
|
||||||
|
reinterpret_cast<const SongGroupIndex::PageEntry*>(data + header.pageTableOff);
|
||||||
|
while (normEntries->objId != 0xffff)
|
||||||
|
{
|
||||||
|
idx.m_normPages[normEntries->programNo] = normEntries;
|
||||||
|
++normEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Drum pages */
|
||||||
|
const SongGroupIndex::PageEntry* drumEntries =
|
||||||
|
reinterpret_cast<const SongGroupIndex::PageEntry*>(data + header.drumTableOff);
|
||||||
|
while (drumEntries->objId != 0xffff)
|
||||||
|
{
|
||||||
|
idx.m_drumPages[drumEntries->programNo] = drumEntries;
|
||||||
|
++drumEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MIDI setups */
|
||||||
|
const uint8_t* setupData = data + header.midiSetupsOff;
|
||||||
|
const uint8_t* setupEnd = data + header.groupEndOff;
|
||||||
|
while (setupData < setupEnd)
|
||||||
|
{
|
||||||
|
uint16_t songId = SBig(*reinterpret_cast<const uint16_t*>(setupData));
|
||||||
|
idx.m_midiSetups[songId] =
|
||||||
|
reinterpret_cast<const std::array<SongGroupIndex::MIDISetup, 16>*>(setupData + 4);
|
||||||
|
setupData += 5 * 16 + 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Normal pages */
|
/* Normal pages */
|
||||||
const MusyX1PageEntry* normEntries =
|
const MusyX1PageEntry* normEntries =
|
||||||
reinterpret_cast<const MusyX1PageEntry*>(subData + header.pageTableOff);
|
reinterpret_cast<const MusyX1PageEntry*>(subData + header.pageTableOff);
|
||||||
@@ -256,7 +286,8 @@ AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, N6
|
|||||||
|
|
||||||
/* MIDI setups */
|
/* MIDI setups */
|
||||||
const uint8_t* setupData = subData + header.midiSetupsOff;
|
const uint8_t* setupData = subData + header.midiSetupsOff;
|
||||||
while (*reinterpret_cast<const uint32_t*>(setupData) != 0xffffffff)
|
const uint8_t* setupEnd = subData + header.groupEndOff;
|
||||||
|
while (setupData < setupEnd)
|
||||||
{
|
{
|
||||||
uint16_t songId = SBig(*reinterpret_cast<const uint16_t*>(setupData));
|
uint16_t songId = SBig(*reinterpret_cast<const uint16_t*>(setupData));
|
||||||
const std::array<MusyX1MIDISetup, 16>* midiSetups =
|
const std::array<MusyX1MIDISetup, 16>* midiSetups =
|
||||||
@@ -270,6 +301,7 @@ AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, N6
|
|||||||
++midiSetupsBuf;
|
++midiSetupsBuf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (header.type == GroupType::SFX)
|
else if (header.type == GroupType::SFX)
|
||||||
{
|
{
|
||||||
SFXGroupIndex& idx = m_sfxGroups[header.groupId];
|
SFXGroupIndex& idx = m_sfxGroups[header.groupId];
|
||||||
@@ -304,7 +336,7 @@ AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, N6
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool absOffs, PCDataTag)
|
void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, PCDataTag)
|
||||||
{
|
{
|
||||||
size_t normPageCount = 0;
|
size_t normPageCount = 0;
|
||||||
size_t drumPageCount = 0;
|
size_t drumPageCount = 0;
|
||||||
@@ -313,7 +345,7 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool abs
|
|||||||
const GroupHeader* group = reinterpret_cast<const GroupHeader*>(data);
|
const GroupHeader* group = reinterpret_cast<const GroupHeader*>(data);
|
||||||
while (group->groupEndOff != 0xffffffff)
|
while (group->groupEndOff != 0xffffffff)
|
||||||
{
|
{
|
||||||
const unsigned char* subData = absOffs ? data : data + 8;
|
const unsigned char* subData = data + 8;
|
||||||
|
|
||||||
if (group->type == GroupType::Song)
|
if (group->type == GroupType::Song)
|
||||||
{
|
{
|
||||||
@@ -337,21 +369,17 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool abs
|
|||||||
|
|
||||||
/* MIDI setups */
|
/* MIDI setups */
|
||||||
const uint8_t* setupData = subData + group->midiSetupsOff;
|
const uint8_t* setupData = subData + group->midiSetupsOff;
|
||||||
while (*reinterpret_cast<const uint32_t*>(setupData) != 0xffffffff)
|
const uint8_t* setupEnd = subData + group->groupEndOff;
|
||||||
|
while (setupData < setupEnd)
|
||||||
{
|
{
|
||||||
++midiSetupCount;
|
++midiSetupCount;
|
||||||
setupData += 8 * 16 + 4;
|
setupData += 8 * 16 + 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (absOffs)
|
|
||||||
group = reinterpret_cast<const GroupHeader*>(data + group->groupEndOff);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
data += group->groupEndOff;
|
data += group->groupEndOff;
|
||||||
group = reinterpret_cast<const GroupHeader*>(data);
|
group = reinterpret_cast<const GroupHeader*>(data);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (normPageCount)
|
if (normPageCount)
|
||||||
m_convNormalPages.reset(new SongGroupIndex::PageEntry[normPageCount]);
|
m_convNormalPages.reset(new SongGroupIndex::PageEntry[normPageCount]);
|
||||||
@@ -363,7 +391,8 @@ void AudioGroupProject::_allocateConvBuffers(const unsigned char* data, bool abs
|
|||||||
|
|
||||||
AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, PCDataTag)
|
AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, PCDataTag)
|
||||||
{
|
{
|
||||||
_allocateConvBuffers(data, absOffs, PCDataTag{});
|
if (!absOffs)
|
||||||
|
_allocateConvBuffers(data, PCDataTag{});
|
||||||
SongGroupIndex::PageEntry* normPagesBuf = m_convNormalPages.get();
|
SongGroupIndex::PageEntry* normPagesBuf = m_convNormalPages.get();
|
||||||
SongGroupIndex::PageEntry* drumPagesBuf = m_convDrumPages.get();
|
SongGroupIndex::PageEntry* drumPagesBuf = m_convDrumPages.get();
|
||||||
std::array<SongGroupIndex::MIDISetup, 16>* midiSetupsBuf = m_convMidiSetups.get();
|
std::array<SongGroupIndex::MIDISetup, 16>* midiSetupsBuf = m_convMidiSetups.get();
|
||||||
@@ -380,6 +409,39 @@ AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, PC
|
|||||||
SongGroupIndex& idx = m_songGroups[group->groupId];
|
SongGroupIndex& idx = m_songGroups[group->groupId];
|
||||||
bIdx = &idx;
|
bIdx = &idx;
|
||||||
|
|
||||||
|
if (absOffs)
|
||||||
|
{
|
||||||
|
/* Normal pages */
|
||||||
|
const SongGroupIndex::PageEntry* normEntries =
|
||||||
|
reinterpret_cast<const SongGroupIndex::PageEntry*>(data + group->pageTableOff);
|
||||||
|
while (normEntries->objId != 0xffff)
|
||||||
|
{
|
||||||
|
idx.m_normPages[normEntries->programNo] = normEntries;
|
||||||
|
++normEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Drum pages */
|
||||||
|
const SongGroupIndex::PageEntry* drumEntries =
|
||||||
|
reinterpret_cast<const SongGroupIndex::PageEntry*>(data + group->drumTableOff);
|
||||||
|
while (drumEntries->objId != 0xffff)
|
||||||
|
{
|
||||||
|
idx.m_drumPages[drumEntries->programNo] = drumEntries;
|
||||||
|
++drumEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MIDI setups */
|
||||||
|
const uint8_t* setupData = data + group->midiSetupsOff;
|
||||||
|
const uint8_t* setupEnd = data + group->groupEndOff;
|
||||||
|
while (setupData < setupEnd)
|
||||||
|
{
|
||||||
|
uint16_t songId = *reinterpret_cast<const uint16_t*>(setupData);
|
||||||
|
idx.m_midiSetups[songId] =
|
||||||
|
reinterpret_cast<const std::array<SongGroupIndex::MIDISetup, 16>*>(setupData + 4);
|
||||||
|
setupData += 5 * 16 + 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Normal pages */
|
/* Normal pages */
|
||||||
const MusyX1PageEntry* normEntries =
|
const MusyX1PageEntry* normEntries =
|
||||||
reinterpret_cast<const MusyX1PageEntry*>(subData + group->pageTableOff);
|
reinterpret_cast<const MusyX1PageEntry*>(subData + group->pageTableOff);
|
||||||
@@ -404,7 +466,8 @@ AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, PC
|
|||||||
|
|
||||||
/* MIDI setups */
|
/* MIDI setups */
|
||||||
const uint8_t* setupData = subData + group->midiSetupsOff;
|
const uint8_t* setupData = subData + group->midiSetupsOff;
|
||||||
while (*reinterpret_cast<const uint32_t*>(setupData) != 0xffffffff)
|
const uint8_t* setupEnd = subData + group->groupEndOff;
|
||||||
|
while (setupData < setupEnd)
|
||||||
{
|
{
|
||||||
uint16_t songId = *reinterpret_cast<const uint16_t*>(setupData);
|
uint16_t songId = *reinterpret_cast<const uint16_t*>(setupData);
|
||||||
const std::array<MusyX1MIDISetup, 16>* midiSetups =
|
const std::array<MusyX1MIDISetup, 16>* midiSetups =
|
||||||
@@ -418,6 +481,7 @@ AudioGroupProject::AudioGroupProject(const unsigned char* data, bool absOffs, PC
|
|||||||
++midiSetupsBuf;
|
++midiSetupsBuf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (group->type == GroupType::SFX)
|
else if (group->type == GroupType::SFX)
|
||||||
{
|
{
|
||||||
SFXGroupIndex& idx = m_sfxGroups[group->groupId];
|
SFXGroupIndex& idx = m_sfxGroups[group->groupId];
|
||||||
|
|||||||
@@ -69,10 +69,8 @@ const SystemChar* ContainerRegistry::TypeToName(Type tp)
|
|||||||
return _S("Star Wars - Rogue Squadron (PC)");
|
return _S("Star Wars - Rogue Squadron (PC)");
|
||||||
case Type::RogueSquadronN64:
|
case Type::RogueSquadronN64:
|
||||||
return _S("Star Wars - Rogue Squadron (N64)");
|
return _S("Star Wars - Rogue Squadron (N64)");
|
||||||
case Type::BattleForNabooPC:
|
case Type::Factor5N64Rev:
|
||||||
return _S("Star Wars Episode I - Battle for Naboo (PC)");
|
return _S("Factor5 Revision ROM (N64)");
|
||||||
case Type::BattleForNabooN64:
|
|
||||||
return _S("Star Wars Episode I - Battle for Naboo (N64)");
|
|
||||||
case Type::RogueSquadron2:
|
case Type::RogueSquadron2:
|
||||||
return _S("Star Wars - Rogue Squadron 2 (GCN)");
|
return _S("Star Wars - Rogue Squadron 2 (GCN)");
|
||||||
case Type::RogueSquadron3:
|
case Type::RogueSquadron3:
|
||||||
@@ -610,7 +608,7 @@ static void SwapN64Rom32(void* data, size_t size)
|
|||||||
words[i] = SBig(words[i]);
|
words[i] = SBig(words[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RS1SongMapping
|
static const struct RS1SongMapping
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
int songId;
|
int songId;
|
||||||
@@ -714,7 +712,7 @@ struct RS1SongMapping
|
|||||||
|
|
||||||
static int LookupRS1SongId(const char* name)
|
static int LookupRS1SongId(const char* name)
|
||||||
{
|
{
|
||||||
RS1SongMapping* map = RS1Mappings;
|
const RS1SongMapping* map = RS1Mappings;
|
||||||
while (map->name)
|
while (map->name)
|
||||||
{
|
{
|
||||||
if (!strcmp(name, map->name))
|
if (!strcmp(name, map->name))
|
||||||
@@ -1087,148 +1085,7 @@ static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadRS1
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ValidateBFNPC(FILE* fp)
|
static bool ValidateFactor5N64Rev(FILE* fp)
|
||||||
{
|
|
||||||
size_t endPos = FileLength(fp);
|
|
||||||
if (endPos > 100 * 1024 * 1024)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
uint32_t fstOff;
|
|
||||||
uint32_t fstSz;
|
|
||||||
if (fread(&fstOff, 1, 4, fp) == 4 && fread(&fstSz, 1, 4, fp) == 4)
|
|
||||||
{
|
|
||||||
if (fstOff + fstSz <= endPos)
|
|
||||||
{
|
|
||||||
FSeek(fp, fstOff, SEEK_SET);
|
|
||||||
uint32_t elemCount = fstSz / 32;
|
|
||||||
std::unique_ptr<RS1FSTEntry[]> entries(new RS1FSTEntry[elemCount]);
|
|
||||||
fread(entries.get(), fstSz, 1, fp);
|
|
||||||
|
|
||||||
uint8_t foundComps = 0;
|
|
||||||
for (uint32_t i = 0; i < elemCount; ++i)
|
|
||||||
{
|
|
||||||
RS1FSTEntry& entry = entries[i];
|
|
||||||
if (!strncmp("proj", entry.name, 16))
|
|
||||||
foundComps |= 1;
|
|
||||||
else if (!strncmp("pool", entry.name, 16))
|
|
||||||
foundComps |= 2;
|
|
||||||
else if (!strncmp("sdir", entry.name, 16))
|
|
||||||
foundComps |= 4;
|
|
||||||
else if (!strncmp("samp", entry.name, 16))
|
|
||||||
foundComps |= 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (foundComps == 0xf)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadBFNPC(FILE* fp)
|
|
||||||
{
|
|
||||||
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
|
|
||||||
size_t endPos = FileLength(fp);
|
|
||||||
|
|
||||||
uint32_t fstOff;
|
|
||||||
uint32_t fstSz;
|
|
||||||
if (fread(&fstOff, 1, 4, fp) == 4 && fread(&fstSz, 1, 4, fp) == 4)
|
|
||||||
{
|
|
||||||
if (fstOff + fstSz <= endPos)
|
|
||||||
{
|
|
||||||
FSeek(fp, fstOff, SEEK_SET);
|
|
||||||
uint32_t elemCount = fstSz / 32;
|
|
||||||
std::unique_ptr<RS1FSTEntry[]> entries(new RS1FSTEntry[elemCount]);
|
|
||||||
fread(entries.get(), fstSz, 1, fp);
|
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> proj;
|
|
||||||
size_t projSz = 0;
|
|
||||||
std::unique_ptr<uint8_t[]> pool;
|
|
||||||
size_t poolSz = 0;
|
|
||||||
std::unique_ptr<uint8_t[]> sdir;
|
|
||||||
size_t sdirSz = 0;
|
|
||||||
std::unique_ptr<uint8_t[]> samp;
|
|
||||||
size_t sampSz = 0;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < elemCount; ++i)
|
|
||||||
{
|
|
||||||
RS1FSTEntry& entry = entries[i];
|
|
||||||
if (!strncmp("proj", entry.name, 16))
|
|
||||||
{
|
|
||||||
proj.reset(new uint8_t[entry.decompSz]);
|
|
||||||
FSeek(fp, entry.offset, SEEK_SET);
|
|
||||||
fread(proj.get(), 1, entry.decompSz, fp);
|
|
||||||
projSz = entry.decompSz;
|
|
||||||
}
|
|
||||||
else if (!strncmp("pool", entry.name, 16))
|
|
||||||
{
|
|
||||||
pool.reset(new uint8_t[entry.decompSz]);
|
|
||||||
FSeek(fp, entry.offset, SEEK_SET);
|
|
||||||
fread(pool.get(), 1, entry.decompSz, fp);
|
|
||||||
poolSz = entry.decompSz;
|
|
||||||
}
|
|
||||||
else if (!strncmp("sdir", entry.name, 16))
|
|
||||||
{
|
|
||||||
sdir.reset(new uint8_t[entry.decompSz]);
|
|
||||||
FSeek(fp, entry.offset, SEEK_SET);
|
|
||||||
fread(sdir.get(), 1, entry.decompSz, fp);
|
|
||||||
sdirSz = entry.decompSz;
|
|
||||||
}
|
|
||||||
else if (!strncmp("samp", entry.name, 16))
|
|
||||||
{
|
|
||||||
samp.reset(new uint8_t[entry.decompSz]);
|
|
||||||
FSeek(fp, entry.offset, SEEK_SET);
|
|
||||||
fread(samp.get(), 1, entry.decompSz, fp);
|
|
||||||
sampSz = entry.decompSz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.emplace_back(_S("Group"),
|
|
||||||
IntrusiveAudioGroupData{proj.release(), projSz, pool.release(), poolSz, sdir.release(),
|
|
||||||
sdirSz, samp.release(), sampSz, true, PCDataTag{}});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadBFNPCSongs(FILE* fp)
|
|
||||||
{
|
|
||||||
std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ret;
|
|
||||||
size_t endPos = FileLength(fp);
|
|
||||||
|
|
||||||
uint32_t fstOff;
|
|
||||||
uint32_t fstSz;
|
|
||||||
if (fread(&fstOff, 1, 4, fp) == 4 && fread(&fstSz, 1, 4, fp) == 4)
|
|
||||||
{
|
|
||||||
if (fstOff + fstSz <= endPos)
|
|
||||||
{
|
|
||||||
FSeek(fp, fstOff, SEEK_SET);
|
|
||||||
uint32_t elemCount = fstSz / 32;
|
|
||||||
std::unique_ptr<RS1FSTEntry[]> entries(new RS1FSTEntry[elemCount]);
|
|
||||||
fread(entries.get(), fstSz, 1, fp);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < elemCount; ++i)
|
|
||||||
{
|
|
||||||
RS1FSTEntry& entry = entries[i];
|
|
||||||
if (!strncmp(entry.name, "s_", 2))
|
|
||||||
{
|
|
||||||
std::unique_ptr<uint8_t[]> song(new uint8_t[entry.decompSz]);
|
|
||||||
FSeek(fp, entry.offset, SEEK_SET);
|
|
||||||
fread(song.get(), 1, entry.decompSz, fp);
|
|
||||||
|
|
||||||
SystemString name = StrToSys(entry.name);
|
|
||||||
ret.emplace_back(name, ContainerRegistry::SongData(std::move(song), entry.decompSz, -1, -1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ValidateBFNN64(FILE* fp)
|
|
||||||
{
|
{
|
||||||
size_t endPos = FileLength(fp);
|
size_t endPos = FileLength(fp);
|
||||||
if (endPos > 32 * 1024 * 1024)
|
if (endPos > 32 * 1024 * 1024)
|
||||||
@@ -1282,7 +1139,7 @@ static bool ValidateBFNN64(FILE* fp)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadBFNN64(FILE* fp)
|
static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadFactor5N64Rev(FILE* fp)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
|
std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ret;
|
||||||
size_t endPos = FileLength(fp);
|
size_t endPos = FileLength(fp);
|
||||||
@@ -1393,7 +1250,7 @@ static std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> LoadBFNN64(
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadBFNN64Songs(FILE* fp)
|
static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadFactor5N64RevSongs(FILE* fp)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ret;
|
std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ret;
|
||||||
size_t endPos = FileLength(fp);
|
size_t endPos = FileLength(fp);
|
||||||
@@ -1427,6 +1284,8 @@ static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadBFN
|
|||||||
|
|
||||||
if (!strncmp(ent.name, "s_", 2))
|
if (!strncmp(ent.name, "s_", 2))
|
||||||
{
|
{
|
||||||
|
long idx = strtol(ent.name + 2, nullptr, 10);
|
||||||
|
|
||||||
std::unique_ptr<uint8_t[]> song(new uint8_t[ent.decompSz]);
|
std::unique_ptr<uint8_t[]> song(new uint8_t[ent.decompSz]);
|
||||||
|
|
||||||
if (ent.compSz == 0xffffffff)
|
if (ent.compSz == 0xffffffff)
|
||||||
@@ -1440,7 +1299,7 @@ static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadBFN
|
|||||||
}
|
}
|
||||||
|
|
||||||
SystemString name = StrToSys(ent.name);
|
SystemString name = StrToSys(ent.name);
|
||||||
ret.emplace_back(name, ContainerRegistry::SongData(std::move(song), ent.decompSz, -1, -1));
|
ret.emplace_back(name, ContainerRegistry::SongData(std::move(song), ent.decompSz, -1, idx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2011,16 +1870,10 @@ ContainerRegistry::Type ContainerRegistry::DetectContainerType(const SystemChar*
|
|||||||
return Type::RogueSquadronN64;
|
return Type::RogueSquadronN64;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ValidateBFNPC(fp))
|
if (ValidateFactor5N64Rev(fp))
|
||||||
{
|
{
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return Type::BattleForNabooPC;
|
return Type::Factor5N64Rev;
|
||||||
}
|
|
||||||
|
|
||||||
if (ValidateBFNN64(fp))
|
|
||||||
{
|
|
||||||
fclose(fp);
|
|
||||||
return Type::BattleForNabooN64;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ValidateRS2(fp))
|
if (ValidateRS2(fp))
|
||||||
@@ -2195,19 +2048,11 @@ std::vector<std::pair<SystemString, IntrusiveAudioGroupData>> ContainerRegistry:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ValidateBFNPC(fp))
|
if (ValidateFactor5N64Rev(fp))
|
||||||
{
|
{
|
||||||
auto ret = LoadBFNPC(fp);
|
auto ret = LoadFactor5N64Rev(fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
typeOut = Type::BattleForNabooPC;
|
typeOut = Type::Factor5N64Rev;
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ValidateBFNN64(fp))
|
|
||||||
{
|
|
||||||
auto ret = LoadBFNN64(fp);
|
|
||||||
fclose(fp);
|
|
||||||
typeOut = Type::BattleForNabooN64;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2282,16 +2127,9 @@ std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ContainerRegis
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ValidateBFNPC(fp))
|
if (ValidateFactor5N64Rev(fp))
|
||||||
{
|
{
|
||||||
auto ret = LoadBFNPCSongs(fp);
|
auto ret = LoadFactor5N64RevSongs(fp);
|
||||||
fclose(fp);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ValidateBFNN64(fp))
|
|
||||||
{
|
|
||||||
auto ret = LoadBFNN64Songs(fp);
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,32 +49,35 @@ struct PitchEvent
|
|||||||
/* Intermediate event */
|
/* Intermediate event */
|
||||||
struct Event
|
struct Event
|
||||||
{
|
{
|
||||||
|
enum class Type : uint8_t
|
||||||
|
{
|
||||||
|
Note,
|
||||||
|
Control,
|
||||||
|
Program,
|
||||||
|
Pitch
|
||||||
|
} m_type;
|
||||||
|
|
||||||
bool endEvent = false;
|
bool endEvent = false;
|
||||||
bool isNote = false;
|
|
||||||
bool isControlChange = false;
|
|
||||||
bool isProgChange = false;
|
|
||||||
uint8_t channel;
|
uint8_t channel;
|
||||||
uint8_t noteOrCtrl;
|
uint8_t noteOrCtrl;
|
||||||
uint8_t velOrVal;
|
uint8_t velOrVal;
|
||||||
uint8_t program;
|
uint8_t program;
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
|
|
||||||
bool isPitchBend = false;
|
|
||||||
int pitchBend;
|
int pitchBend;
|
||||||
|
|
||||||
Event(NoteEvent, uint8_t chan, uint8_t note, uint8_t vel, uint16_t len)
|
Event(NoteEvent, uint8_t chan, uint8_t note, uint8_t vel, uint16_t len)
|
||||||
: isNote(true), channel(chan), noteOrCtrl(note), velOrVal(vel), length(len)
|
: m_type(Type::Note), channel(chan), noteOrCtrl(note), velOrVal(vel), length(len)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Event(CtrlEvent, uint8_t chan, uint8_t note, uint8_t vel, uint16_t len)
|
Event(CtrlEvent, uint8_t chan, uint8_t note, uint8_t vel, uint16_t len)
|
||||||
: isControlChange(true), channel(chan), noteOrCtrl(note), velOrVal(vel), length(len)
|
: m_type(Type::Control), channel(chan), noteOrCtrl(note), velOrVal(vel), length(len)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Event(ProgEvent, uint8_t chan, uint8_t prog) : isProgChange(true), channel(chan), program(prog) {}
|
Event(ProgEvent, uint8_t chan, uint8_t prog) : m_type(Type::Program), channel(chan), program(prog) {}
|
||||||
|
|
||||||
Event(PitchEvent, uint8_t chan, int pBend) : isPitchBend(true), channel(chan), pitchBend(pBend) {}
|
Event(PitchEvent, uint8_t chan, int pBend) : m_type(Type::Pitch), channel(chan), pitchBend(pBend) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class MIDIDecoder
|
class MIDIDecoder
|
||||||
@@ -864,7 +867,7 @@ std::vector<uint8_t> SongConverter::SongToMIDI(const unsigned char* data, int& v
|
|||||||
/* Resolve key-off events */
|
/* Resolve key-off events */
|
||||||
for (auto& pair : events)
|
for (auto& pair : events)
|
||||||
{
|
{
|
||||||
if (pair.second.isNote)
|
if (pair.second.m_type == Event::Type::Note)
|
||||||
{
|
{
|
||||||
auto it = allEvents.emplace(pair.first + pair.second.length, pair.second);
|
auto it = allEvents.emplace(pair.first + pair.second.length, pair.second);
|
||||||
it->second.endEvent = true;
|
it->second.endEvent = true;
|
||||||
@@ -879,24 +882,23 @@ std::vector<uint8_t> SongConverter::SongToMIDI(const unsigned char* data, int& v
|
|||||||
encoder._sendContinuedValue(pair.first - lastTime);
|
encoder._sendContinuedValue(pair.first - lastTime);
|
||||||
lastTime = pair.first;
|
lastTime = pair.first;
|
||||||
|
|
||||||
if (pair.second.isControlChange)
|
switch (pair.second.m_type)
|
||||||
{
|
{
|
||||||
|
case Event::Type::Control:
|
||||||
encoder.controlChange(pair.second.channel, pair.second.noteOrCtrl, pair.second.velOrVal);
|
encoder.controlChange(pair.second.channel, pair.second.noteOrCtrl, pair.second.velOrVal);
|
||||||
}
|
break;
|
||||||
else if (pair.second.isProgChange)
|
case Event::Type::Program:
|
||||||
{
|
|
||||||
encoder.programChange(trk->m_midiChan, pair.second.program);
|
encoder.programChange(trk->m_midiChan, pair.second.program);
|
||||||
}
|
break;
|
||||||
else if (pair.second.isPitchBend)
|
case Event::Type::Pitch:
|
||||||
{
|
|
||||||
encoder.pitchBend(trk->m_midiChan, pair.second.pitchBend);
|
encoder.pitchBend(trk->m_midiChan, pair.second.pitchBend);
|
||||||
}
|
break;
|
||||||
else if (pair.second.isNote)
|
case Event::Type::Note:
|
||||||
{
|
|
||||||
if (pair.second.endEvent)
|
if (pair.second.endEvent)
|
||||||
encoder.noteOff(pair.second.channel, pair.second.noteOrCtrl, pair.second.velOrVal);
|
encoder.noteOff(pair.second.channel, pair.second.noteOrCtrl, pair.second.velOrVal);
|
||||||
else
|
else
|
||||||
encoder.noteOn(pair.second.channel, pair.second.noteOrCtrl, pair.second.velOrVal);
|
encoder.noteOn(pair.second.channel, pair.second.noteOrCtrl, pair.second.velOrVal);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1080,7 +1082,9 @@ std::vector<uint8_t> SongConverter::MIDIToSong(const std::vector<uint8_t>& data,
|
|||||||
lastModVal = 0;
|
lastModVal = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.second.isControlChange)
|
switch (event.second.m_type)
|
||||||
|
{
|
||||||
|
case Event::Type::Control:
|
||||||
{
|
{
|
||||||
if (event.second.noteOrCtrl == 1)
|
if (event.second.noteOrCtrl == 1)
|
||||||
{
|
{
|
||||||
@@ -1119,8 +1123,9 @@ std::vector<uint8_t> SongConverter::MIDIToSong(const std::vector<uint8_t>& data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (event.second.isProgChange)
|
case Event::Type::Program:
|
||||||
{
|
{
|
||||||
if (version == 1)
|
if (version == 1)
|
||||||
{
|
{
|
||||||
@@ -1148,16 +1153,18 @@ std::vector<uint8_t> SongConverter::MIDIToSong(const std::vector<uint8_t>& data,
|
|||||||
region.eventBuf.push_back(0);
|
region.eventBuf.push_back(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (event.second.isPitchBend)
|
case Event::Type::Pitch:
|
||||||
{
|
{
|
||||||
EncodeRLE(region.pitchBuf, uint32_t(eventTick - lastPitchTick));
|
EncodeRLE(region.pitchBuf, uint32_t(eventTick - lastPitchTick));
|
||||||
lastPitchTick = eventTick;
|
lastPitchTick = eventTick;
|
||||||
int newPitch = (event.second.pitchBend - 0x2000) * 2;
|
int newPitch = (event.second.pitchBend - 0x2000) * 2;
|
||||||
EncodeContinuousRLE(region.pitchBuf, newPitch - lastPitchVal);
|
EncodeContinuousRLE(region.pitchBuf, newPitch - lastPitchVal);
|
||||||
lastPitchVal = newPitch;
|
lastPitchVal = newPitch;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (event.second.isNote)
|
case Event::Type::Note:
|
||||||
{
|
{
|
||||||
if (version == 1)
|
if (version == 1)
|
||||||
{
|
{
|
||||||
@@ -1194,6 +1201,8 @@ std::vector<uint8_t> SongConverter::MIDIToSong(const std::vector<uint8_t>& data,
|
|||||||
region.eventBuf.push_back(event.second.velOrVal);
|
region.eventBuf.push_back(event.second.velOrVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
standalone_bootstrap.bat
Normal file
10
standalone_bootstrap.bat
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
@echo off
|
||||||
|
git clone https://github.com/AxioDL/boo.git
|
||||||
|
pushd boo
|
||||||
|
git submodule update --recursive --init
|
||||||
|
popd
|
||||||
|
|
||||||
|
git clone https://github.com/libAthena/athena.git
|
||||||
|
pushd athena
|
||||||
|
git submodule update --recursive --init
|
||||||
|
popd
|
||||||
11
standalone_bootstrap.sh
Executable file
11
standalone_bootstrap.sh
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
git clone https://github.com/AxioDL/boo.git
|
||||||
|
pushd boo
|
||||||
|
git submodule update --recursive --init
|
||||||
|
popd
|
||||||
|
|
||||||
|
git clone https://github.com/libAthena/athena.git
|
||||||
|
pushd athena
|
||||||
|
git submodule update --recursive --init
|
||||||
|
popd
|
||||||
|
|
||||||
Reference in New Issue
Block a user