Пример #1
0
static inline size_t snprint_pointer(char *buf, size_t size, void *ptr,
                                     bool left, char padding, size_t width)
{
    char str[35] = "0x";
    size_t len = utoa_s((unsigned int)ptr, 16, str + 2, sizeof(str) - 2);

    if (len == 0)
        return 0;

    len += 2;
    return copy_with_padding(buf, size, str, len, left, padding, width);
}
Пример #2
0
static inline size_t snprint_uint(char *buf, size_t size, unsigned int i,
                                  unsigned int base, bool left,
                                  char padding, size_t width)
{
    char str[33];
    size_t len = utoa_s(i, base, str, sizeof(str));

    if (len == 0)
        return 0;

    return copy_with_padding(buf, size, str, len, left, padding, width);
}
Пример #3
0
bool module_renderer::SaveITProject(LPCSTR lpszFileName)
//-------------------------------------------------
{
    // Check song type

    if(!(m_dwSongFlags & SONG_ITPROJECT)) return false;

    UINT i,j = 0;
    for(i = 0 ; i < m_nInstruments ; i++) { if(m_szInstrumentPath[i][0] != '\0' || !Instruments[i+1]) j++; }
    if(m_nInstruments && j != m_nInstruments) return false;

    // Open file

    FILE *f;

    if((!lpszFileName) || ((f = fopen(lpszFileName, "wb")) == NULL)) return false;


    // File ID

    uint32_t id = ITP_FILE_ID;
    fwrite(&id, 1, sizeof(id), f);

    id = ITP_VERSION;
    fwrite(&id, 1, sizeof(id), f);

    // Song name

    // name string length
    id = 27;
    fwrite(&id, 1, sizeof(id), f);

    // song name
    char namebuf[27];
    copy_with_padding(namebuf, 27, this->song_name);
    fwrite(namebuf, 1, 27, f);

    // Song comments

    // comment string length
    id = m_lpszSongComments ? strlen(m_lpszSongComments)+1 : 0;
    fwrite(&id, 1, sizeof(id), f);

    // comment string
    if(m_lpszSongComments) fwrite(&m_lpszSongComments[0], 1, strlen(m_lpszSongComments)+1, f);

    // Song global config

    id = (m_dwSongFlags & SONG_FILE_FLAGS);
    fwrite(&id, 1, sizeof(id), f);
    id = m_nDefaultGlobalVolume;
    fwrite(&id, 1, sizeof(id), f);
    id = m_nSamplePreAmp;
    fwrite(&id, 1, sizeof(id), f);
    id = m_nDefaultSpeed;
    fwrite(&id, 1, sizeof(id), f);
    id = m_nDefaultTempo;
    fwrite(&id, 1, sizeof(id), f);

    // Song channels data

    // number of channels
    id = m_nChannels;
    fwrite(&id, 1, sizeof(id), f);

    // channel name string length
    id = MAX_CHANNELNAME;
    fwrite(&id, 1, sizeof(id), f);

    // channel config data
    for(i=0; i<m_nChannels; i++){
        id = ChnSettings[i].nPan;
        fwrite(&id, 1, sizeof(id), f);
        id = ChnSettings[i].dwFlags;
        fwrite(&id, 1, sizeof(id), f);
        id = ChnSettings[i].nVolume;
        fwrite(&id, 1, sizeof(id), f);
        fwrite(&ChnSettings[i].szName[0], 1, MAX_CHANNELNAME, f);
    }

    // Song mix plugins

    // mix plugins data length
    id = SaveMixPlugins(NULL, TRUE);
    fwrite(&id, 1, sizeof(id), f);

    // mix plugins data
    SaveMixPlugins(f, FALSE);

    // Song midi config

    // midi cfg data length
    id = sizeof(MODMIDICFG);
    fwrite(&id, 1, sizeof(id), f);

    // midi cfg
    fwrite(&m_MidiCfg, 1, sizeof(MODMIDICFG), f);

    // Song Instruments

    // number of instruments
    id = m_nInstruments;
    fwrite(&id, 1, sizeof(id), f);

    // path name string length
    id = _MAX_PATH;
    fwrite(&id, 1, sizeof(id), f);

    // instruments' path
    for(i=0; i<m_nInstruments; i++) fwrite(&m_szInstrumentPath[i][0], 1, _MAX_PATH, f);

    // Song Orders

    // order array size
    id = Order.size();
    fwrite(&id, 1, sizeof(id), f);

    // order array
    Order.WriteAsByte(f, id);

    // Song Patterns

    // number of patterns
    id = MAX_PATTERNS;
    fwrite(&id, 1, sizeof(id), f);

    // number of pattern name strings
    modplug::tracker::patternindex_t numNamedPats = Patterns.GetNumNamedPatterns();
    numNamedPats = bad_min(numNamedPats, MAX_PATTERNS);
    id = numNamedPats;
    fwrite(&id, 1, sizeof(id), f);

    // length of a pattern name string
    id = MAX_PATTERNNAME;
    fwrite(&id, 1, sizeof(id), f);
    // pattern name string
    for(modplug::tracker::patternindex_t nPat = 0; nPat < numNamedPats; nPat++)
    {
        char name[MAX_PATTERNNAME];
        MemsetZero(name);
        Patterns[nPat].GetName(name, MAX_PATTERNNAME);
        fwrite(name, 1, MAX_PATTERNNAME, f);
    }

    // modcommand data length
    id = sizeof(modplug::tracker::modevent_t);
    fwrite(&id, 1, sizeof(id), f);

    // patterns data content
    for(UINT npat=0; npat<MAX_PATTERNS; npat++){
        // pattern size (number of rows)
        id = Patterns[npat] ? Patterns[npat].GetNumRows() : 0;
        fwrite(&id, 1, sizeof(id), f);
        // pattern data
        if(Patterns[npat] && Patterns[npat].GetNumRows()) Patterns[npat].WriteITPdata(f);
        //fwrite(Patterns[npat], 1, m_nChannels * Patterns[npat].GetNumRows() * sizeof(modplug::tracker::modcommand_t), f);
    }

    // Song lonely (instrument-less) samples

    // Write original number of samples
    id = m_nSamples;
    fwrite(&id, 1, sizeof(id), f);

    vector<bool> sampleUsed(m_nSamples, false);

    // Mark samples used in instruments
    for(i=0; i<m_nInstruments; i++)
    {
        if(Instruments[i + 1] != nullptr)
        {
            modinstrument_t *p = Instruments[i + 1];
            for(j = 0; j < 128; j++)
            {
                if(p->Keyboard[j] > 0 && p->Keyboard[j] <= m_nSamples)
                    sampleUsed[p->Keyboard[j] - 1] = true;
            }
        }
    }

    // Count samples not used in any instrument
    i = 0;
    for(j = 1; j <= m_nSamples; j++)
        if(!sampleUsed[j - 1] && Samples[j].sample_data) i++;

    id = i;
    fwrite(&id, 1, sizeof(id), f);

    // Write samples not used in any instrument (help, this looks like duplicate code!)
    ITSAMPLESTRUCT itss;
    for(UINT nsmp=1; nsmp<=m_nSamples; nsmp++)
    {
        if(!sampleUsed[nsmp - 1] && Samples[nsmp].sample_data)
        {

            modsample_t *psmp = &Samples[nsmp];
            memset(&itss, 0, sizeof(itss));
            memcpy(itss.filename, psmp->legacy_filename, 12);
            memcpy(itss.name, m_szNames[nsmp], 26);

            itss.id = LittleEndian(IT_IMPS);
            itss.gvl = (uint8_t)psmp->global_volume;
            itss.flags = 0x00;

            if(psmp->flags & CHN_LOOP) itss.flags |= 0x10;
            if(psmp->flags & CHN_SUSTAINLOOP) itss.flags |= 0x20;
            if(psmp->flags & CHN_PINGPONGLOOP) itss.flags |= 0x40;
            if(psmp->flags & CHN_PINGPONGSUSTAIN) itss.flags |= 0x80;
            itss.C5Speed = psmp->c5_samplerate;
            if (!itss.C5Speed) itss.C5Speed = 8363;
            itss.length = psmp->length;
            itss.loopbegin = psmp->loop_start;
            itss.loopend = psmp->loop_end;
            itss.susloopbegin = psmp->sustain_start;
            itss.susloopend = psmp->sustain_end;
            itss.vol = (uint8_t)(psmp->default_volume >> 2);
            itss.dfp = (uint8_t)(psmp->default_pan >> 2);
            itss.vit = autovibxm2it[psmp->vibrato_type & 7];
            itss.vis = bad_min(psmp->vibrato_rate, 64);
            itss.vid = bad_min(psmp->vibrato_depth, 32);
            itss.vir = bad_min(psmp->vibrato_sweep, 255); //(psmp->vibrato_sweep < 64) ? psmp->vibrato_sweep * 4 : 255;
            if (psmp->flags & CHN_PANNING) itss.dfp |= 0x80;
            if ((psmp->sample_data) && (psmp->length)) itss.cvt = 0x01;
            UINT flags = RS_PCM8S;

            if(psmp->flags & CHN_STEREO)
            {
                flags = RS_STPCM8S;
                itss.flags |= 0x04;
            }
            if(psmp->flags & CHN_16BIT)
            {
                itss.flags |= 0x02;
                flags = (psmp->flags & CHN_STEREO) ? RS_STPCM16S : RS_PCM16S;
            }

            id = nsmp;
            fwrite(&id, 1, sizeof(id), f);

            itss.samplepointer = NULL;
            fwrite(&itss, 1, sizeof(ITSAMPLESTRUCT), f);

            id = WriteSample(NULL, psmp, flags);
            fwrite(&id, 1, sizeof(id), f);
            WriteSample(f, psmp, flags);
        }
    }