Ejemplo n.º 1
0
bool ModModule::load(Stream* stream, int loadMode)
{
    noConstMetaInfo().filename = stream->name();
    setTempo(125);
    setSpeed(6);
    state().globalVolume = 0x40;
    char modName[20];
    stream->read(modName, 20);
    noConstMetaInfo().title = stringncpy(modName, 20);
    const IdMetaInfo* meta = nullptr;
    if(loadMode != LoadingMode::Smp15)
    {
        // check 31-sample mod
        logger()->info(L4CXX_LOCATION, "Probing meta-info for 31-sample mod...");
        stream->seek(0x438);
        meta = findMeta(stream);
        if(meta == nullptr)
        {
            logger()->warn(L4CXX_LOCATION, "Could not find a valid module ID");
            return false;
        }
    }
    else
    {
        logger()->info(L4CXX_LOCATION, "Trying to load 15-sample mod...");
        meta = &smp15MetaInfo;
    }
    logger()->debug(L4CXX_LOCATION, "%d-channel, ID '%s', Tracker '%s'", int(meta->channels), meta->id, meta->tracker);
    noConstMetaInfo().trackerInfo = meta->tracker;
    for(int i = 0; i < meta->channels; i++)
    {
        m_channels.emplace_back(new ModChannel(this, ((i + 1) & 2) == 0));
    }
    stream->seek(20);
    const int numSamples = loadMode == LoadingMode::Smp15 ? 15 : 31;
    for(int i = 0; i < numSamples; i++)
    {
        ModSample* smp = new ModSample();
        m_samples.push_back(smp);
        if(!smp->loadHeader(stream))
        {
            logger()->warn(L4CXX_LOCATION, "Sample header could not be loaded");
            return false;
        }
    }
    uint8_t maxPatNum = 0;
    {
        // load orders
        uint8_t songLen;
        *stream >> songLen;
        if(songLen > 128)
        {
            songLen = 128;
        }
        logger()->debug(L4CXX_LOCATION, "Song length: %d", int(songLen));
        uint8_t tmp;
        *stream >> tmp; // skip the restart pos
        for(uint_fast8_t i = 0; i < songLen; i++)
        {
            *stream >> tmp;
            if(tmp >= 64)
            {
                continue;
            }
            if(tmp > maxPatNum)
            {
                maxPatNum = tmp;
            }
            logger()->trace(L4CXX_LOCATION, "Order %d index: %d", int(i), int(tmp));
            addOrder(std::make_unique<OrderEntry>(tmp));
        }
        if(loadMode != LoadingMode::Smp31Malformed)
        {
            while(songLen++ < 128)
            {
                *stream >> tmp;
                if(tmp >= 64)
                {
                    continue;
                }
                if(tmp > maxPatNum)
                {
                    maxPatNum = tmp;
                }
            }
        }
        else
        {
            stream->seekrel(128 - songLen);
        }
    }