Пример #1
0
//////////////////////////////////////////////////////
// Load DisorderTracker II module
//////////////////////////////////////////////////////
mp_sint32 LoaderPLM::load(XMFileBase& f, XModule* module)
{
    mp_sint32 i,j;

    module->cleanUp();

    // this will make code much easier to read
    TXMHeader*		header = &module->header;
    TXMInstrument*	instr  = module->instr;
    TXMSample*		smp	   = module->smp;
    TXMPattern*		phead  = module->phead;

    // we're already out of memory here
    if (!phead || !instr || !smp)
        return MP_OUT_OF_MEMORY;

    ///////////////////////////////////////////////////
    // read header
    ///////////////////////////////////////////////////

    f.read(header->sig,1,3);
    f.readByte();

    mp_uint32 hdrSize = f.readByte();
    mp_ubyte ver = f.readByte();

    if (ver != 0x10)
        return MP_LOADER_FAILED;

    f.read(header->name, 1, 32);

    // skip remaining bytes from the song name
    f.readDword(); // 36
    f.readDword(); // 40
    f.readDword(); // 44
    f.readDword(); // 48 => skipped rest of song name :)

    header->channum = f.readByte();

    f.readByte();	// doc says ignore flags byte

    mp_ubyte maxVol = f.readByte();

    f.readByte();	// skip soundblaster amplify

    header->speed = f.readByte();

    header->tempo = f.readByte();

    // panning positions
    for (i = 0; i < 32; i++)
        header->pan[i] = (mp_ubyte)XModule::pan15to255(f.readByte());

    header->smpnum = header->insnum = f.readByte();

    mp_sint32 numPatterns = f.readByte();

    mp_sint32 numOrders = f.readWord();

    header->mainvol = 255;

    ///////////////////////////////////////////////////
    // read orderlist, special with PLM
    ///////////////////////////////////////////////////

    f.seekWithBaseOffset(hdrSize);

    TOrdHdr* ordHeaders = new TOrdHdr[numOrders];

    for (i = 0; i < numOrders; i++)
    {
        ordHeaders[i].startPos = f.readWord();
        ordHeaders[i].startChannel = f.readByte();
        ordHeaders[i].patternIndex = f.readByte();

        /*printf("%x, %i, %i, %i\n",f.posWithBaseOffset(), ordHeaders[i].startPos, ordHeaders[i].startChannel, ordHeaders[i].patternIndex);
        getch();*/

    }

    mp_uint32* patOffsets = new mp_uint32[numPatterns];

    mp_uint32* smpOffsets = new mp_uint32[header->insnum];

    f.readDwords(patOffsets, numPatterns);
    f.readDwords(smpOffsets, header->insnum);

    ///////////////////////////////////////////////////
    // read patterns
    ///////////////////////////////////////////////////
    mp_ubyte* patterns[256];

    for (i = 0; i < numPatterns; i++)
    {

        if (patOffsets[i] != 0)
        {
            f.seekWithBaseOffset(patOffsets[i]);

            mp_uint32 size = f.readDword();

            patterns[i] = new mp_ubyte[size];

            if (patterns[i] == NULL)
            {

                for (j = 0; j < i; j++)
                    delete[] patterns[j];

                delete[] smpOffsets;
                delete[] patOffsets;
                return MP_OUT_OF_MEMORY;
            }

            f.read(patterns[i], 1, size);
        }
        else
        {
            patterns[i] = NULL;
        }

    }

    ///////////////////////////////////////////////////
    // read instruments (+samples)
    ///////////////////////////////////////////////////
    /* Sample layout:
    id              4 bytes  0			; ID (PLS+28)
    headersize      1 byte   4			; size of header in bytes, including ID etc
    version         1 byte   5
    fullname        32 byte  6          ; NOT asciiz
    filename        12 byte  38			; ditto
    pan             byte     50         ; default pan, 0..f, >f=none
    vol             byte     51			; default vol 0..40h
    flags           byte     52			; 1 = 16 bit , 0=8 bit
    c4spd           word     53			; c4spd (as for S3M)
    gusloc          dword    55			; posn in gusram (not used in file)
    loopst          dword    59			; loopstart
    loopen          dword    63			; loopend
    len             dword    67			; data size IN BYTES
    data			lots of bytes		; unsigned data*/

    for (i = 0; i < header->insnum; i++)
    {

        if (!smpOffsets[i])
            continue;

        f.seekWithBaseOffset(smpOffsets[i]);

        mp_uint32 id = f.readDword();

        if (id != 0x1a534c50)
        {
            for (j = 0; j < numPatterns; j++)
                delete[] patterns[j];

            delete[] smpOffsets;
            delete[] patOffsets;

            return MP_LOADER_FAILED;
        }

        mp_uint32 sHdrSize = f.readByte();
        mp_ubyte ver = f.readByte();

        f.read(instr[i].name, 1, 32);

        f.read(smp[i].name, 1, 12);

        mp_ubyte pan = f.readByte();

        smp[i].flags = 4;

        if (pan <= 0xf)
        {
            smp[i].pan = (mp_ubyte)XModule::pan15to255(pan);
            smp[i].flags|=2;
        }

        mp_ubyte vol = f.readByte();

        smp[i].vol = vol <= 64 ? XModule::vol64to255(vol) : 255/*0xff*/;

        mp_ubyte flags = f.readByte();

        smp[i].type = (flags&1)?16:0;

        XModule::convertc4spd(f.readWord(), &smp[i].finetune, &smp[i].relnote);

        f.readDword();	// skip guspos

        smp[i].loopstart = f.readDword();
        //smp[i].looplen = f.readDword();

        mp_sint32 looplen = ((mp_sint32)f.readDword() - (mp_sint32)smp[i].loopstart) - ((flags&1)?2:1);
        if (looplen < 0)
            looplen = 0;
        smp[i].looplen = looplen;

        if (smp[i].looplen)
        {
            smp[i].type = (flags & 2) ? 2 : 1;
        }

        smp[i].samplen = f.readDword();

#ifdef VERBOSE
        printf("%i: %i, %i, %x\n",i+1,vol,flags,smp[i].samplen);
#endif

        if (smp[i].samplen)
        {

            instr[i].samp = 1;

            for (j = 0; j < 120; j++)
            {
                instr[i].snum[j] = i;
            }

            smp[i].sample = (mp_sbyte*)module->allocSampleMem(smp[i].samplen);

            if (smp[i].sample == NULL)
            {
                for (j = 0; j < numPatterns; j++)
                    delete[] patterns[j];

                delete[] smpOffsets;
                delete[] patOffsets;
                return MP_OUT_OF_MEMORY;
            }

            if (flags&1)
            {
                module->loadSample(f, smp[i].sample, smp[i].samplen, smp[i].samplen>>1, XModule::ST_UNSIGNED);
                smp[i].samplen>>=1;
            }
            else
            {
Пример #2
0
mp_sint32 LoaderOKT::load(XMFileBase& f, XModule* module)
{
	// max pattern size
	mp_ubyte buffer[8192];
	
	module->cleanUp();

	// this will make code much easier to read
	TXMHeader*		header = &module->header;
	TXMInstrument*	instr  = module->instr;
	TXMSample*		smp	   = module->smp;
	TXMPattern*		phead  = module->phead;	
	
	// we're already out of memory here
	if (!phead || !instr || !smp)
		return -7;
	
	f.read(header->sig, 1, 8);

	header->speed = 125;
	header->tempo = 6;
	header->mainvol = 255;
	
	mp_sint32 pc = 0;
	mp_sint32 sc = 0;
	
	while (true)
	{
		
		mp_ubyte ID[4];
		
		mp_uint32 bytesRead = f.read(&ID, 4, 1);

		if (bytesRead != 4)
			break;		
		
		switch (BigEndian::GET_DWORD(ID))
		{
			case 0x434D4F44:	// 'CMOD'
			{
				f.read(buffer, 4, 1);
				
				if (BigEndian::GET_DWORD(buffer) != 8)
					return -8;
					
				for (mp_sint32 i = 0; i < 4; i++)
				{
					f.read(buffer, 2, 1);
					if (!BigEndian::GET_WORD(buffer))
						header->channum++;
					else
						header->channum+=2;
				}
				
				break;
			}
			
			case 0x53414D50:	// 'SAMP'
			{
				f.read(buffer, 4, 1);
				
				header->insnum = BigEndian::GET_DWORD(buffer) / 32;
				
				mp_sint32 s = 0;
				for (mp_sint32 i = 0; i < header->insnum; i++)
				{
					f.read(buffer, 1, 32);
					
					memcpy(instr[i].name, buffer, 20);
					
					if (BigEndian::GET_DWORD(buffer+20))
					{
						instr[i].samp = 1;
						
						memcpy(smp[s].name, buffer, 20);
						
						smp[s].samplen = BigEndian::GET_DWORD(buffer+20);
						
						smp[s].loopstart = BigEndian::GET_WORD(buffer+24) << 1;
						smp[s].looplen = BigEndian::GET_WORD(buffer+26) << 1;
						smp[s].vol = XModule::vol64to255(BigEndian::GET_WORD(buffer+29));
						smp[s].flags = 1;
						
						if (smp[s].looplen > 2)
							smp[s].type = 1;
						
						for (mp_sint32 j = 0; j < 120; j++) 
							instr[i].snum[j] = s;
						
						s++;
					}
					
					header->smpnum = s;
					
				}
				
				break;
			}

			case 0x53504545:	// 'SPEE'
			{
				f.read(buffer, 4, 1);
				
				if (BigEndian::GET_DWORD(buffer) != 2)
					return -8;
				
				f.read(buffer, 2, 1);				
				
				header->tempo = BigEndian::GET_WORD(buffer);
				
				break;
			}
			
			case 0x534C454E:	// 'SLEN'
			{
				f.read(buffer, 4, 1);			

				if (BigEndian::GET_DWORD(buffer) != 2)
					return -8;
					
				f.read(buffer, 2, 1);				
				
				header->patnum = BigEndian::GET_WORD(buffer);
			
				break;
			}

			case 0x504C454E:	// 'PLEN'
			{
				f.read(buffer, 4, 1);			

				if (BigEndian::GET_DWORD(buffer) != 2)
					return -8;
					
				f.read(buffer, 2, 1);				
				
				header->ordnum = BigEndian::GET_WORD(buffer);
			
				break;
			}

			case 0x50415454:	// 'PATT'
			{
				f.read(buffer, 4, 1);			

				if (BigEndian::GET_DWORD(buffer) > 256)
					return -8;
					
				f.read(header->ord, 1, BigEndian::GET_DWORD(buffer));				
				
				break;
			}

			case 0x50424F44 :	// 'PBOD'
			{
				f.read(buffer, 4, 1);			

				mp_sint32 chunkLen = BigEndian::GET_DWORD(buffer);

				mp_sint32 i = pc;
				
				if (chunkLen)
				{
					f.read(buffer, 1, chunkLen);
					
					phead[i].rows = BigEndian::GET_WORD(buffer);					
					phead[i].effnum = 1;
					phead[i].channum = (mp_ubyte)header->channum;
					
					phead[i].patternData = new mp_ubyte[phead[i].rows*header->channum * (phead[i].effnum * 2 + 2)];
					
					// out of memory?
					if (phead[i].patternData == NULL)
					{
						return -7;
					}
					
					memset(phead[i].patternData,0,phead[i].rows*header->channum * (phead[i].effnum * 2 + 2));
					
					mp_ubyte* pattern = buffer+2;
					
					mp_sint32 r,c,cnt = 0;
					mp_sint32 offs = 0;
					for (r = 0; r < phead[i].rows; r++) 
					{
						for (c = 0; c < header->channum;c++) 
						{
							mp_ubyte note = pattern[cnt];
							
							if (note)
								note+=12*3;
							
							mp_ubyte ins = pattern[cnt+1];
							
							if (note)
								ins++;
							else ins = 0;
							
							mp_ubyte eff = pattern[cnt+2];
							mp_ubyte op = pattern[cnt+3];
							
							convertOKTEffects(eff, op);
#ifdef VERBOSE
							if (pattern[cnt+2] && !eff)
							{
								printf("Pattern: %i, %i, %i\n", i, c, r);
							}
#endif
							
							phead[i].patternData[offs] = note;
							phead[i].patternData[offs+1] = ins;
							phead[i].patternData[offs+2] = eff;
							phead[i].patternData[offs+3] = op;
							
							offs+=(phead[i].effnum * 2 + 2);
							
							cnt+=4;
						}
						
					}
					
				}
				else // empty pattern
				{
					phead[i].rows = 64;
					phead[i].effnum = 1;
					phead[i].channum = (mp_ubyte)header->channum;
					
					phead[i].patternData = new mp_ubyte[phead[i].rows*header->channum * (phead[i].effnum * 2 + 2)];
					
					// out of memory?
					if (phead[i].patternData == NULL)
					{
						return -7;
					}
					
					memset(phead[i].patternData,0,phead[i].rows*header->channum * (phead[i].effnum * 2 + 2));
				}
				
				pc++;
				
				break;
			}
			
			case 0x53424F44  :	// 'SBOD'
			{
				f.read(buffer, 4, 1);
				
				mp_sint32 sampLen = BigEndian::GET_DWORD(buffer);
			
				mp_uint32 allocMem = sampLen;
				if (smp[sc].samplen > allocMem)
					allocMem = smp[sc].samplen;
			
				smp[sc].sample = (mp_sbyte*)module->allocSampleMem(allocMem);
				memset(smp[sc].sample, 0, allocMem);
				
				if (smp[sc].sample == NULL)
				{
					return -7;
				}
				
				if (!module->loadSample(f,smp[sc].sample,sampLen,sampLen))
				{
					return -7;
				}
			
				sc++;
			
			}
			
		}
			
	}
	
	strcpy(header->tracker,"Oktalyzer");
	
	module->setDefaultPanning();
	
	module->postProcessSamples();
	
	return 0;
}
Пример #3
0
mp_sint32 LoaderFAR::load(XMFileBase& f, XModule* module)
{
	mp_ubyte buffer[2048];
	
	module->cleanUp();

	// this will make code much easier to read
	TXMHeader*		header = &module->header;
	TXMInstrument*	instr  = module->instr;
	TXMSample*		smp	   = module->smp;
	TXMPattern*		phead  = module->phead;	
	
	// we're already out of memory here
	if (!phead || !instr || !smp)
		return -7;
	
	mp_sint32 i,j;
	
	// read most of the header
	f.read(buffer, 1, 98);
	
	memcpy(header->sig, buffer, 3);
	
	memcpy(header->name, buffer + 4, 32);

	header->freqtab = 1;

	header->mainvol = 255;
	header->tempo = buffer[75];
	header->speed = 80;
	header->tempo = 4;

	header->channum = 16;
	
	char* unpackedSongMessage = new char[LittleEndian::GET_WORD(buffer + 96)];
										
	f.read(unpackedSongMessage, 1, LittleEndian::GET_WORD(buffer + 96));

	mp_sint32 size = LittleEndian::GET_WORD(buffer + 96);
	
	// song message isn't null terminated
	for (i = 0; i < size; i++)
		if (unpackedSongMessage[i] == '\0') unpackedSongMessage[i] = ' ';

	for (i = 0; i < size; i++)
	{
		char line[140];
		memset(line, 0, sizeof(line));
		
		if (size - i >= 131)
		{
			XModule::convertStr(line, unpackedSongMessage+i, 132, false);
			i+=131;
		}
		else
		{
			XModule::convertStr(line, unpackedSongMessage+i, size-i, false);
			i+=size-i;
		}
		module->addSongMessageLine(line);
	}			
	
	delete[] unpackedSongMessage;
	
	f.read(header->ord, 1, 256);
	
	header->patnum = f.readByte();
	header->ordnum = f.readByte();
	header->restart = f.readByte();
	
	mp_uword patSizes[256];
	
	f.readWords(patSizes, 256);
	
	j = LittleEndian::GET_WORD(buffer + 47) - (869 + LittleEndian::GET_WORD(buffer + 96));
	
	for (i = 0; i < j; i++)
		f.readByte();
	
	j = 0;
	for (i = 0; i < 256; i++)
		if (patSizes[i])
			j = i;
			
	header->patnum = j+1;
	
	for (i = 0; i < header->patnum; i++)
	{
		
		if (patSizes[i])
		{
		
			mp_ubyte* pattern = new mp_ubyte[patSizes[i]];
			
			f.read(pattern, 1, patSizes[i]);
			
			// brauch ich des?
			
			mp_sint32 pNumRows = (patSizes[i] - 2) / (16*4);
			
			mp_sint32 numRows = *pattern + 2; // huh?
			
			if (numRows > pNumRows) 
				numRows = pNumRows;
			
			phead[i].rows = numRows;
			phead[i].effnum = 2;
			phead[i].channum = (mp_ubyte)header->channum;
			
			phead[i].patternData = new mp_ubyte[phead[i].rows*header->channum * (phead[i].effnum * 2 + 2)];
			
			// out of memory?
			if (phead[i].patternData == NULL)
			{
				return -7;
			}
			
			memset(phead[i].patternData,0,phead[i].rows*header->channum * (phead[i].effnum * 2 + 2));

			mp_sint32 r,c,cnt = 2;
			mp_sint32 offs = 0;
			for (r=0;r < phead[i].rows; r++) {
				for (c=0;c < header->channum;c++) 
				{
					mp_ubyte note = pattern[cnt];
					mp_ubyte ins = pattern[cnt+1];
					mp_ubyte vol = pattern[cnt+2];
					mp_ubyte eff = pattern[cnt+3] >> 4;
					mp_ubyte op = pattern[cnt+3] & 0x0F;

					if (vol)
					{
						vol = XModule::vol64to255(vol << 2);
					
						phead[i].patternData[offs+2] = 0x0C;
						phead[i].patternData[offs+3] = vol;
					}
					
					if (note)
					{
						note+=12*3;
						ins++;
					}

					phead[i].patternData[offs]=note;
					phead[i].patternData[offs+1]=ins;
					
					eff=0x70;
					op = pattern[cnt+3];
					
					/*switch (eff)
					{
						// porta to note
						case 0x03:
							op <<= 4;
							break;
						
						// retrigger
						case 0x04:
							eff = 0x39;
							break;

						// vibrato depth
						case 0x5: 
							vibDepth[c] = op;
							break;

						// vibrato
						case 0x6: 
							eff = 0x04;
							op = (op<<4)|vibDepth[c];
							break;
							
						// volslide up
						case 0x07:
							eff = 0x0A;
							op<<=4;
							break;
							
						// volslide down
						case 0x08:
							eff = 0x0A;
							break;
							
						// break
						case 0x0B:
							eff = 0x08;
							op <<= 4;
							break;
						
						case 0x00:
							break;
							
						case 0x0f:
							eff = 0x7f;
							break;
							
						default:
							printf("Missing effects %i,%i\n",eff,op);
							eff = op = 0;
					}*/
					
					phead[i].patternData[offs+4]=eff;
					phead[i].patternData[offs+5]=op;
					
					offs+=(phead[i].effnum * 2 + 2);
					
					cnt+=4;
				}
			}
			
			
			delete[] pattern;
		}
		
	}
		
	char sampleMap[8];
	
	f.read(sampleMap, 1, 8);
	
	j = 0;
	for (i = 0; i < 64; i++)
		if (sampleMap[i>>3]&(1<<(i&7))) 
			j = i+1;
			
	header->insnum = j;       
		
	mp_sint32 s = 0;
	for (i = 0; i < header->insnum; i++)
	{
		if (sampleMap[i>>3]&(1<<(i&7))) 
		{
			instr[i].samp = 1;
			for (j = 0; j < 120; j++) 
				instr[i].snum[j] = s;

			f.read(instr[i].name, 1, 32);
			
			memcpy(smp[s].name, instr[i].name, 32);
			
			mp_sint32 size = f.readDword();
			mp_ubyte finetune = f.readByte();
			mp_sint32 volume = f.readByte() << 4;
			if (volume>255) volume = 255;
			mp_sint32 repstart = f.readDword();
			mp_sint32 repend = f.readDword();
			mp_ubyte type = f.readByte();
			mp_ubyte flags = f.readByte();

			smp[s].vol = volume;
			smp[s].flags = 1;
			smp[s].samplen = size;
			smp[s].loopstart = repstart;
			mp_sint32 looplen = (repend - repstart);
			if (looplen < 0) 
				looplen = 0;
			smp[s].looplen = looplen;
			
			if (flags & 8)
				smp[s].type = 1;
			
			if (type & 1)
			{
				smp[s].type |= 16;

				smp[s].samplen >>= 1;
				smp[s].loopstart >>=1;
				smp[s].looplen >>=1;
			}
			
			if (module->loadModuleSample(f, s) != 0)
				return -7;
			
			s++;
		}
	}
Пример #4
0
mp_sint32 LoaderCBA::load(XMFileBase& f, XModule* module)
{
	module->cleanUp();

	// this will make code much easier to read
	TXMHeader*		header = &module->header;
	TXMInstrument*	instr  = module->instr;
	TXMSample*		smp	   = module->smp;
	TXMPattern*		phead  = module->phead;	
	
	// we're already out of memory here
	if (!phead || !instr || !smp)
		return MP_OUT_OF_MEMORY;
	
	f.read(header->sig, 1, 3);
	f.readByte();   // skip 0xF9
	
	f.read(header->name, 1, 32);
	
	f.readByte();   // skip 0x1A
	
	mp_sint32 songMsgLen = f.readWord();

	header->channum = f.readByte();
	header->patnum = f.readByte()+1; // number of patterns
	header->ordnum = f.readByte(); // song length
	header->insnum = f.readByte(); // number of instruments
	header->tempo = f.readByte();	// default tickspeed
	header->speed = f.readByte();	// default tempo
	header->flags = XModule::MODULE_ST3NEWINSTRUMENT;
	header->mainvol = 255;
	
	f.read(header->pan, 1, 32);

	f.read(header->ord, 1, 255);
	
	mp_sint32 i, s = 0;
	for (i = 0; i < header->insnum; i++) 
	{		
		mp_ubyte name[32];
		mp_ubyte flags;
		mp_ubyte vol;
		mp_uword c4spd;
		mp_sint32 len;
		mp_sint32 loopstart;
		mp_sint32 loopend;
		f.read(name, 1, 32);
		flags = f.readByte();
		vol = f.readByte();
		c4spd = f.readWord();
		
		len = f.readDword();
		loopstart = f.readDword();
		loopend = f.readDword();

		memcpy(instr[i].name, name, 32);
		
		if ((flags & 0x02) && len)
		{
			instr[i].samp = 1;
		
			memcpy(smp[s].name, name, 32);
		
			for (mp_sint32 j = 0; j < 120; j++) 
				instr[i].snum[j] = s;			
		
			smp[s].flags = 1;
			smp[s].samplen = len;
			
			mp_sint32 looplen = (loopend - loopstart);
			if (looplen < 0) 
				looplen = 0;
			smp[s].looplen = looplen;
			
			smp[s].loopstart = loopstart;
			smp[s].vol = XModule::vol64to255(vol);
			
			if (flags & 0x08)
				smp[s].type = 1;
			
			XModule::convertc4spd(c4spd, &smp[s].finetune, &smp[s].relnote);			
			
			s++;
		}
	}
	
	header->smpnum = s;
	
	mp_ubyte* pattern = new mp_ubyte[header->channum*64*5];
	if (pattern == NULL)
		return MP_OUT_OF_MEMORY;
	
	for (i = 0; i < header->patnum;i++) 
	{

		f.read(pattern, 1, header->channum*64*5);
		
		phead[i].rows = 64;
		phead[i].effnum = 2;
		phead[i].channum = (mp_ubyte)header->channum;
		
		phead[i].patternData = new mp_ubyte[phead[i].rows*header->channum * (phead[i].effnum * 2 + 2)];
		
		// out of memory?
		if (phead[i].patternData == NULL)
		{
			delete[] pattern;
			return MP_OUT_OF_MEMORY;
		}
		
		memset(phead[i].patternData,0,phead[i].rows*header->channum * (phead[i].effnum * 2 + 2));
		
		mp_sint32 r,c,cnt = 0;
		mp_sint32 offs = 0;
		for (r=0; r < 64; r++) {
			for (c = 0; c < header->channum; c++) {
				mp_ubyte ins = pattern[cnt];
				mp_ubyte note = pattern[cnt+1];
				mp_ubyte vol = pattern[cnt+2];
				mp_ubyte eff = pattern[cnt+3];
				mp_ubyte op = pattern[cnt+4];
				
				if (note == 255)
					note = 122;
				
				phead[i].patternData[offs] = note;
				phead[i].patternData[offs+1] = ins;
				
				if (vol)
				{
					phead[i].patternData[offs+2] = 0x0C;
					phead[i].patternData[offs+3] = XModule::vol64to255(vol-1);
				}

				convertEffect(eff, op);
#ifdef VERBOSE
				if (eff == 0 && pattern[cnt+3])
				{
					printf("pattern: %i, row: %i, channel %i: %x, %x\n", i, r, c, pattern[cnt+3], pattern[cnt+4]);
				}
#endif								
				
				phead[i].patternData[offs+4] = eff;
				phead[i].patternData[offs+5] = op;
				
				cnt+=5;
				offs+=(phead[i].effnum * 2 + 2);
			}
		}
		
	}
	
	delete[] pattern;
	
	mp_sint32 result = module->loadModuleSamples(f, XModule::ST_DELTA);
	if (result != MP_OK)
		return result;

	module->allocateSongMessage(songMsgLen+1);
			
	if (module->message)	
	{
		memset(module->message, 0, songMsgLen+1);
		f.read(module->message, 1, songMsgLen);
	}
	
	strcpy(header->tracker,"..converted..");
	
	//module->setDefaultPanning();
	
	module->postProcessSamples();
	
	return MP_OK;
}