Example #1
0
CPLoader::Error CPLoader_S3M::load_sample(CPSample *p_sample) {

	int type = file->get_byte();

	char filename[13];
	file->get_byte_array((uint8_t *)filename, 12);
	filename[12] = 0;

	uint32_t samplepos = (uint32_t)file->get_byte() << 16;
	samplepos |= file->get_word();
	samplepos *= 16;
	//		printf("sample at %i\n",samplepos);
	/**/
	int sample_size = file->get_dword();

	int loop_begin = file->get_dword();
	int loop_end = file->get_dword();

	int def_volume = file->get_byte();
	;
	int dsk = file->get_byte();
	int pack = file->get_byte();

	int flags = file->get_byte();
	int c2speed = file->get_dword();

	file->get_dword(); //useless crap
	file->get_dword();
	file->get_dword();

	char name[29];
	file->get_byte_array((uint8_t *)name, 28);
	name[28] = 0;

	p_sample->set_default_volume(def_volume);
	p_sample->set_name(name);

	char scrs[5];
	file->get_byte_array((uint8_t *)scrs, 4);
	scrs[4] = 0;

	bool data_is_16bits = flags & 4;
	bool data_is_stereo = flags & 2;

	if (type == 0) {
		//empty sample
		return FILE_OK;
	}

	if ((type != 1) || scrs[0] != 'S' || scrs[1] != 'C' || scrs[2] != 'R' || scrs[3] != 'S') {
		//			printf("type: %i, %c%c%c%c\n",type,scrs[0],scrs[1],scrs[2],scrs[3]);
		CP_PRINTERR("Not an S3M CPSample!");
		return FILE_CORRUPTED;
	}

	//p_sample->data.set_c5_freq(p_sample->c2spd<<1);

	file->seek(samplepos);

	int real_sample_size = sample_size << BITBOOL(data_is_16bits);
	real_sample_size <<= BITBOOL(data_is_stereo);

	CPSampleManager *sm = CPSampleManager::get_singleton();

	CPSample_ID id = sm->create(data_is_16bits, data_is_stereo, sample_size);

	if (id.is_null())
		return FILE_OUT_OF_MEMORY;

	sm->lock_data(id);
	void *dataptr = sm->get_data(id);

	int chans = (data_is_stereo ? 2 : 1);
	for (int c = 0; c < chans; c++) {
		for (int i = 0; i < sample_size; i++) {

			if (data_is_16bits) {

				uint16_t s = file->get_word();
				s -= 32768; //toggle sign

				int16_t *v = (int16_t *)&s;
				((int16_t *)dataptr)[i * chans + c] = *v;
			} else {

				int8_t *v;
				uint8_t s = file->get_byte();
				s -= 128; //toggle sign
				v = (int8_t *)&s;
				((int8_t *)dataptr)[i * chans + c] = *v;
			}
		}
	}

	sm->unlock_data(id);

	sm->set_loop_begin(id, loop_begin);
	sm->set_loop_end(id, loop_end);
	sm->set_loop_type(id, (flags & 1) ? CP_LOOP_FORWARD : CP_LOOP_NONE);
	sm->set_c5_freq(id, c2speed << 1);
	p_sample->set_sample_data(id);

	/* Scream tracker previous to 3.10 seems to be buggy, as in, wont save what is after the sample loop, including the loop end point. Because of this I must fix it by habd */
	if (flags & 1) {

		for (int c = 0; c < (data_is_stereo ? 2 : 1); c++) {
			sm->set_data(id, loop_end, sm->get_data(id, loop_begin, c), c);
		}
	}

	return FILE_OK;
}
CPLoader::Error CPLoader_IT::load_instrument(CPInstrument *p_instrument,int *p_samples) {



	char aux_header[4];
	
	file->get_byte_array((uint8_t*)aux_header,4);	

	
	if (	aux_header[0]!='I' ||
		       aux_header[1]!='M' ||
		       aux_header[2]!='P' ||
		       aux_header[3]!='I') {
		CP_PRINTERR("IT CPLoader CPInstrument: Failed Identifier");
	
		return FILE_UNRECOGNIZED;
	}
		
	

	// Ignore deprecated 8.3 filename field
	for (int i=0;i<12;i++) file->get_byte();
	
	//Ignore zerobyte
	file->get_byte();		/* (byte) CPInstrument type (always 0) */
	
	switch( file->get_byte() ) { /* New CPNote Action [0,1,2,3] */
		case 0: p_instrument->set_NNA_type( CPInstrument::NNA_NOTE_CUT ) ; break;
		case 1: p_instrument->set_NNA_type( CPInstrument::NNA_NOTE_CONTINUE ) ; break;
		case 2: p_instrument->set_NNA_type( CPInstrument::NNA_NOTE_OFF ) ; break;
		case 3: p_instrument->set_NNA_type( CPInstrument::NNA_NOTE_FADE ) ; break;
	};
	switch( file->get_byte() ) { // Duplicate Check Type
		case 0: p_instrument->set_DC_type( CPInstrument::DCT_DISABLED ); break ;		
		case 1: p_instrument->set_DC_type( CPInstrument::DCT_NOTE ); break ;		
		case 2: p_instrument->set_DC_type( CPInstrument::DCT_SAMPLE ); break ;		
		case 3: p_instrument->set_DC_type( CPInstrument::DCT_INSTRUMENT ); break ;		
	}
	switch( file->get_byte() ) { //Duplicate Check Action
		case 0: p_instrument->set_DC_action( CPInstrument::DCA_NOTE_CUT ); break ;
		case 1: p_instrument->set_DC_action( CPInstrument::DCA_NOTE_OFF ); break ;
		case 2: p_instrument->set_DC_action( CPInstrument::DCA_NOTE_FADE ); break ;
	}
	
	int fade = file->get_word();
	//intf("AFADE: %i\n",fade);
	if (fade>CPInstrument::MAX_FADEOUT) //needs to be clipped because of horrible modplug doings
		fade=CPInstrument::MAX_FADEOUT;
	
	p_instrument->set_volume_fadeout( fade );
	p_instrument->set_pan_pitch_separation( file->get_byte() );
	p_instrument->set_pan_pitch_center( file->get_byte() );
	p_instrument->set_volume_global_amount( file->get_byte() );
	uint8_t pan=file->get_byte();
	p_instrument->set_pan_default_amount(pan&0x7F);
	p_instrument->set_pan_default_enabled( !(pan&0x80) );
	p_instrument->set_volume_random_variation( file->get_byte() );
	p_instrument->set_pan_random_variation( file->get_byte() );
	
	
	
	file->get_word(); //empty (version)
	uint8_t samples=file->get_byte();
	if (p_samples)
		*p_samples=samples;
	file->get_byte(); //empty
	char aux_name[26];	
	file->get_byte_array((uint8_t*)aux_name,26);
	p_instrument->set_name(aux_name);
	
	uint8_t cutoff=file->get_byte();
		
	p_instrument->set_filter_default_cutoff(cutoff&0x7F);
	p_instrument->set_filter_use_default_cutoff(cutoff&0x80); 
	
	uint8_t resonance=file->get_byte();
		
	p_instrument->set_filter_default_resonance(resonance&0x7F);
	p_instrument->set_filter_use_default_resonance(resonance&0x80); 
	
	file->get_dword(); //MIDI, IGNORED!
	
	/* CPNote -> CPSample table */
	for (uint8_t i=0;i<CPNote::NOTES;i++) {
		
		
		uint8_t note=file->get_byte();
		if (note>=CPNote::NOTES)
			note=0;
		p_instrument->set_note_number(i,note);		
		
		uint8_t samp=file->get_byte();
		if (samp==0 || samp>99)
			samp=CPNote::EMPTY;
		else 
			samp--;
		
		
		p_instrument->set_sample_number(i,samp);
	

	}

	
	load_envelope( p_instrument->get_volume_envelope() );
	load_envelope( p_instrument->get_pan_envelope() );
	bool use_as_filter;
	load_envelope( p_instrument->get_pitch_filter_envelope(), &use_as_filter );
	p_instrument->set_pitch_use_as_filter( use_as_filter );

	return FILE_OK;

}