static void load_bagObjects(BagObject *bo, int &count) { uint16 totalSize = loadInt16(); uint8 *bagData = (uint8 *)malloc(totalSize); if (bagData) { loadStr(bagData, totalSize); count = loadInt16(); assert(count <= Game::NUM_BAG_OBJECTS); uint16 bagObjectsOffset[Game::NUM_BAG_OBJECTS + 1]; for (int i = 0; i < count; ++i) { bagObjectsOffset[i] = loadInt16(); loadStr(bo[i].name, 20); } for (int i = 0; i < count; ++i) { int dataSize = (i == count - 1) ? totalSize : bagObjectsOffset[i + 1]; dataSize -= bagObjectsOffset[i]; bo[i].data = (uint8 *)malloc(dataSize); if (bo[i].data) { memcpy(bo[i].data, bagData + bagObjectsOffset[i], dataSize); bo[i].dataSize = dataSize; } } free(bagData); } }
static void saveOrLoadStr(char *s, int16 len = -1) { bool countTermChar = (len == -2); // deal with original buggy file format... bool storeLen = (len < 0); if (storeLen) { len = strlen(s); if (countTermChar) { ++len; } saveOrLoadInt16(len); } switch (_saveOrLoadMode) { case kSaveMode: saveStr(s, len); break; case kLoadMode: loadStr(s, len); if (storeLen) { s[len] = 0; } break; } }
TrackFrames buildTrackFramesFromMidi(const std::string& filename) { TrackFrames trackFrames; FILE* pFic; fopen_s(&pFic, filename.c_str(), "rb"); // Load header struct HeaderChunk { char HThd[4]; uint32_t size; uint16_t format; uint16_t nbTrack; uint16_t division; } headerChunk; loadStr(headerChunk.HThd, 4, pFic); headerChunk.size = load32(pFic); headerChunk.format = load16(pFic); headerChunk.nbTrack = load16(pFic); headerChunk.division = load16(pFic); uint32_t maxTime = 0; std::set<int> channelSet; //int midiToChannels[] = { // mario // 5, 0, 1, 2, // 5, 5, 5, 5, // 5, 5, 5, 5, // 5, 5, 5, 5, //}; //int midiToChannels[] = { // sm2 // 0, 2, 1, 5, // 5, 5, 5, 5, // 5, 3, 5, 5, // 5, 5, 5, 5, //}; int midiToChannels[] = { 0, 1, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, }; //int midiToChannels[] = { // zelda // 0, 1, 2, 5, // 5, 5, 5, 5, // 5, 3, 5, 5, // 5, 5, 5, 5, //}; // Load tracks for (auto i = 0u; i < headerChunk.nbTrack; ++i) { char MTrk[4]; loadStr(MTrk, 4, pFic); auto len = load32(pFic); auto start = ftell(pFic); auto cur = start; uint32_t curTime = 0; while (cur - start < static_cast<decltype(cur)>(len)) { auto v_time = loadLength(pFic); auto event = load8(pFic); curTime += v_time;// / (headerChunk.division / 24); maxTime = std::max(maxTime, curTime); trackFrames.resize(maxTime * 4 + 16); if (event == 0xFF) { // Meta event event = load8(pFic); if (event == 0x58) { // Time Signature event = load8(pFic); assert(event == 0x04); load32(pFic); // Ignore who f*****g cares } else if (event == 0x7F) { // Sequencer Specific Meta-Event auto dataLen = load8(pFic); // Len, ignore while (dataLen) { load8(pFic); --dataLen; } } else if (event == 0x51) { // Set Tempo event = load8(pFic); assert(event == 0x03); load8(pFic); load8(pFic); load8(pFic); } else if (event == 0x2F) { // End of Track event = load8(pFic); assert(event == 0x00); } else if (event == 0x03) { // Sequence/Track Name auto textLen = load8(pFic); char text[257] = {0}; loadStr(text, textLen, pFic); printf("Track found: %i, %s\n", i, text); } else if (event == 0x59) { // Key Signature event = load8(pFic); assert(event == 0x02); auto sf = load8(pFic); auto mi = load8(pFic); } else if (event == 0x21) { // End of Track event = load8(pFic); assert(event == 0x01); load8(pFic); } else if (event == 0x20) { // MIDI Channel Prefix event = load8(pFic); assert(event == 0x01); auto channel = load8(pFic); } else { assert(false); } } else if (event & 0x80) { auto channelNo = event & 0x0F; channelSet.insert(channelNo); if (channelNo < sizeof(midiToChannels) / sizeof(int)) channelNo = midiToChannels[channelNo]; event = event & 0xF0; if (event == 0xB0) { // Control Change auto controllerNumber = load8(pFic) & 0x7F; auto controllerValue = load8(pFic) & 0x7F; } else if (event == 0xC0) { // Program Change auto programNumber = load8(pFic) & 0x7F; } else if (event == 0x90) { // Note On event auto note = load8(pFic) & 0x7F; auto vol = load8(pFic) & 0x7F; if (channelNo < 3) { auto& trackFrame = trackFrames[curTime * 4 + channelNo]; trackFrame = NOTE(noteTable[note], channelNo, (vol * 15) / 127); } else if (channelNo == 3) { auto& trackFrame = trackFrames[curTime * 4 + channelNo]; trackFrame = NOTE(noteTable[note + 12], channelNo, (vol * 15) / 127); } } else if (event == 0x80) { // Note Off event auto note = load8(pFic) & 0x7F; auto vol = load8(pFic) & 0x7F; if (channelNo == 2) { //auto& trackFrame = trackFrames[curTime * 4 + channelNo]; //trackFrame = NOTE(noteTable[note + 12], channelNo, 0); } if (channelNo == 3) { auto& trackFrame = trackFrames[curTime * 4 + channelNo]; trackFrame = NOTE(noteTable[note], channelNo, 0); } } else if (event == 0xE0) { // Pitch Wheel Change auto l = load8(pFic) & 0x7F; auto m = load8(pFic) & 0x7F; } else { assert(false); } } else if (event <= 0x7F) { load8(pFic); } else { assert(false); } cur = ftell(pFic); } } fclose(pFic); for (auto& channelNo : channelSet) { printf("%i\n", channelNo); } return trackFrames; }