[Scummvm-cvs-logs] CVS: scummvm/scumm resource.cpp,1.115,1.116 scumm.h,1.277,1.278 scummvm.cpp,2.308,2.309 sound.cpp,1.191,1.192

Travis Howell kirben at users.sourceforge.net
Mon Aug 4 22:22:05 CEST 2003


Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1:/tmp/cvs-serv29526/scumm

Modified Files:
	resource.cpp scumm.h scummvm.cpp sound.cpp 
Log Message:

Add adlib music improvements for indy3/monkeyega/monkeyvga and cleanups from patch #770862


Index: resource.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/resource.cpp,v
retrieving revision 1.115
retrieving revision 1.116
diff -u -d -r1.115 -r1.116
--- resource.cpp	28 Jul 2003 16:55:05 -0000	1.115
+++ resource.cpp	5 Aug 2003 05:21:56 -0000	1.116
@@ -649,7 +649,6 @@
 		size = _fileHandle.readUint32LE();
 		tag = _fileHandle.readUint16LE();
 		_fileHandle.seek(-6, SEEK_CUR);
-		/* FIXME */
 		if ((type == rtSound) && !(_features & GF_AMIGA) && !(_features & GF_FMTOWNS)) {
 			return readSoundResourceSmallHeader(type, idx);
 		}
@@ -889,371 +888,296 @@
 	return 0;
 }
 
