aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
Diffstat (limited to 'scumm')
-rw-r--r--scumm/resource.cpp608
-rw-r--r--scumm/scummvm.cpp2
-rw-r--r--scumm/sound.cpp2
3 files changed, 465 insertions, 147 deletions
diff --git a/scumm/resource.cpp b/scumm/resource.cpp
index edc6bc66ab..5b3b67bca3 100644
--- a/scumm/resource.cpp
+++ b/scumm/resource.cpp
@@ -641,8 +641,12 @@ int Scumm::loadResource(int type, int idx) {
_fileHandle.seek(fileOffs + _fileOffset, SEEK_SET);
if (_features & GF_OLD_BUNDLE) {
- size = _fileHandle.readUint16LE();
- _fileHandle.seek(-2, SEEK_CUR);
+ if ((_version == 3) && !(_features & GF_AMIGA) && (type == rtSound)) {
+ return readSoundResourceSmallHeader(type, idx);
+ } else {
+ size = _fileHandle.readUint16LE();
+ _fileHandle.seek(-2, SEEK_CUR);
+ }
} else if (_features & GF_SMALL_HEADER) {
if (!(_features & GF_SMALL_NAMES))
_fileHandle.seek(8, SEEK_CUR);
@@ -895,61 +899,127 @@ static byte ADLIB_INSTR_MIDI_HACK[95] = {
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, 0x01, // part/channel (offset 28)
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf7,
0x00, 0xb0, 0x07, 0x64 // Controller 7 = 100 (offset 92)
};
-int Scumm::convertADResource(int type, int idx, byte * src_ptr, int size) {
+static const byte map_param[7] = {
+ 0, 2, 3, 4, 8, 9, 0,
+};
- byte * ptr;
- byte ticks, play_once;
- byte music_type, num_instr;
- byte *channel, *instr, *track;
- int i, ch;
+static const byte freq2note[128] = {
+ /*128*/ 6, 6, 6, 6,
+ /*132*/ 7, 7, 7, 7, 7, 7, 7,
+ /*139*/ 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ /*148*/ 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ /*157*/ 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ /*166*/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ /*176*/ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ /*186*/ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ /*197*/ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ /*209*/ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ /*222*/ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ /*235*/ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ /*249*/ 18, 18, 18, 18, 18, 18, 18
+};
+
+static const uint16 num_steps_table[] = {
+ 1, 2, 4, 5,
+ 6, 7, 8, 9,
+ 10, 12, 14, 16,
+ 18, 21, 24, 30,
+ 36, 50, 64, 82,
+ 100, 136, 160, 192,
+ 240, 276, 340, 460,
+ 600, 860, 1200, 1600
+};
+int Scumm::convert_extraflags(byte * ptr, byte * src_ptr) {
+ int flags = src_ptr[0];
+
+ int t1, t2, t3, t4, time;
+ int v1, v2, v3;
+
+ if (!(flags & 0x80))
+ return -1;
+
+ t1 = (src_ptr[1] & 0xf0) >> 3;
+ t2 = (src_ptr[2] & 0xf0) >> 3;
+ t3 = (src_ptr[3] & 0xf0) >> 3 | (flags & 0x40 ? 0x80 : 0);
+ t4 = (src_ptr[3] & 0x0f) << 1;
+ v1 = (src_ptr[1] & 0x0f);
+ v2 = (src_ptr[2] & 0x0f);
+ v3 = 31;
+ if ((flags & 0x7) == 0) {
+ v1 = v1 + 31 + 8;
+ v2 = v2 + 31 + 8;
+ } else {
+ v1 = v1 * 2 + 31;
+ v2 = v2 * 2 + 31;
+ }
- 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);
- res.roomoffs[type][idx] = 0xFFFFFFFF;
- return 0;
+ /* flags a */
+ if ((flags & 0x7) == 6)
+ ptr[0] = 0;
+ else {
+ ptr[0] = (flags >> 4) & 0xb;
+ ptr[1] = map_param[flags & 0x7];
}
- // 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;
+ /* extra a */
+ ptr[2] = 0;
+ ptr[3] = 0;
+ ptr[4] = t1 >> 4;
+ ptr[5] = t1 & 0xf;
+ ptr[6] = v1 >> 4;
+ ptr[7] = v1 & 0xf;
+ ptr[8] = t2 >> 4;
+ ptr[9] = t2 & 0xf;
+ ptr[10] = v2 >> 4;
+ ptr[11] = v2 & 0xf;
+ ptr[12] = t3 >> 4;
+ ptr[13] = t3 & 0xf;
+ ptr[14] = t4 >> 4;
+ ptr[15] = t4 & 0xf;
+ ptr[16] = v3 >> 4;
+ ptr[17] = v3 & 0xf;
+
+ time = num_steps_table[t1] + num_steps_table[t2]
+ + num_steps_table[t3 & 0x7f] + num_steps_table[t4];
+ if (flags & 0x20) {
+ int playtime = ((src_ptr[4] >> 4) & 0xf) * 118 +
+ (src_ptr[4] & 0xf) * 8;
+ if (playtime > time)
+ time = playtime;
+ }
+ /*
+ time = ((src_ptr[4] >> 4) & 0xf) * 118 +
+ (src_ptr[4] & 0xf) * 8;
+ */
+ return time;
+}
- // skip over the rest of the header and copy the MIDI data into a buffer
- src_ptr += 0x11 + 8 * 16;
- size -= 0x11 + 8 * 16;
+int Scumm::convertADResource(int type, int idx, byte * src_ptr, int size) {
- CHECK_HEAP
-
- track = src_ptr;
-
+ byte * ptr;
+ byte ticks, play_once;
+ byte num_instr;
+ byte *channel, *instr, *track;
+ byte *tracks[3];
+ int delay, delay2, olddelay;
+ int i, ch;
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
ptr = createResource(type, idx, total_size);
+ byte *start_ptr = ptr;
memcpy(ptr, "ADL ", 4); ptr += 4;
uint32 dw = READ_BE_UINT32(&total_size);
memcpy(ptr, &dw, 4); ptr += 4;
@@ -973,125 +1043,373 @@ int Scumm::convertADResource(int type, int idx, byte * src_ptr, int size) {
dw = READ_BE_UINT32(&total_size);
memcpy(ptr, &dw, 4); ptr += 4;
- // 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.
-
- /* now fill in the instruments */
- for (i = 0; i < num_instr; i++) {
- ch = channel[i] - 1;
-
- debug(4, "Sound %d: instrument %d on channel %d.",
- idx, i, ch);
+ src_ptr += 2;
+ size -= 2;
- memcpy(ptr, ADLIB_INSTR_MIDI_HACK,
- sizeof(ADLIB_INSTR_MIDI_HACK));
+ if (*src_ptr == 0x80) {
+ // 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;
+ // The "speed" of the song
+ ticks = *(src_ptr + 1);
- /* oplvl_1 */
- ptr[30 + 2] = (instr[i * 16 + 4] >> 4) & 0xf;
- ptr[30 + 3] = instr[i * 16 + 4] & 0xf;
+ // Flag that tells us whether we should loop the song (0) or play it only once (1)
+ play_once = *(src_ptr + 2);
- /* atdec_1 */
- ptr[30 + 4] = ((~instr[i * 16 + 5]) >> 4) & 0xf;
- ptr[30 + 5] = (~instr[i * 16 + 5]) & 0xf;
+ // Number of instruments used
+ num_instr = *(src_ptr + 8); // Normally 8
- /* sustrel_1 */
- ptr[30 + 6] = ((~instr[i * 16 + 6]) >> 4) & 0xf;
- ptr[30 + 7] = (~instr[i * 16 + 6]) & 0xf;
+ // copy the pointer to instrument data
+ channel = src_ptr + 9;
+ instr = src_ptr + 0x11;
- /* waveform_1 */
- ptr[30 + 8] = (instr[i * 16 + 7] >> 4) & 0xf;
- ptr[30 + 9] = instr[i * 16 + 7] & 0xf;
+ // skip over the rest of the header and copy the MIDI data into a buffer
+ src_ptr += 0x11 + 8 * 16;
+ size -= 0x11 + 8 * 16;
+
+ CHECK_HEAP
+
+ track = src_ptr;
- /* flags_2 */
- ptr[30 + 10] = (instr[i * 16 + 8] >> 4) & 0xf;
- ptr[30 + 11] = instr[i * 16 + 8] & 0xf;
+ // 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);
- /* oplvl_2 */
- ptr[30 + 12] = (instr[i * 16 + 9] >> 4) & 0xf;
- ptr[30 + 13] = instr[i * 16 + 9] & 0xf;
+ // 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.
- /* atdec_2 */
- ptr[30 + 14] = ((~instr[i * 16 + 10]) >> 4) & 0xf;
- ptr[30 + 15] = (~instr[i * 16 + 10]) & 0xf;
+ /* now fill in the instruments */
+ for (i = 0; i < num_instr; i++) {
+ ch = channel[i] - 1;
+
+ debug(4, "Sound %d: instrument %d on channel %d.",
+ idx, i, ch);
+
+ memcpy(ptr, ADLIB_INSTR_MIDI_HACK,
+ sizeof(ADLIB_INSTR_MIDI_HACK));
+
+ 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;
+
+ /* oplvl_1 */
+ ptr[30 + 2] = (instr[i * 16 + 4] >> 4) & 0xf;
+ ptr[30 + 3] = instr[i * 16 + 4] & 0xf;
+
+ /* atdec_1 */
+ ptr[30 + 4] = ((~instr[i * 16 + 5]) >> 4) & 0xf;
+ ptr[30 + 5] = (~instr[i * 16 + 5]) & 0xf;
+
+ /* sustrel_1 */
+ ptr[30 + 6] = ((~instr[i * 16 + 6]) >> 4) & 0xf;
+ ptr[30 + 7] = (~instr[i * 16 + 6]) & 0xf;
+
+ /* 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);
+ }
- /* sustrel_2 */
- ptr[30 + 16] = ((~instr[i * 16 + 11]) >> 4) & 0xf;
- ptr[30 + 17] = (~instr[i * 16 + 11]) & 0xf;
+ *ptr++ = 0; // delay 0;
- /* waveform_2 */
- ptr[30 + 18] = (instr[i * 16 + 12] >> 4) & 0xf;
- ptr[30 + 19] = instr[i * 16 + 12] & 0xf;
+ // Now copy the actual music data
+ memcpy(ptr, track, size);
+ ptr += size;
- /* 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.
+ 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;
+ }
+ assert(ptr < end);
+
+ // 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;
- // First, find the track end
- byte *end = ptr;
- ptr -= size;
- for (; ptr < end; ptr++) {
- if (*ptr == 0xff && *(ptr + 1) == 0x2f)
+ return 1;
+ }
+
+
+ /* This is a sfx resource. First parse it quickly to find the parallel
+ * tracks.
+ */
+ byte current_instr[3][14];
+ int current_note[3];
+ int track_time[3];
+
+ int track_ctr = 0;
+ byte chunk_type = 0;
+
+ for (i = 0; i < 3; i++) {
+ track_time[i] = -1;
+ current_note[i] = -1;
+ }
+ while (size > 0) {
+ tracks[track_ctr] = src_ptr;
+ track_time[track_ctr] = 0;
+ track_ctr++;
+ while (size > 0) {
+ chunk_type = *(src_ptr);
+ if (chunk_type == 1) {
+ src_ptr += 15;
+ size -= 15;
+ } else if (chunk_type == 2) {
+ src_ptr += 11;
+ size -= 11;
+ } else if (chunk_type == 0x80) {
+ src_ptr ++;
+ size --;
+ } else {
break;
+ }
+ }
+ if (chunk_type == 0xff)
+ break;
+ src_ptr++;
+ }
+
+ int curtime = 0;
+ for (;;) {
+ int mintime = -1;
+ ch = -1;
+ for (i = 0; i < 3; i++) {
+ if (track_time[i] >= 0 &&
+ (mintime == -1 || mintime > track_time[i])) {
+ mintime = track_time[i];
+ ch = i;
+ }
+ }
+ if (mintime < 0)
+ break;
+
+ src_ptr = tracks[ch];
+ chunk_type = *(src_ptr);
+
+
+ if (current_note[ch] >= 0) {
+ delay = mintime - curtime;
+ curtime = mintime;
+ if (delay > 0x7f) {
+ if (delay > 0x3fff) {
+ *ptr++ = (delay >> 14) | 0x80;
+ delay &= 0x3fff;
+ }
+ *ptr++ = (delay >> 7) | 0x80;
+ delay &= 0x7f;
+ }
+ *ptr++ = delay;
+ *ptr++ = 0x80 + ch; // key off channel;
+ *ptr++ = current_note[ch];
+ *ptr++ = 0;
+ current_note[ch] = -1;
}
- assert(ptr < end);
- // 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
+
+ switch (chunk_type) {
+ case 1:
+ /* Instrument definition */
+ memcpy(current_instr[ch], src_ptr+1, 14);
+ src_ptr += 15;
+ break;
+
+ case 2:
+ /* tone/parammodulation */
+ memcpy(ptr, ADLIB_INSTR_MIDI_HACK,
+ sizeof(ADLIB_INSTR_MIDI_HACK));
+
+ ptr[5] += ch;
+ ptr[28] += ch;
+ ptr[92] += ch;
+
+ /* flags_1 */
+ ptr[30 + 0] = (current_instr[ch][3] >> 4) & 0xf;
+ ptr[30 + 1] = current_instr[ch][3] & 0xf;
+
+ /* oplvl_1 */
+ ptr[30 + 2] = (current_instr[ch][4] >> 4) & 0xf;
+ ptr[30 + 3] = current_instr[ch][4] & 0xf;
+
+ /* atdec_1 */
+ ptr[30 + 4] = ((~current_instr[ch][5]) >> 4) & 0xf;
+ ptr[30 + 5] = (~current_instr[ch][5]) & 0xf;
+
+ /* sustrel_1 */
+ ptr[30 + 6] = ((~current_instr[ch][6]) >> 4) & 0xf;
+ ptr[30 + 7] = (~current_instr[ch][6]) & 0xf;
+
+ /* waveform_1 */
+ ptr[30 + 8] = (current_instr[ch][7] >> 4) & 0xf;
+ ptr[30 + 9] = current_instr[ch][7] & 0xf;
+
+ /* flags_2 */
+ ptr[30 + 10] = (current_instr[ch][8] >> 4) & 0xf;
+ ptr[30 + 11] = current_instr[ch][8] & 0xf;
+
+ /* oplvl_2 */
+ ptr[30 + 12] = ((current_instr[ch][9]) >> 4) & 0xf;
+ ptr[30 + 13] = (current_instr[ch][9]) & 0xf;
+
+ /* atdec_2 */
+ ptr[30 + 14] = ((~current_instr[ch][10]) >> 4) & 0xf;
+ ptr[30 + 15] = (~current_instr[ch][10]) & 0xf;
+
+ /* sustrel_2 */
+ ptr[30 + 16] = ((~current_instr[ch][11]) >> 4) & 0xf;
+ ptr[30 + 17] = (~current_instr[ch][11]) & 0xf;
+
+ /* waveform_2 */
+ ptr[30 + 18] = (current_instr[ch][12] >> 4) & 0xf;
+ ptr[30 + 19] = current_instr[ch][12] & 0xf;
+
+ /* feedback */
+ ptr[30 + 20] = (current_instr[ch][2] >> 4) & 0xf;
+ ptr[30 + 21] = current_instr[ch][2] & 0xf;
+
+ delay = mintime - curtime;
+ curtime = mintime;
+
+
+
+ {
+ delay = convert_extraflags(ptr + 30 + 22, src_ptr + 1);
+ delay2 = convert_extraflags(ptr + 30 + 40, src_ptr + 6);
+ debug(4, "delays: %d / %d", delay, delay2);
+ if (delay2 >= 0 && delay2 < delay)
+ delay = delay2;
+ if (delay == -1)
+ delay = 0;
+ }
+
+ /* duration */
+ ptr[30 + 58] = 0; // ((delay * 17 / 63) >> 4) & 0xf;
+ ptr[30 + 59] = 0; // (delay * 17 / 63) & 0xf;
+
+ ptr += sizeof(ADLIB_INSTR_MIDI_HACK);
+
+ olddelay = mintime - curtime;
+ curtime = mintime;
+ if (olddelay > 0x7f) {
+ if (olddelay > 0x3fff) {
+ *ptr++ = (olddelay >> 14) | 0x80;
+ olddelay &= 0x3fff;
+ }
+ *ptr++ = (olddelay >> 7) | 0x80;
+ olddelay &= 0x7f;
+ }
+ *ptr++ = olddelay;
+
+
+ /* FIXME: delay factor found by try and error */
+ delay = (delay + 1) * 240 / 13;
+
+ {
+ int freq = ((current_instr[ch][1] & 3) << 8)
+ | current_instr[ch][0];
+ freq <<= ((current_instr[ch][1] >> 2) & 7) + 1;
+ int note = -11;
+ while (freq >= 0x100) {
+ note += 12;
+ freq >>= 1;
+ }
+ debug(4, "Freq: %d (%x) Note: %d", freq, freq, note);
+ if (freq < 0x80)
+ note = 0;
+ else
+ note += freq2note[freq - 0x80];
+
+ debug(4, "Note: %d", note);
+ if (note < 0)
+ note = 0;
+ else if (note > 127)
+ note = 127;
+
+ // Insert a note on event
+ *ptr++ = 0x90 + ch; // key on channel
+ *ptr++ = note;
+ *ptr++ = 63;
+ current_note[ch] = note;
+ track_time[ch] = curtime + delay;
+ }
+ src_ptr += 11;
+ break;
+
+ case 0x80:
+ track_time[ch] = -1;
+ src_ptr ++;
+ break;
+
+ default:
+ track_time[ch] = -1;
+ }
+ tracks[ch] = src_ptr;
}
- // Finally we reinsert the end of song sysex, just in case
+
+ /* insert end of song sysex */
memcpy(ptr, "\x00\xff\x2f\x00\x00", 5); ptr += 5;
-
+
return 1;
}
diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp
index 0a75b46ba5..3413d8dcc5 100644
--- a/scumm/scummvm.cpp
+++ b/scumm/scummvm.cpp
@@ -619,7 +619,7 @@ Scumm::Scumm (GameDetector *detector, OSystem *syst)
_imuseDigital = new IMuseDigital(this);
} else if ((_features & GF_AMIGA) && (_features & GF_OLD_BUNDLE)) {
_playerV2 = NULL;
- } else if (_features & GF_OLD_BUNDLE) {
+ } else if (_version <= 2) {
if ((_version == 1) && (_gameId == GID_MANIAC))
_playerV2 = NULL;
else
diff --git a/scumm/sound.cpp b/scumm/sound.cpp
index 3ea0aea0be..39ca11053a 100644
--- a/scumm/sound.cpp
+++ b/scumm/sound.cpp
@@ -512,7 +512,7 @@ void Sound::playSound(int soundID) {
return;
}
- if (_scumm->_features & GF_OLD_BUNDLE) {
+ if (_scumm->_version <= 2) {
//TODO: support maniac v1 sounds
if ((_scumm->_version == 1) && (_scumm->_gameId == GID_MANIAC))
return;