Пример #1
0
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);
	}
}
Пример #2
0
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;
	}
}
Пример #3
0
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;
}