-// FIXME: some default MIDI instruments for INDY3/MI1
-static char OLD256_MIDI_HACK[] =
-	// 0
-	"\x00\xf0\x14\x7d\x00"  // sysex 00: part on/off
-	"\x00\x00\x03"          // part/channel
-	"\x00\x00\x07\x0f\x00\x00\x08\x00\x00\x00\x00\x02\x00\x00\xf7"
-	"\x04\xf0\x41\x7d\x10"  // sysex 16: set instrument
-	"\x00"                  // part/channel
-	"\x01\x06\x02\x0a\x08\x09\x0d\x08\x04\x04"
-	"\x04\x06\x02\x02\x03\x07\x0f\x0d"
-	"\x05\x04\x0c\x00\x03\x01\x01\x00"
-	"\x00\x00\x01\x01\x0e\x00\x02\x02"
-	"\x01\x00\x01\x00\x01\x02\x00\x01"
-	"\x08\x00\x00\x00\x01\x02\x04\x00"
-	"\x06\x02\x00\x00\x04\x00\x03\x02"
-	"\x04\x00\x00\xf7"
-	"\x00\xb0\x07\x64"      // Controller 7 = 100
-	// 1
-	"\x00\xf0\x14\x7d\x00"  // sysex 00: part on/off
-	"\x01\x00\x03"          // part/channel
-	"\x00\x00\x07\x0f\x00\x00\x08\x00\x00\x00\x00\x02\x00\x00\xf7"
-	"\x04\xf0\x41\x7d\x10"  // sysex 16: set instrument
-	"\x01"                  // part/channel
-	"\x01\x06\x02\x0a\x08\x09\x0d\x08\x04\x04"
-	"\x04\x06\x02\x02\x03\x07\x0f\x0d"
-	"\x05\x04\x0c\x00\x03\x01\x01\x00"
-	"\x00\x00\x01\x01\x0e\x00\x02\x02"
-	"\x01\x00\x01\x00\x01\x02\x00\x01"
-	"\x08\x00\x00\x00\x01\x02\x04\x00"
-	"\x06\x02\x00\x00\x04\x00\x03\x02"
-	"\x04\x00\x00\xf7"
-	"\x00\xb1\x07\x64"      // Controller 7 = 100
-	// 2
-	"\x00\xf0\x14\x7d\x00"  // sysex 00: part on/off
-	"\x02\x00\x03"          // part/channel
-	"\x00\x00\x07\x0f\x00\x00\x08\x00\x00\x00\x00\x02\x00\x00\xf7"
-	"\x04\xf0\x41\x7d\x10"  // sysex 16: set instrument
-	"\x02"                  // part/channel
-	"\x01\x06\x02\x0a\x08\x09\x0d\x08\x04\x04"
-	"\x04\x06\x02\x02\x03\x07\x0f\x0d"
-	"\x05\x04\x0c\x00\x03\x01\x01\x00"
-	"\x00\x00\x01\x01\x0e\x00\x02\x02"
-	"\x01\x00\x01\x00\x01\x02\x00\x01"
-	"\x08\x00\x00\x00\x01\x02\x04\x00"
-	"\x06\x02\x00\x00\x04\x00\x03\x02"
-	"\x04\x00\x00\xf7"
-	"\x00\xb2\x07\x64"      // Controller 7 = 100
-	// 3
-	"\x00\xf0\x14\x7d\x00"  // sysex 00: part on/off
-	"\x03\x00\x03"          // part/channel
-	"\x00\x00\x07\x0f\x00\x00\x08\x00\x00\x00\x00\x02\x00\x00\xf7"
-	"\x04\xf0\x41\x7d\x10"  // sysex 16: set instrument
-	"\x03"                  // part/channel
-	"\x01\x06\x02\x0a\x08\x09\x0d\x08\x04\x04"
-	"\x04\x06\x02\x02\x03\x07\x0f\x0d"
-	"\x05\x04\x0c\x00\x03\x01\x01\x00"
-	"\x00\x00\x01\x01\x0e\x00\x02\x02"
-	"\x01\x00\x01\x00\x01\x02\x00\x01"
-	"\x08\x00\x00\x00\x01\x02\x04\x00"
-	"\x06\x02\x00\x00\x04\x00\x03\x02"
-	"\x04\x00\x00\xf7"
-	"\x00\xb3\x07\x64"      // Controller 7 = 100
-	// 4
-	"\x00\xf0\x14\x7d\x00"  // sysex 00: part on/off
-	"\x04\x00\x03"          // part/channel
-	"\x00\x00\x07\x0f\x00\x00\x08\x00\x00\x00\x00\x02\x00\x00\xf7"
-	"\x04\xf0\x41\x7d\x10"  // sysex 16: set instrument
-	"\x04"                  // part/channel
-	"\x01\x06\x02\x0a\x08\x09\x0d\x08\x04\x04"
-	"\x04\x06\x02\x02\x03\x07\x0f\x0d"
-	"\x05\x04\x0c\x00\x03\x01\x01\x00"
-	"\x00\x00\x01\x01\x0e\x00\x02\x02"
-	"\x01\x00\x01\x00\x01\x02\x00\x01"
-	"\x08\x00\x00\x00\x01\x02\x04\x00"
-	"\x06\x02\x00\x00\x04\x00\x03\x02"
-	"\x04\x00\x00\xf7"
-	"\x00\xb4\x07\x64"      // Controller 7 = 100
-	// 5
-	"\x00\xf0\x14\x7d\x00"  // sysex 00: part on/off
-	"\x05\x00\x03"          // part/channel
-	"\x00\x00\x07\x0f\x00\x00\x08\x00\x00\x00\x00\x02\x00\x00\xf7"
-	"\x04\xf0\x41\x7d\x10"  // sysex 16: set instrument
-	"\x05"                  // part/channel
-	"\x01\x06\x02\x0a\x08\x09\x0d\x08\x04\x04"
-	"\x04\x06\x02\x02\x03\x07\x0f\x0d"
-	"\x05\x04\x0c\x00\x03\x01\x01\x00"
-	"\x00\x00\x01\x01\x0e\x00\x02\x02"
-	"\x01\x00\x01\x00\x01\x02\x00\x01"
-	"\x08\x00\x00\x00\x01\x02\x04\x00"
-	"\x06\x02\x00\x00\x04\x00\x03\x02"
-	"\x04\x00\x00\xf7"
-	"\x00\xb5\x07\x64"      // Controller 7 = 100
-	// 6
-	"\x00\xf0\x14\x7d\x00"  // sysex 00: part on/off
-	"\x06\x00\x03"          // part/channel
-	"\x00\x00\x07\x0f\x00\x00\x08\x00\x00\x00\x00\x02\x00\x00\xf7"
-	"\x04\xf0\x41\x7d\x10"  // sysex 16: set instrument
-	"\x06"                  // part/channel
-	"\x01\x06\x02\x0a\x08\x09\x0d\x08\x04\x04"
-	"\x04\x06\x02\x02\x03\x07\x0f\x0d"
-	"\x05\x04\x0c\x00\x03\x01\x01\x00"
-	"\x00\x00\x01\x01\x0e\x00\x02\x02"
-	"\x01\x00\x01\x00\x01\x02\x00\x01"
-	"\x08\x00\x00\x00\x01\x02\x04\x00"
-	"\x06\x02\x00\x00\x04\x00\x03\x02"
-	"\x04\x00\x00\xf7"
-	"\x00\xb6\x07\x64"      // Controller 7 = 100
-	// 7
-	"\x00\xf0\x14\x7d\x00"  // sysex 00: part on/off
-	"\x07\x00\x03"          // part/channel
-	"\x00\x00\x07\x0f\x00\x00\x08\x00\x00\x00\x00\x02\x00\x00\xf7"
-	"\x04\xf0\x41\x7d\x10"  // sysex 16: set instrument
-	"\x07"                  // part/channel
-	"\x01\x06\x02\x0a\x08\x09\x0d\x08\x04\x04"
-	"\x04\x06\x02\x02\x03\x07\x0f\x0d"
-	"\x05\x04\x0c\x00\x03\x01\x01\x00"
-	"\x00\x00\x01\x01\x0e\x00\x02\x02"
-	"\x01\x00\x01\x00\x01\x02\x00\x01"
-	"\x08\x00\x00\x00\x01\x02\x04\x00"
-	"\x06\x02\x00\x00\x04\x00\x03\x02"
-	"\x04\x00\x00\xf7"
-	"\x00\xb7\x07\x64";     // Controller 7 = 100
-
-int Scumm::readSoundResourceSmallHeader(int type, int idx) {
-	uint32 pos, total_size, size, dw, tag;
-	uint32 best_size = 0, best_offs = 0;
+// Adlib MIDI-SYSEX to set MIDI instruments for small header games.
+static byte ADLIB_INSTR_MIDI_HACK[95] = {
+	0x00, 0xf0, 0x14, 0x7d, 0x00,  // sysex 00: part on/off
+	0x00, 0x00, 0x03,              // part/channel  (offset  5)
+	0x00, 0x00, 0x07, 0x0f, 0x00, 0x00, 0x08, 0x00, 
+	0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xf7,
+	0x04, 0xf0, 0x41, 0x7d, 0x10,  // sysex 16: set instrument
+	0x00,                          // part/channel  (offset 28)
+	0x01, 0x06, 0x02, 0x0a, 0x08, 0x09, 0x0d, 0x08, 0x04, 0x04,
+	0x04, 0x06, 0x02, 0x02, 0x03, 0x07, 0x0f, 0x0d,
+	0x05, 0x04, 0x0c, 0x00, 0x03, 0x01, 0x01, 0x00,
+	0x00, 0x00, 0x01, 0x01, 0x0e, 0x00, 0x02, 0x02,
+	0x01, 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x01,
+	0x08, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00,
+	0x06, 0x02, 0x00, 0x00, 0x04, 0x00, 0x03, 0x02,
+	0x04, 0x00, 0x00, 0xf7,
+	0x00, 0xb0, 0x07, 0x64        // Controller 7 = 100 (offset 92)
+};
+			
+int Scumm::convertADResource(int type, int idx, byte * src_ptr, int size) {
 
-	debug(4, "readSoundResourceSmallHeader(%s,%d)", resTypeFromId(type), idx);
+	byte * ptr;
+	byte ticks, play_once;
+	byte music_type, num_instr;
+	byte *channel, *instr, *track;
+	int i, ch;
+	
+	src_ptr += 2;
+	size -= 2;
+	music_type = *(src_ptr);	// 0x80: is music; otherwise not.
+	if (music_type != 0x80) {
+		// It's an SFX; we don't know how to handle those yet
+		debug(4, "Sound %d not played, format not yet supported", idx);
+		nukeResource(type, idx);
+		res.roomoffs[type][idx] = 0xFFFFFFFF;
+		return 0;
+	}
 
-	//if (_rescache->readResource(roomNr, type, idx))
-	//		return 1;
+	// The "speed" of the song
+	ticks = *(src_ptr + 1);
+	
+	// Flag that tells us whether we should loop the song (0) or play it only once (1)
+	play_once = *(src_ptr + 2);
+	
+	// Number of instruments used
+	num_instr = *(src_ptr + 8);	// Normally 8
+	
+	// copy the pointer to instrument data
+	channel = src_ptr + 9;
+	instr   = src_ptr + 0x11;
 
-	total_size = size = _fileHandle.readUint32LE();
-	tag = _fileHandle.readUint16LE();
-	debug(4, "  tag='%c%c', size=%d",
-					(char) (tag & 0xff),
-					(char) ((tag >> 8) & 0xff), size);
+	// skip over the rest of the header and copy the MIDI data into a buffer
+	src_ptr  += 0x11 + 8 * 16;
+	size -= 0x11 + 8 * 16;
 
-	pos = 6;
-	while (pos < total_size) {
-		size = _fileHandle.readUint32LE();
-		tag = _fileHandle.readUint16LE();
-		debug(4, "  tag='%c%c', size=%d",
-					(char) (tag & 0xff),
-					(char) ((tag >> 8) & 0xff), size);
-		pos += size;
+	CHECK_HEAP 
+			
+	track = src_ptr;
+			
+	int total_size = 8 + 16 + 14 + 8 + 7 + 8*sizeof(ADLIB_INSTR_MIDI_HACK) + size;
+	total_size += 24;	// Up to 24 additional bytes are needed for the jump sysex
 
-		// MI1 and Indy3 uses one or more nested SO resources, which contains AD and WA
-		// resources.
-		if ((tag == 0x4441) && !(best_offs)) { // AD
-				best_size = size;
-				best_offs = _fileHandle.pos();
-		} else { // other AD, WA and nested SO resources
-			if (tag == 0x4F53) {
-				pos -= size;
-				size = 6;
-				pos += 6;
-			}
-		}
-		_fileHandle.seek(size - 6, SEEK_CUR);
-	}
+	ptr = createResource(type, idx, total_size);
+	memcpy(ptr, "ADL ", 4); ptr += 4;
+	uint32 dw = READ_BE_UINT32(&total_size);
+	memcpy(ptr, &dw, 4); ptr += 4;
+	memcpy(ptr, "MDhd", 4); ptr += 4;
+	ptr[0] = 0; ptr[1] = 0; ptr[2] = 0; ptr[3] = 8;
+	ptr += 4;
+	memset(ptr, 0, 8), ptr += 8;
+	memcpy(ptr, "MThd", 4); ptr += 4;
+	ptr[0] = 0; ptr[1] = 0; ptr[2] = 0; ptr[3] = 6;
+	ptr += 4;
+	ptr[0] = 0; ptr[1] = 0; ptr[2] = 0; ptr[3] = 1; // MIDI format 0 with 1 track
+	ptr += 4;
+	
+	// We will ignore the PPQN in the original resource, because
+	// it's invalid anyway. We use a constant PPQN of 480.
+	// memcpy(ptr, &ticks, 2); ptr += 2;
+	*ptr++ = 480 >> 8;
+	*ptr++ = 480 & 0xFF;
+	
+	memcpy(ptr, "MTrk", 4); ptr += 4;
+	dw = READ_BE_UINT32(&total_size);
+	memcpy(ptr, &dw, 4); ptr += 4;
 
-	// AD resources have a header, instrument definitions and one MIDI track.
-	// We build an 'ADL ' resource from that:
-	//   8 bytes resource header
-	//  16 bytes MDhd header
-	//  14 bytes MThd header
-	//   8 bytes MTrk header
-	//   7 bytes MIDI tempo sysex
-	//     + some default instruments
-	// TODO:  - make some real MIDI instrument definitions
-	//        - proper handling of the short (non-music, SFX) AD resources format
-	//        - check the LE/BE handling for platforms other than PC
+	// Conver the ticks into a MIDI tempo. 
+	dw = (500000 * 256) / ticks;
+	debug(4, "  ticks = %d, speed = %ld", ticks, dw);
+	
+	// Write a tempo change SysEx
+	memcpy(ptr, "\x00\xFF\x51\x03", 4); ptr += 4;
+	*ptr++ = (byte)((dw >> 16) & 0xFF);
+	*ptr++ = (byte)((dw >> 8) & 0xFF);
+	*ptr++ = (byte)(dw & 0xFF);
+		
+	// Copy our hardcoded instrument table into it
+	// Then, convert the instrument table as given in this song resource
+	// And write it *over* the hardcoded table.
+	// Note: we deliberately.
 
-	if (best_offs != 0) {
-		byte *ptr, *track, *instr;
-		byte ticks, play_once;
-		byte music_type, num_instr;
+	/* now fill in the instruments */
+	for (i = 0; i < num_instr; i++) {
+		ch = channel[i] - 1;
 
-		_fileHandle.seek(best_offs - 6, SEEK_SET);
+		debug(4, "Sound %d: instrument %d on channel %d.", 
+			  idx, i, ch);
 
-		ptr = createResource(type, idx, best_size);
-		_fileHandle.read(ptr, best_size);
+	    memcpy(ptr, ADLIB_INSTR_MIDI_HACK, 
+			   sizeof(ADLIB_INSTR_MIDI_HACK));
 
-		music_type = *(ptr + 8);	// 0x80: is music; otherwise not.
+		ptr[5]  += ch;
+		ptr[28] += ch;
+		ptr[92] += ch;
+	
+		/* flags_1 */
+		ptr[30 + 0] = (instr[i * 16 + 3] >> 4) & 0xf;
+		ptr[30 + 1] = instr[i * 16 + 3] & 0xf;
 		
-		if (music_type != 0x80) {
-			// It's an SFX; we don't know how to handle those yet
-			debug(4, "Sound %d not played, format not yet supported", idx);
-			nukeResource(type, idx);
-			res.roomoffs[type][idx] = 0xFFFFFFFF;
-			return 0;
-		}
+		/* oplvl_1 */
+		ptr[30 + 2] = (instr[i * 16 + 4] >> 4) & 0xf;
+		ptr[30 + 3] = instr[i * 16 + 4] & 0xf;
 		
-		// The "speed" of the song
-		ticks = *(ptr + 9);
+		/* atdec_1 */
+		ptr[30 + 4] = ((~instr[i * 16 + 5]) >> 4) & 0xf;
+		ptr[30 + 5] = (~instr[i * 16 + 5]) & 0xf;
 		
-		// Flag that tells us whether we should loop the song (0) or play it only once (1)
-		play_once = *(ptr + 10);
+		/* sustrel_1 */
+		ptr[30 + 6] = ((~instr[i * 16 + 6]) >> 4) & 0xf;
+		ptr[30 + 7] = (~instr[i * 16 + 6]) & 0xf;
 		
-		// Number of instruments used
-		num_instr = *(ptr + 16);	// Normally 8
-		if (num_instr != 8)
-			warning("Sound %d has %d instruments, expected 8", idx, num_instr);
-
-		// copy the instrument data in another memory area
-		instr = (byte *)calloc(8 * 16, 1);
-		assert(instr);
-		memcpy(instr, ptr + 0x19, 8*16);
-
-		// skip over the rest of the header and copy the MIDI data into a buffer
-		size = best_size;
-		ptr  += 0x19 + 8 * 16;
-		size -= 0x19 + 8 * 16;
-		CHECK_HEAP 
-		track = (byte *)calloc(size, 1);
-		if (track == NULL) {
-			error("Out of memory while allocating %d", size);
+		/* waveform_1 */
+		ptr[30 + 8] = (instr[i * 16 + 7] >> 4) & 0xf;
+		ptr[30 + 9] = instr[i * 16 + 7] & 0xf;
+		
+		/* flags_2 */
+		ptr[30 + 10] = (instr[i * 16 + 8] >> 4) & 0xf;
+		ptr[30 + 11] = instr[i * 16 + 8] & 0xf;
+		
+		/* oplvl_2 */
+		ptr[30 + 12] = (instr[i * 16 + 9] >> 4) & 0xf;
+		ptr[30 + 13] = instr[i * 16 + 9] & 0xf;
+		
+		/* atdec_2 */
+		ptr[30 + 14] = ((~instr[i * 16 + 10]) >> 4) & 0xf;
+		ptr[30 + 15] = (~instr[i * 16 + 10]) & 0xf;
+		
+		/* sustrel_2 */
+		ptr[30 + 16] = ((~instr[i * 16 + 11]) >> 4) & 0xf;
+		ptr[30 + 17] = (~instr[i * 16 + 11]) & 0xf;
+		
+		/* waveform_2 */
+		ptr[30 + 18] = (instr[i * 16 + 12] >> 4) & 0xf;
+		ptr[30 + 19] = instr[i * 16 + 12] & 0xf;
+		
+		/* feedback */
+		ptr[30 + 20] = (instr[i * 16 + 2] >> 4) & 0xf;
+		ptr[30 + 21] = instr[i * 16 + 2] & 0xf;
+		ptr += sizeof(ADLIB_INSTR_MIDI_HACK);
+	}
+	
+	*ptr++ = 0;  // delay 0;
+	
+	// Now copy the actual music data 
+	memcpy(ptr, track, size);
+	ptr += size;
+	
+	if (!play_once) {
+		// The song is meant to be looped. We achieve this by inserting just
+		// before the song end a jump to the song start. More precisely we abuse
+		// a S&M sysex, "maybe_jump" to achieve this effect. We could also
+		// use a set_loop sysex, but it's a bit longer, a little more complicated,
+		// and has no advantage either.
+		
+		// First, find the track end
+		byte *end = ptr;
+		ptr -= size;
+		for (; ptr < end; ptr++) {
+			if (*ptr == 0xff && *(ptr + 1) == 0x2f)
+				break;
 		}
-		memcpy(track, ptr, size);         // saving MIDI track data
-
-		// Now nuke the old resource, and replace it with a new one
-		nukeResource(type, idx);
-		total_size = 8 + 16 + 14 + 8 + 7 + sizeof(OLD256_MIDI_HACK) + size;
-		if (!play_once)
-			total_size += 24;	// Up to 24 additional bytes are needed for the jump sysex
-
-		// Write the ADL header (see also above for more information)
-		ptr = createResource(type, idx, total_size);
-		memcpy(ptr, "ADL ", 4); ptr += 4;
-		dw = READ_BE_UINT32(&total_size);
-		memcpy(ptr, &dw, 4); ptr += 4;
-		memcpy(ptr, "MDhd", 4); ptr += 4;
-		ptr[0] = 0; ptr[1] = 0; ptr[2] = 0; ptr[3] = 8;
-		ptr += 4;
-		memset(ptr, 0, 8); ptr += 8;
-		memcpy(ptr, "MThd", 4); ptr += 4;
-		ptr[0] = 0; ptr[1] = 0; ptr[2] = 0; ptr[3] = 6;
-		ptr += 4;
-		ptr[0] = 0; ptr[1] = 0; ptr[2] = 0; ptr[3] = 1; // MIDI format 0 with 1 track
-		ptr += 4;
-
-		// We will ignore the PPQN in the original resource, because
-		// it's invalid anyway. We use a constant PPQN of 480.
-		// memcpy(ptr, &ticks, 2); ptr += 2;
-		*ptr++ = 480 >> 8;
-		*ptr++ = 480 & 0xFF;
-
-		memcpy(ptr, "MTrk", 4); ptr += 4;
-		*ptr++ = (byte)(((sizeof(OLD256_MIDI_HACK) + size + 7) >> 24) & 0xFF);
-		*ptr++ = (byte)(((sizeof(OLD256_MIDI_HACK) + size + 7) >> 16) & 0xFF);
-		*ptr++ = (byte)(((sizeof(OLD256_MIDI_HACK) + size + 7) >>  8) & 0xFF);
-		*ptr++ = (byte)(((sizeof(OLD256_MIDI_HACK) + size + 7)      ) & 0xFF);
-
-		// Conver the ticks into a MIDI tempo. 
-		dw = (500000 * 256) / ticks;
-		debug(4, "  ticks = %d, speed = %u", ticks, dw);
+		assert(ptr < end);
 		
-		// Write a tempo change SysEx
-		memcpy(ptr, "\x00\xFF\x51\x03", 4); ptr += 4;
-		*ptr++ = (byte)((dw >> 16) & 0xFF);
-		*ptr++ = (byte)((dw >> 8) & 0xFF);
-		*ptr++ = (byte)(dw & 0xFF);
-
-		// Copy our hardcoded instrument table into it
-		// Then, convert the instrument table as given in this song resource
-		// And write it *over* the hardcoded table.
-		// Note: we deliberately.
-		memcpy(ptr, OLD256_MIDI_HACK, sizeof(OLD256_MIDI_HACK));
-
+		// Now insert the jump. The jump offset is measured in ticks, and 
+		// each instrument definition spans 4 ticks... so we jump to tick
+		// 8*4, although jumping to tick 0 would probably work fine, too.
+		// Note: it's possible that some musics don't loop from the start...
+		// in that case we'll have to figure out how the loop range is specified
+		// and then how to handle it appropriately (if it's specified in
+		// ticks, we are fine; but if it's a byte offset, it'll be nasty).
+		const int jump_offset = 8 * 4;
+		memcpy(ptr, "\xf0\x13\x7d\x30\00", 5); ptr += 5;	// maybe_jump
+		memcpy(ptr, "\x00\x00", 2); ptr += 2;			// cmd -> 0 means always jump
+		memcpy(ptr, "\x00\x00\x00\x00", 4); ptr += 4;	// track -> there is only one track, 0
+		memcpy(ptr, "\x00\x00\x00\x01", 4); ptr += 4;	// beat -> for now, 1 (first beat)
+		// Ticks
+		*ptr++ = (byte)((jump_offset >> 12) & 0x0F);
+		*ptr++ = (byte)((jump_offset >> 8) & 0x0F);
+		*ptr++ = (byte)((jump_offset >> 4) & 0x0F);
+		*ptr++ = (byte)(jump_offset & 0x0F);
+		memcpy(ptr, "\x00\xf7", 2); ptr += 2;	// sysex end marker
+	}
+	// Finally we reinsert the end of song sysex, just in case
+	memcpy(ptr, "\x00\xff\x2f\x00\x00", 5); ptr += 5;
+	
+	src_ptr+=size;
+	size  = 0;
 		
-		/* now fill in the instruments */
-		for (int i = 0; i < 8; i++) {
-
-			/* flags_1 */
-			ptr[95 * i + 30 + 0] = (instr[i * 16 + 3] >> 4) & 0xf;
-			ptr[95 * i + 30 + 1] = instr[i * 16 + 3] & 0xf;
-
-			/* oplvl_1 */
-			ptr[95 * i + 30 + 2] = (instr[i * 16 + 4] >> 4) & 0xf;
-			ptr[95 * i + 30 + 3] = instr[i * 16 + 4] & 0xf;
-
-			/* atdec_1 */
-			ptr[95 * i + 30 + 4] = ((~instr[i * 16 + 5]) >> 4) & 0xf;
-			ptr[95 * i + 30 + 5] = (~instr[i * 16 + 5]) & 0xf;
-
-			/* sustrel_1 */
-			ptr[95 * i + 30 + 6] = ((~instr[i * 16 + 6]) >> 4) & 0xf;
-			ptr[95 * i + 30 + 7] = (~instr[i * 16 + 6]) & 0xf;
-
-			/* waveform_1 */
-			ptr[95 * i + 30 + 8] = (instr[i * 16 + 7] >> 4) & 0xf;
-			ptr[95 * i + 30 + 9] = instr[i * 16 + 7] & 0xf;
-
-			/* flags_2 */
-			ptr[95 * i + 30 + 10] = (instr[i * 16 + 8] >> 4) & 0xf;
-			ptr[95 * i + 30 + 11] = instr[i * 16 + 8] & 0xf;
-
-			/* oplvl_2 */
-			ptr[95 * i + 30 + 12] = 3;
-			ptr[95 * i + 30 + 13] = 0xF;
+	return 1;
+}
 
-			/* atdec_2 */
-			ptr[95 * i + 30 + 14] = ((~instr[i * 16 + 10]) >> 4) & 0xf;
-			ptr[95 * i + 30 + 15] = (~instr[i * 16 + 10]) & 0xf;
 
-			/* sustrel_2 */
-			ptr[95 * i + 30 + 16] = ((~instr[i * 16 + 11]) >> 4) & 0xf;
-			ptr[95 * i + 30 + 17] = (~instr[i * 16 + 11]) & 0xf;
-
-			/* waveform_2 */
-			ptr[95 * i + 30 + 18] = (instr[i * 16 + 12] >> 4) & 0xf;
-			ptr[95 * i + 30 + 19] = instr[i * 16 + 12] & 0xf;
+int Scumm::readSoundResourceSmallHeader(int type, int idx) {
+	uint32 pos, total_size, size, tag;
+	uint32 ad_size = 0, ad_offs = 0;
+	uint32 wa_size = 0, wa_offs = 0;
 
-			/* feedback */
-			ptr[95 * i + 30 + 20] = (instr[i * 16 + 2] >> 4) & 0xf;
-			ptr[95 * i + 30 + 21] = instr[i * 16 + 2] & 0xf;
-		}
+	debug(4, "readSoundResourceSmallHeader(%s,%d)", resTypeFromId(type), idx);
 
-		free(instr);
-		ptr += sizeof(OLD256_MIDI_HACK);
+	//if (_rescache->readResource(roomNr, type, idx))
+	//		return 1;
 
-		// Now copy the actual music data 
-		memcpy(ptr, track, size);
-		free(track);
+	if ((_features & GF_OLD_BUNDLE)) {
+		wa_offs = _fileHandle.pos();
+		wa_size = _fileHandle.readUint16LE();
+		_fileHandle.seek(wa_size - 2, SEEK_CUR);
+		ad_offs = _fileHandle.pos();
+		ad_size = _fileHandle.readUint16LE();
+		_fileHandle.seek(4, SEEK_CUR);
+		total_size = wa_size + ad_size;
+	} else {
+		total_size = size = _fileHandle.readUint32LE();
+		tag = _fileHandle.readUint16LE();
+		debug(4, "  tag='%c%c', size=%d",
+		      (char) (tag & 0xff),
+		      (char) ((tag >> 8) & 0xff), size);
 		
-		if (!play_once) {
-			// The song is meant to be looped. We achieve this by inserting just
-			// before the song end a jump to the song start. More precisely we abuse
-			// a S&M sysex, "maybe_jump" to achieve this effect. We could also
-			// use a set_loop sysex, but it's a bit longer, a little more complicated,
-			// and has no advantage either.
-
-			// First, find the track end
-			byte *end = ptr + size;
-			for (; ptr < end; ptr++) {
-				if (*ptr == 0xff && *(ptr + 1) == 0x2f)
-					break;
+		pos = 6;
+		while (pos < total_size) {
+			size = _fileHandle.readUint32LE();
+			tag = _fileHandle.readUint16LE();
+			debug(4, "  tag='%c%c', size=%d",
+			      (char) (tag & 0xff),
+			      (char) ((tag >> 8) & 0xff), size);
+			pos += size;
+			
+			// MI1 and Indy3 uses one or more nested SO resources, which contains AD and WA
+			// resources.
+			if ((tag == 0x4441) && !(ad_offs)) { // AD
+				ad_size = size;
+				ad_offs = _fileHandle.pos();
+			} else if ((tag == 0x4157) && !(wa_offs)) { // WA
+				wa_size = size;
+				wa_offs = _fileHandle.pos();
+			} else { // other AD, WA and nested SO resources
+				if (tag == 0x4F53) { // SO
+					pos -= size;
+					size = 6;
+					pos += 6;
+				}
 			}
-			assert(ptr < end);
+			_fileHandle.seek(size - 6, SEEK_CUR);
+		}
+	}
 
-			// Now insert the jump. The jump offset is measured in ticks, and 
-			// each instrument definition spans 4 ticks... so we jump to tick
-			// 8*4, although jumping to tick 0 would probably work fine, too.
-			// Note: it's possible that some musics don't loop from the start...
-			// in that case we'll have to figure out how the loop range is specified
-			// and then how to handle it appropriately (if it's specified in
-			// ticks, we are fine; but if it's a byte offset, it'll be nasty).
-			const int jump_offset = 8 * 4;
-			memcpy(ptr, "\xf0\x13\x7d\x30\00", 5); ptr += 5;	// maybe_jump
-			memcpy(ptr, "\x00\x00", 2); ptr += 2;			// cmd -> 0 means always jump
-			memcpy(ptr, "\x00\x00\x00\x00", 4); ptr += 4;	// track -> there is only one track, 0
-			memcpy(ptr, "\x00\x00\x00\x01", 4); ptr += 4;	// beat -> for now, 1 (first beat)
-			// Ticks
-			*ptr++ = (byte)((jump_offset >> 12) & 0x0F);
-			*ptr++ = (byte)((jump_offset >> 8) & 0x0F);
-			*ptr++ = (byte)((jump_offset >> 4) & 0x0F);
-			*ptr++ = (byte)(jump_offset & 0x0F);
-			memcpy(ptr, "\x00\xf7", 2); ptr += 2;	// sysex end marker
+	// AD resources have a header, instrument definitions and one MIDI track.
+	// We build an 'ADL ' resource from that:
+	//   8 bytes resource header
+	//  16 bytes MDhd header
+	//  14 bytes MThd header
+	//   8 bytes MTrk header
+	//   7 bytes MIDI tempo sysex
+	//     + some default instruments
+	// TODO:  - make some real MIDI instrument definitions
+	//        - proper handling of the short (non-music, SFX) AD resources format
+	//        - check the LE/BE handling for platforms other than PC
 
-			// Finally we reinsert the end of song sysex, just in case
-			memcpy(ptr, "\x00\xff\x2f\x00\x00", 5); ptr += 5;
-		}
-		
-		return 1;
+	if (ad_offs != 0) {
+		byte *ptr;
+		if (_features & GF_OLD_BUNDLE) {
+			ptr = (byte *) calloc(ad_size - 4, 1);
+			_fileHandle.seek(ad_offs + 4, SEEK_SET);
+			_fileHandle.read(ptr, ad_size - 4);
+			return convertADResource(type, idx, ptr, ad_size - 4);
+		} else {
+			ptr = (byte *) calloc(ad_size - 6, 1);
+			_fileHandle.seek(ad_offs, SEEK_SET);
+			_fileHandle.read(ptr, ad_size - 6);
+			return convertADResource(type, idx, ptr, ad_size - 6);
+		} 
 	}
 	res.roomoffs[type][idx] = 0xFFFFFFFF;
 	return 0;

Index: scumm.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.h,v
retrieving revision 1.277
retrieving revision 1.278
diff -u -d -r1.277 -r1.278
--- scumm.h	29 Jul 2003 12:13:39 -0000	1.277
+++ scumm.h	5 Aug 2003 05:21:57 -0000	1.278
@@ -642,6 +642,8 @@
 
 protected:
 	int readSoundResource(int type, int index);
+	int convert_extraflags(byte *ptr, byte * src_ptr);
+	int convertADResource(int type, int index, byte *ptr, int size);
 	int readSoundResourceSmallHeader(int type, int index);
 	void setResourceCounter(int type, int index, byte flag);
 	bool validateResource(const char *str, int type, int index) const;

Index: scummvm.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scummvm.cpp,v
retrieving revision 2.308
retrieving revision 2.309
diff -u -d -r2.308 -r2.309
--- scummvm.cpp	2 Aug 2003 00:36:38 -0000	2.308
+++ scummvm.cpp	5 Aug 2003 05:21:57 -0000	2.309
@@ -616,8 +616,12 @@
 		_imuseDigital = new IMuseDigital(this);
 		_imuse = NULL;
 		_playerV2 = NULL;
+	} else if ((_features & GF_AMIGA) && (_features & GF_OLD_BUNDLE)) {
+		_playerV2 = NULL;
+		_imuse = NULL;
+		_imuseDigital = NULL;
 	} else if (_features & GF_OLD_BUNDLE) {
-		if ((_features & GF_AMIGA) || ((_version == 1) && (_gameId == GID_MANIAC)))
+		if ((_version == 1) && (_gameId == GID_MANIAC))
 			_playerV2 = NULL;
 		else
 			_playerV2 = new Player_V2(this);

Index: sound.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/sound.cpp,v
retrieving revision 1.191
retrieving revision 1.192
diff -u -d -r1.191 -r1.192
--- sound.cpp	1 Aug 2003 12:50:19 -0000	1.191
+++ sound.cpp	5 Aug 2003 05:21:57 -0000	1.192
@@ -323,7 +323,7 @@
 			memcpy(sound, ptr + 33, size);
 			_scumm->_mixer->playRaw(NULL, sound, size, rate, flags, soundID);
 			return;
-		} else if (_scumm->_features & GF_OLD256) {
+		} else if (_scumm->_features & GF_FMTOWNS) {
 			size = READ_LE_UINT32(ptr);
 #if 0
 			// FIXME - this is just some debug output for Zak256





More information about the Scummvm-git-logs mailing list