aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
Diffstat (limited to 'scumm')
-rw-r--r--scumm/resource.cpp158
1 files changed, 86 insertions, 72 deletions
diff --git a/scumm/resource.cpp b/scumm/resource.cpp
index 4a9cf874ce..689984ff1a 100644
--- a/scumm/resource.cpp
+++ b/scumm/resource.cpp
@@ -957,8 +957,6 @@ static char OLD256_MIDI_HACK[] =
int Scumm::readSoundResourceSmallHeader(int type, int idx) {
uint32 pos, total_size, size, dw, tag;
uint32 best_size = 0, best_offs = 0;
- byte *ptr, *track, *instr;
- uint16 ticks, skip;
debug(4, "readSoundResourceSmallHeader(%s,%d)", resTypeFromId(type), idx);
@@ -975,7 +973,7 @@ int Scumm::readSoundResourceSmallHeader(int type, int idx) {
while (pos < total_size) {
size = _fileHandle.readUint32LE();
tag = _fileHandle.readUint16LE();
- debug(4, " tag='%c%c', size=%d",
+ debug(4, " tag='%c%c', size=%d",
(char) (tag & 0xff),
(char) ((tag >> 8) & 0xff), size);
pos += size;
@@ -1009,33 +1007,43 @@ int Scumm::readSoundResourceSmallHeader(int type, int idx) {
// - check the LE/BE handling for platforms other than PC
if (best_offs != 0) {
+ byte *ptr, *track, *instr;
+ uint16 ticks, skip;
+ byte music_type, num_instr;
+
_fileHandle.seek(best_offs - 6, SEEK_SET);
ptr = createResource(type, idx, best_size);
_fileHandle.read(ptr, best_size);
- ticks = READ_BE_UINT16_UNALIGNED(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;
+ music_type = *(ptr + 8); // 0x80: is music; otherwise not.
+
+ if (music_type != 0x80) {
+ // It's an SFX; we don't know how to handle those yet
+ warning("Sound %d not played, format not yet supported", idx);
+ nukeResource(type, idx);
+ res.roomoffs[type][idx] = 0xFFFFFFFF;
+ return 0;
}
+
+ // The "speed" of the song
+ ticks = *(ptr + 9);
- /* copy the instrument data in another memory area */
- if (size >= 0x19 + 8*16) {
- instr = (byte *)calloc(8 * 16, 1);
- if (instr)
- memcpy(instr, ptr + 0x19, 8*16);
- } else {
- instr = 0;
- }
+ num_instr = *(ptr + 16); // Normally 8
+ if (num_instr != 8)
+ warning("Sound %d has %d instruments, expected 8", idx, num_instr);
+
+ size = best_size;
+ skip = 0x98;
- ptr += skip; // size + instruments
- size -= skip; // drop instruments for now
+ // 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
+ ptr += skip;
+ size -= skip;
CHECK_HEAP
track = (byte *)calloc(size, 1);
if (track == NULL) {
@@ -1043,9 +1051,11 @@ int Scumm::readSoundResourceSmallHeader(int type, int idx) {
}
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) - 1 + size;
+
+ // 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);
@@ -1053,88 +1063,92 @@ int Scumm::readSoundResourceSmallHeader(int type, int idx) {
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;
+ 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;
- memcpy(ptr, &ticks, 2); ptr += 2; // FIXME: care of BE/LE needed ?
+
+ // FIXME: should we convert ticks here? I.e. BE vs LE, or maybe another scale is
+ // needed? In fact does anything *read* this value, ever?
+ memcpy(ptr, &ticks, 2); ptr += 2;
+
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
+
+ // 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);
- memcpy(ptr, OLD256_MIDI_HACK, sizeof(OLD256_MIDI_HACK) - 1);
-
- if (instr) {
- /* now fill in the instruments */
- for (int i = 0; i < 8; i++) {
+ // 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.
+ memcpy(ptr, OLD256_MIDI_HACK, sizeof(OLD256_MIDI_HACK) - 1);
- /* flags_1 */
- ptr[95 * i + 30 + 0] = (instr[i * 16 + 3] >> 4) & 0xf;
- ptr[95 * i + 30 + 1] = instr[i * 16 + 3] & 0xf;
+
+ /* now fill in the instruments */
+ for (int i = 0; i < 8; i++) {
- /* oplvl_1 */
- ptr[95 * i + 30 + 2] = (instr[i * 16 + 4] >> 4) & 0xf;
- ptr[95 * i + 30 + 3] = instr[i * 16 + 4] & 0xf;
+ /* flags_1 */
+ ptr[95 * i + 30 + 0] = (instr[i * 16 + 3] >> 4) & 0xf;
+ ptr[95 * i + 30 + 1] = instr[i * 16 + 3] & 0xf;
- /* atdec_1 */
- ptr[95 * i + 30 + 4] = ((~instr[i * 16 + 5]) >> 4) & 0xf;
- ptr[95 * i + 30 + 5] = (~instr[i * 16 + 5]) & 0xf;
+ /* oplvl_1 */
+ ptr[95 * i + 30 + 2] = (instr[i * 16 + 4] >> 4) & 0xf;
+ ptr[95 * i + 30 + 3] = instr[i * 16 + 4] & 0xf;
- /* sustrel_1 */
- ptr[95 * i + 30 + 6] = ((~instr[i * 16 + 6]) >> 4) & 0xf;
- ptr[95 * i + 30 + 7] = (~instr[i * 16 + 6]) & 0xf;
+ /* atdec_1 */
+ ptr[95 * i + 30 + 4] = ((~instr[i * 16 + 5]) >> 4) & 0xf;
+ ptr[95 * i + 30 + 5] = (~instr[i * 16 + 5]) & 0xf;
- /* waveform_1 */
- ptr[95 * i + 30 + 8] = (instr[i * 16 + 7] >> 4) & 0xf;
- ptr[95 * i + 30 + 9] = instr[i * 16 + 7] & 0xf;
+ /* sustrel_1 */
+ ptr[95 * i + 30 + 6] = ((~instr[i * 16 + 6]) >> 4) & 0xf;
+ ptr[95 * i + 30 + 7] = (~instr[i * 16 + 6]) & 0xf;
- /* flags_2 */
- ptr[95 * i + 30 + 10] = (instr[i * 16 + 8] >> 4) & 0xf;
- ptr[95 * i + 30 + 11] = instr[i * 16 + 8] & 0xf;
+ /* waveform_1 */
+ ptr[95 * i + 30 + 8] = (instr[i * 16 + 7] >> 4) & 0xf;
+ ptr[95 * i + 30 + 9] = instr[i * 16 + 7] & 0xf;
- /* oplvl_2 */
- ptr[95 * i + 30 + 12] = 3;
- ptr[95 * i + 30 + 13] = 0xF;
+ /* flags_2 */
+ ptr[95 * i + 30 + 10] = (instr[i * 16 + 8] >> 4) & 0xf;
+ ptr[95 * i + 30 + 11] = instr[i * 16 + 8] & 0xf;
- /* atdec_2 */
- ptr[95 * i + 30 + 14] = ((~instr[i * 16 + 10]) >> 4) & 0xf;
- ptr[95 * i + 30 + 15] = (~instr[i * 16 + 10]) & 0xf;
+ /* oplvl_2 */
+ ptr[95 * i + 30 + 12] = 3;
+ ptr[95 * i + 30 + 13] = 0xF;
- /* sustrel_2 */
- ptr[95 * i + 30 + 16] = ((~instr[i * 16 + 11]) >> 4) & 0xf;
- ptr[95 * i + 30 + 17] = (~instr[i * 16 + 11]) & 0xf;
+ /* atdec_2 */
+ ptr[95 * i + 30 + 14] = ((~instr[i * 16 + 10]) >> 4) & 0xf;
+ ptr[95 * i + 30 + 15] = (~instr[i * 16 + 10]) & 0xf;
- /* waveform_2 */
- ptr[95 * i + 30 + 18] = (instr[i * 16 + 12] >> 4) & 0xf;
- ptr[95 * i + 30 + 19] = instr[i * 16 + 12] & 0xf;
+ /* sustrel_2 */
+ ptr[95 * i + 30 + 16] = ((~instr[i * 16 + 11]) >> 4) & 0xf;
+ ptr[95 * i + 30 + 17] = (~instr[i * 16 + 11]) & 0xf;
- /* feedback */
- ptr[95 * i + 30 + 20] = (instr[i * 16 + 2] >> 4) & 0xf;
- ptr[95 * i + 30 + 21] = instr[i * 16 + 2] & 0xf;
- }
+ /* waveform_2 */
+ ptr[95 * i + 30 + 18] = (instr[i * 16 + 12] >> 4) & 0xf;
+ ptr[95 * i + 30 + 19] = instr[i * 16 + 12] & 0xf;
- free(instr);
+ /* feedback */
+ ptr[95 * i + 30 + 20] = (instr[i * 16 + 2] >> 4) & 0xf;
+ ptr[95 * i + 30 + 21] = instr[i * 16 + 2] & 0xf;
}
+ free(instr);
+
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;