diff options
author | Travis Howell | 2002-09-21 13:48:03 +0000 |
---|---|---|
committer | Travis Howell | 2002-09-21 13:48:03 +0000 |
commit | f1a273e09240d6a439cccbe5dffa99a54cc43229 (patch) | |
tree | 010a738669c4ec193a0c0ef36913499c6f930eb7 /scumm/resource.cpp | |
parent | a2a3fb5636b3d12301490db715c5732f5e211915 (diff) | |
download | scummvm-rg350-f1a273e09240d6a439cccbe5dffa99a54cc43229.tar.gz scummvm-rg350-f1a273e09240d6a439cccbe5dffa99a54cc43229.tar.bz2 scummvm-rg350-f1a273e09240d6a439cccbe5dffa99a54cc43229.zip |
Add the following patches:
[ 609649 ] Sound patch for GF_OLD256 games
[ 611997 ] RFC: Timer-based CD audio sync
svn-id: r4986
Diffstat (limited to 'scumm/resource.cpp')
-rw-r--r-- | scumm/resource.cpp | 369 |
1 files changed, 369 insertions, 0 deletions
diff --git a/scumm/resource.cpp b/scumm/resource.cpp index cfbf4e7283..bef67b94a4 100644 --- a/scumm/resource.cpp +++ b/scumm/resource.cpp @@ -530,6 +530,8 @@ int Scumm::loadResource(int type, int idx) size = _fileHandle.readDwordLE(); tag = _fileHandle.readWordLE(); _fileHandle.seek(-6, SEEK_CUR); + if (type == rtSound) + return readSoundResourceSmallHeader(type, idx); } else { if (type == rtSound) { _fileHandle.readDwordLE(); @@ -730,6 +732,373 @@ int Scumm::readSoundResource(int type, int idx) 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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\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 + // 8 + "\x00\xf0\x14\x7d\x00" // sysex 00: part on/off + "\x08\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 + "\x08" // 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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\x08\x00\x00\x00\x01\x02\x04\x00" + "\x06\x02\x00\x00\x04\x00\x03\x02" + "\x04\x00\x00\xf7" + "\x00\xb8\x07\x64" // Controller 7 = 100 + // 9 + "\x00\xf0\x14\x7d\x00" // sysex 00: part on/off + "\x09\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 + "\x09" // 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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\x08\x00\x00\x00\x01\x02\x04\x00" + "\x06\x02\x00\x00\x04\x00\x03\x02" + "\x04\x00\x00\xf7" + "\x00\xb9\x07\x64" // Controller 7 = 100 + // Channels after 9 realy necessary ?!? + // A + "\x00\xf0\x14\x7d\x00" // sysex 00: part on/off + "\x0A\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 + "\x0A" // 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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\x08\x00\x00\x00\x01\x02\x04\x00" + "\x06\x02\x00\x00\x04\x00\x03\x02" + "\x04\x00\x00\xf7" + "\x00\xbA\x07\x64" // Controller 7 = 100 + // B + "\x00\xf0\x14\x7d\x00" // sysex 00: part on/off + "\x0B\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 + "\x0B" // 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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\x08\x00\x00\x00\x01\x02\x04\x00" + "\x06\x02\x00\x00\x04\x00\x03\x02" + "\x04\x00\x00\xf7" + "\x00\xbB\x07\x64" // Controller 7 = 100 + // C + "\x00\xf0\x14\x7d\x00" // sysex 00: part on/off + "\x0C\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 + "\x0C" // 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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\x08\x00\x00\x00\x01\x02\x04\x00" + "\x06\x02\x00\x00\x04\x00\x03\x02" + "\x04\x00\x00\xf7" + "\x00\xbC\x07\x64" // Controller 7 = 100 + // D + "\x00\xf0\x14\x7d\x00" // sysex 00: part on/off + "\x0D\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 + "\x0D" // 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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\x08\x00\x00\x00\x01\x02\x04\x00" + "\x06\x02\x00\x00\x04\x00\x03\x02" + "\x04\x00\x00\xf7" + "\x00\xbD\x07\x64" // Controller 7 = 100 + // E + "\x00\xf0\x14\x7d\x00" // sysex 00: part on/off + "\x0E\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 + "\x0E" // 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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\x08\x00\x00\x00\x01\x02\x04\x00" + "\x06\x02\x00\x00\x04\x00\x03\x02" + "\x04\x00\x00\xf7" + "\x00\xbE\x07\x64" // Controller 7 = 100 + // F + "\x00\xf0\x14\x7d\x00" // sysex 00: part on/off + "\x0F\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 + "\x0F" // 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\x0a\x01\x00" + "\x00\x00\x01\x01\x0e\x00\x02\x02" + "\x01\x00\x01\x00\x01\x02\x00\x0a" + "\x08\x00\x00\x00\x01\x02\x04\x00" + "\x06\x02\x00\x00\x04\x00\x03\x02" + "\x04\x00\x00\xf7" + "\x00\xbF\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; + byte *ptr, *track; + uint16 ticks, skip; + + debug(4, "readSoundResourceSmallHeader(%s,%d)", resTypeFromId(type), idx); + + //if (_rescache->readResource(roomNr, type, idx)) + // return 1; + + total_size = size = _fileHandle.readDwordLE(); + tag = _fileHandle.readWordLE(); + debug(4, " tag='%c%c', size=%d", + (char) (tag & 0xff), + (char) ((tag >> 8) & 0xff), size); + + pos = 6; + while (pos < total_size) { + size = _fileHandle.readDwordLE(); + tag = _fileHandle.readWordLE(); + 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) && !(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); + } + + // 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 MIDI speed event + // + some default instruments + // TODO: - make some real MIDI instrument definitions + // - no sound looping + // - proper handling of the short AD resources format + // - check the LE/BE handling for platforms other than PC + + if (best_offs != 0) { + _fileHandle.seek(best_offs - 6, SEEK_SET); + + ptr = createResource(type, idx, best_size); + _fileHandle.read(ptr, best_size); + + ticks = READ_BE_UINT16(ptr + 9); + size = best_size; + if (size < 0x98) { + // FIXME: OLD256 music file w/o instruments + // perhaps we should use then the other "WA" resource in the "SO" resource + // and play it raw + skip = 0x0a; // let's give it a try + } else { + skip = 0x98; + } + ptr += skip; // size + instruments + size -= skip; // drop instruments for now + CHECK_HEAP track = (byte *)calloc(size, 1); + if (track == NULL) { + error("Out of memory while allocating %d", size); + } + memcpy(track, ptr, size); // saving MIDI track data + nukeResource(type, idx); + + total_size = 8 + 16 + 14 + 8 + 7 + sizeof(OLD256_MIDI_HACK) - 1 + size; + 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; + dw = 0; + memcpy(ptr, &dw, 4); ptr += 4; + memcpy(ptr, &dw, 4); ptr += 4; + 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; + memcpy(ptr, &ticks, 2); ptr += 2; // FIXME: care of BE/LE needed ? + memcpy(ptr, "MTrk", 4); ptr += 4; + *ptr++ = ((sizeof(OLD256_MIDI_HACK) - 1 + size + 7) >> 24) & 0xFF; + *ptr++ = ((sizeof(OLD256_MIDI_HACK) - 1 + size + 7) >> 16) & 0xFF; + *ptr++ = ((sizeof(OLD256_MIDI_HACK) - 1 + size + 7) >> 8) & 0xFF; + *ptr++ = ((sizeof(OLD256_MIDI_HACK) - 1 + size + 7) ) & 0xFF; + // speed hacks + dw = 1100000 - (ticks * 10); + if ((dw > 900000) || (dw < 200000)) + dw = 500000; // for sanity + debug(4, " ticks = %d, speed = %ld", ticks, dw); + memcpy(ptr, "\x00\xFF\x51\x03", 4); ptr += 4; + *ptr++ = (dw >> 16) & 0xFF; + *ptr++ = (dw >> 8) & 0xFF; + *ptr++ = dw & 0xFF; + memcpy(ptr, OLD256_MIDI_HACK, sizeof(OLD256_MIDI_HACK) - 1); + ptr += sizeof(OLD256_MIDI_HACK) - 1; + memcpy(ptr, track, size); + free(track); + //hexdump(ptr = getResourceAddress(type, idx), 32); + return 1; + } + res.roomoffs[type][idx] = 0xFFFFFFFF; + return 0; +} + + int Scumm::getResourceRoomNr(int type, int idx) { if (type == rtRoom) |