5 Commits
v1.9 ... v1.10

Author SHA1 Message Date
Jack Andersen
596bc66ce6 Windows build fix 2016-07-07 09:37:50 -10:00
Jack Andersen
3a7b43a63a Mask out high bit on Tempo changes 2016-07-07 09:17:30 -10:00
Jack Andersen
83a2bf0b4e Merge branch 'master' of https://github.com/AxioDL/amuse 2016-07-06 18:21:49 -10:00
Jack Andersen
695fc10b8f Setup ID prompt for amuserender 2016-07-06 18:19:40 -10:00
feea7c2ecc Add PaperMario TTYD Song Group descs 2016-07-06 21:10:02 -07:00
4 changed files with 112 additions and 4 deletions

View File

@@ -7,8 +7,10 @@
#include "optional.hpp" #include "optional.hpp"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <signal.h>
#include <thread> #include <thread>
#include <map> #include <map>
#include <set>
#include <vector> #include <vector>
#include <unordered_map> #include <unordered_map>
#include <stdarg.h> #include <stdarg.h>
@@ -95,7 +97,6 @@ int wmain(int argc, const boo::SystemChar** argv)
int main(int argc, const boo::SystemChar** argv) int main(int argc, const boo::SystemChar** argv)
#endif #endif
{ {
signal(SIGINT, SIGINTHandler);
logvisor::RegisterConsoleLogger(); logvisor::RegisterConsoleLogger();
std::vector<boo::SystemString> m_args; std::vector<boo::SystemString> m_args;
@@ -392,6 +393,29 @@ int main(int argc, const boo::SystemChar** argv)
{ {
selData = &songSearch->second.first->second; selData = &songSearch->second.first->second;
songIndex = songSearch->second.second; songIndex = songSearch->second.second;
std::set<int> sortSetups;
for (auto& pair : songIndex->m_midiSetups)
sortSetups.insert(pair.first);
if (m_setupId == -1)
{
/* Ask user to specify which group in project */
printf("Multiple MIDI Setups:\n");
for (int setup : sortSetups)
printf(" %d\n", setup);
int userSel = 0;
printf("Enter Setup Number: ");
if (scanf("%d", &userSel) <= 0)
{
Log.report(logvisor::Error, "unable to parse prompt");
exit(1);
}
m_setupId = userSel;
}
if (sortSetups.find(m_setupId) == sortSetups.cend())
{
Log.report(logvisor::Error, "unable to find setup %d", m_setupId);
exit(1);
}
} }
else else
{ {
@@ -436,6 +460,7 @@ int main(int argc, const boo::SystemChar** argv)
/* Enter playback loop */ /* Enter playback loop */
std::shared_ptr<amuse::Sequencer> seq = engine.seqPlay(m_groupId, m_setupId, m_arrData->m_data.get()); std::shared_ptr<amuse::Sequencer> seq = engine.seqPlay(m_groupId, m_setupId, m_arrData->m_data.get());
size_t wroteFrames = 0; size_t wroteFrames = 0;
signal(SIGINT, SIGINTHandler);
do do
{ {
engine.pumpEngine(); engine.pumpEngine();

View File

@@ -1745,6 +1745,73 @@ static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadSta
return ret; return ret;
} }
static bool ValidatePaperMarioTTYDSongs(FILE* fp)
{
size_t endPos = FileLength(fp);
std::unique_ptr<uint8_t[]> data(new uint8_t[endPos]);
fread(data.get(), 1, endPos, fp);
uint32_t off = 0;
while (off < endPos)
{
int32_t len = SBig(*(reinterpret_cast<int32_t*>(data.get() + off)));
if (len == -1)
break;
off += len;
}
return (off + 4) == endPos;
}
struct TTYDSongDesc
{
char name[30];
uint8_t group;
uint8_t setup;
};
static std::vector<std::pair<SystemString, ContainerRegistry::SongData>> LoadPaperMarioTTYDSongs(FILE* midifp, FILE* descFp)
{
if (!descFp)
return {};
std::vector<TTYDSongDesc> songDescs;
/* We need at least 143 for the default song table */
songDescs.reserve(143);
while (true)
{
TTYDSongDesc songDesc;
fread(&songDesc, sizeof(TTYDSongDesc), 1, descFp);
if (songDesc.name[0] == 0)
break;
uint32_t i = 0;
songDescs.push_back(songDesc);
}
size_t endPos = FileLength(midifp);
std::unique_ptr<uint8_t[]> data(new uint8_t[endPos]);
fread(data.get(), 1, endPos, midifp);
uint32_t off = 0;
uint32_t song = 0;
std::vector<std::pair<SystemString, ContainerRegistry::SongData>> ret;
while (off < endPos)
{
int32_t len = SBig(*(reinterpret_cast<int32_t*>(data.get() + off)));
if (len == -1)
break;
std::unique_ptr<uint8_t[]> songData(new uint8_t[len - 32]);
memcpy(songData.get(), (data.get() + off + 32), len - 32);
ret.emplace_back(StrToSys(std::string(songDescs[song].name, 30)),
ContainerRegistry::SongData(std::move(songData), len - 32,
songDescs[song].group, songDescs[song].setup));
off += len;
song++;
}
return ret;
}
ContainerRegistry::Type ContainerRegistry::DetectContainerType(const SystemChar* path) ContainerRegistry::Type ContainerRegistry::DetectContainerType(const SystemChar* path)
{ {
FILE* fp; FILE* fp;
@@ -2135,6 +2202,22 @@ ContainerRegistry::LoadSongs(const SystemChar* path)
return ret; return ret;
} }
if (ValidatePaperMarioTTYDSongs(fp))
{
/* Song Description */
SystemChar newpath[1024];
dot = StrRChr(path, _S('.'));
SNPrintf(newpath, 1024, _S("%.*s.stbl"), int(dot - path), path);
FILE* descFp = FOpen(newpath, _S("rb"));
if (descFp)
{
auto ret = LoadPaperMarioTTYDSongs(fp, descFp);
fclose(fp);
fclose(descFp);
return ret;
}
}
fclose(fp); fclose(fp);
} }

View File

@@ -675,7 +675,7 @@ std::vector<uint8_t> SongConverter::SongToMIDI(const unsigned char* data, int& v
encoder.getResult().push_back(0x51); encoder.getResult().push_back(0x51);
encoder.getResult().push_back(3); encoder.getResult().push_back(3);
uint32_t tempo24 = SBig(60000000 / change.m_tempo); uint32_t tempo24 = SBig(60000000 / (change.m_tempo & 0x7fffffff));
for (int i=1 ; i<4 ; ++i) for (int i=1 ; i<4 ; ++i)
encoder.getResult().push_back(reinterpret_cast<uint8_t*>(&tempo24)[i]); encoder.getResult().push_back(reinterpret_cast<uint8_t*>(&tempo24)[i]);

View File

@@ -354,7 +354,7 @@ bool SongState::initialize(const unsigned char* ptr)
else else
m_tempoPtr = nullptr; m_tempoPtr = nullptr;
m_tempo = m_header.m_initialTempo; m_tempo = m_header.m_initialTempo & 0x7fffffff;
m_curTick = 0; m_curTick = 0;
m_songState = SongPlayState::Playing; m_songState = SongPlayState::Playing;
@@ -604,7 +604,7 @@ bool SongState::advance(Sequencer& seq, double dt)
if (remTicks <= 0) if (remTicks <= 0)
{ {
/* Turn over tempo */ /* Turn over tempo */
m_tempo = change.m_tempo; m_tempo = change.m_tempo & 0x7fffffff;
seq.setTempo(m_tempo * 384 / 60); seq.setTempo(m_tempo * 384 / 60);
++m_tempoPtr; ++m_tempoPtr;
continue; continue;