Typing refinements for song events

This commit is contained in:
Jack Andersen 2016-07-17 11:23:29 -10:00
parent b421412cac
commit 2a2a16fd17
2 changed files with 129 additions and 120 deletions

View File

@ -610,111 +610,111 @@ 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;
} RS1Mappings[] = } RS1Mappings[] =
{ {
{"logo1_SNG", 0}, {"logo1_SNG", 0},
{"roguetitle_SNG", 1}, {"roguetitle_SNG", 1},
{"roguetheme_SNG", 1}, {"roguetheme_SNG", 1},
{"title_SNG", 2}, {"title_SNG", 2},
{"hangar1_SNG", 3}, {"hangar1_SNG", 3},
{"hangar2_SNG", 3}, {"hangar2_SNG", 3},
{"hangar3_SNG", 3}, {"hangar3_SNG", 3},
{"jingle01_SNG", 4}, {"jingle01_SNG", 4},
{"jingle02_SNG", 4}, {"jingle02_SNG", 4},
{"jingle03_SNG", 4}, {"jingle03_SNG", 4},
{"jingle04_SNG", 4}, {"jingle04_SNG", 4},
{"jingle05_SNG", 4}, {"jingle05_SNG", 4},
{"jingle06_SNG", 4}, {"jingle06_SNG", 4},
{"jingle07_SNG", 4}, {"jingle07_SNG", 4},
{"jingle08_SNG", 4}, {"jingle08_SNG", 4},
{"c1l1_theme_SNG", 4}, {"c1l1_theme_SNG", 4},
{"c1l1_prob1_SNG", 4}, {"c1l1_prob1_SNG", 4},
{"c1l1_prob2_SNG", 4}, {"c1l1_prob2_SNG", 4},
{"c1l1_spc01_SNG", 4}, {"c1l1_spc01_SNG", 4},
{"c1l1_spc02_SNG", 4}, {"c1l1_spc02_SNG", 4},
{"c1l2_theme_SNG", 5}, {"c1l2_theme_SNG", 5},
{"c1l2_spc01_SNG", 5}, {"c1l2_spc01_SNG", 5},
{"c1l3_spc01_SNG", 6}, {"c1l3_spc01_SNG", 6},
{"c1l3_theme_SNG", 6}, {"c1l3_theme_SNG", 6},
{"c1l4_spc01_SNG", 7}, {"c1l4_spc01_SNG", 7},
{"c1l4_theme_SNG", 7}, {"c1l4_theme_SNG", 7},
{"action1_SNG", 7}, {"action1_SNG", 7},
{"action1b_SNG", 7}, {"action1b_SNG", 7},
{"action2_SNG", 7}, {"action2_SNG", 7},
{"action4_SNG", 7}, {"action4_SNG", 7},
{"action5_SNG", 7}, {"action5_SNG", 7},
{"action6_SNG", 7}, {"action6_SNG", 7},
{"action7_SNG", 7}, {"action7_SNG", 7},
{"c1l5_act01_SNG", 8}, {"c1l5_act01_SNG", 8},
{"c1l5_act02_SNG", 8}, {"c1l5_act02_SNG", 8},
{"c1l5_theme_SNG", 8}, {"c1l5_theme_SNG", 8},
{"c1l5_spc01_SNG", 8}, {"c1l5_spc01_SNG", 8},
{"c2l1_theme_SNG", 9}, {"c2l1_theme_SNG", 9},
{"c2l1_spc01_SNG", 9}, {"c2l1_spc01_SNG", 9},
{"imperial_SNG", 10}, {"imperial_SNG", 10},
{"c2l2_theme_SNG", 10}, {"c2l2_theme_SNG", 10},
{"c2l2_spc01_SNG", 10}, {"c2l2_spc01_SNG", 10},
{"c3l5_theme_SNG", 10}, {"c3l5_theme_SNG", 10},
{"c2l3_theme_SNG", 11}, {"c2l3_theme_SNG", 11},
{"c2l3_spc01_SNG", 11}, {"c2l3_spc01_SNG", 11},
{"c2l5_theme_SNG", 12}, {"c2l5_theme_SNG", 12},
{"c2l5_spc01_SNG", 12}, {"c2l5_spc01_SNG", 12},
{"c5l1_start_SNG", 12}, {"c5l1_start_SNG", 12},
{"c4l1_theme_SNG", 12}, {"c4l1_theme_SNG", 12},
{"c5l1_1_SNG", 12}, {"c5l1_1_SNG", 12},
{"c5l1_2_SNG", 12}, {"c5l1_2_SNG", 12},
{"c5l1_3_SNG", 12}, {"c5l1_3_SNG", 12},
{"c3l1_theme_SNG", 13}, {"c3l1_theme_SNG", 13},
{"c5l2_theme_SNG", 13}, {"c5l2_theme_SNG", 13},
{"c5l2_spc01_SNG", 13}, {"c5l2_spc01_SNG", 13},
{"c5l3_theme_SNG", 13}, {"c5l3_theme_SNG", 13},
{"c3l2_theme_SNG", 14}, {"c3l2_theme_SNG", 14},
{"silent01_SNG", 14}, {"silent01_SNG", 14},
{"silent02_SNG", 14}, {"silent02_SNG", 14},
{"c3l5_spc01_SNG", 14}, {"c3l5_spc01_SNG", 14},
{"c3l4_theme_SNG", 14}, {"c3l4_theme_SNG", 14},
{"c3l4_spc01_SNG", 14}, {"c3l4_spc01_SNG", 14},
{"credits_SNG", 20}, {"credits_SNG", 20},
{"c1l1_cut1_SNG", 30}, {"c1l1_cut1_SNG", 30},
{"c1l2_cut1_SNG", 30}, {"c1l2_cut1_SNG", 30},
{"c1l3_cut1_SNG", 30}, {"c1l3_cut1_SNG", 30},
{"c1l4_cut1_SNG", 30}, {"c1l4_cut1_SNG", 30},
{"c1l5_cut1_SNG", 30}, {"c1l5_cut1_SNG", 30},
{"c2l1_cut1_SNG", 30}, {"c2l1_cut1_SNG", 30},
{"c2l2_cut1_SNG", 30}, {"c2l2_cut1_SNG", 30},
{"c2l3_cut1_SNG", 30}, {"c2l3_cut1_SNG", 30},
{"c2l5_cut1_SNG", 30}, {"c2l5_cut1_SNG", 30},
{"c2l6_cut1_SNG", 30}, {"c2l6_cut1_SNG", 30},
{"c3l1_cut1_SNG", 30}, {"c3l1_cut1_SNG", 30},
{"c3l2_cut1_SNG", 30}, {"c3l2_cut1_SNG", 30},
{"c3l3_cut1_SNG", 30}, {"c3l3_cut1_SNG", 30},
{"c3l4_cut1_SNG", 30}, {"c3l4_cut1_SNG", 30},
{"c3l5_cut1_SNG", 30}, {"c3l5_cut1_SNG", 30},
{"c4l1_cut1_SNG", 30}, {"c4l1_cut1_SNG", 30},
{"c5l1_cut1_SNG", 30}, {"c5l1_cut1_SNG", 30},
{"c5l2_cut1_SNG", 30}, {"c5l2_cut1_SNG", 30},
{"c5l3_cut1_SNG", 30}, {"c5l3_cut1_SNG", 30},
{"extr_cut1_SNG", 30}, {"extr_cut1_SNG", 30},
{"cut_jing1_SNG", 30}, {"cut_jing1_SNG", 30},
{"cut_jing2_SNG", 30}, {"cut_jing2_SNG", 30},
{"cut_seq1_SNG", 30}, {"cut_seq1_SNG", 30},
{"cut_seq2_SNG", 30}, {"cut_seq2_SNG", 30},
{"cut_seq3_SNG", 30}, {"cut_seq3_SNG", 30},
{"cut_seq4_SNG", 30}, {"cut_seq4_SNG", 30},
{"cut_seq5_SNG", 30}, {"cut_seq5_SNG", 30},
{"cut_seq6_SNG", 30}, {"cut_seq6_SNG", 30},
{"cut_seq7_SNG", 30}, {"cut_seq7_SNG", 30},
{"cut_seq8_SNG", 30}, {"cut_seq8_SNG", 30},
{} {}
}; };
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))

View File

@ -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;
}
} }
} }
} }