The SCI01+ sound resource format Originally written by Rickard Lind, 2000-01-05 Extensively rewritten by Lars Skovlund, 2002-10-27 Again updated by Lars Skovlund, 2005-10-12 Used in: Quest for Glory II: Trial by Fire (QfG2) Christmas greeting card 1990 (CC1990) The magic number (84 00) is left out, offset 0 is directly after these two bytes. If you examine a SCI01 sound resource use "sciunpack --without-header" to get the pointers within the file correct for your hex viewer. DESCRIPTION ----------- The SCI01 sound resource consists of a number of track lists and the tracks themselves. There is one track list for (almost) every piece of sound hardware supported by the game. Each track either contains track data for one specific channel or a digital sample. SCI1 resources are the same, except that sample chunks are no longer allowed (since they are now separate resources). Optional Priority Header ------------------------ Some SCI1 songs contain an 8-byte header before the track list. At least on PC platforms, its data is mostly unused. The priority value is used if the script does not override it. offset size description ------------------------------------------------------- 0 byte 0xf0 Priority header marker byte 1 byte Recommended priority for this song 2 6 bytes Apparently unused Track List ---------- The track list tells us which tracks are to be played on particular hardware platforms. Each entry either terminates the previous list or contains an entry for the current one. List Termination ---------------- offset size description ----------------------- 0 byte 0xff 1 byte Hardware ID of next list, 0xff if none List Entry ---------- offset size description ----------------------- 0 byte 0 1 byte 0 2 word Data Chunk pointer 4 word Data Chunk size The very first list in a file looks a little odd, in that it starts with a single byte which tells us the hardware ID associated with the first list (0 in all the cases I've seen) followed by list entries as usual. Known Hardware IDs ------------------ Some of these are used by multiple drivers, probably because they support the same number of polyphonic voices. Note that the hardware ID does not necessarily tell us whether samples are supported - thus, the list for Roland MT-32 also contains sample tracks, because the user may also have a Sound Blaster card connected. SCI1 most likely has more hardware IDs than these. 0x00 - Sound Blaster, Adlib 0x06 - MT-32 with Sound Blaster (for digital audio) 0x09 - CMS/Game Blaster 0x0c - Roland MT-32 0x12 - PC Speaker 0x13 - IBM PS/1, Tandy 3-voice Data Chunks ----------- In the sound resources of QfG2 and CC1990 I've seen two types of Data Chunks, Sample and MIDI channel track. Sample Chunk ------------ offset size description ----------------------- 0 byte =0xfe 1 byte !=0xfe (always 0 in QfG2 and CC1990) 2 word Sample rate (Hz) 4 word Sample length 6 word Sample point 1 (begin?) 8 word Sample point 2 (end?) 10 Unsigned 8-bit mono sample data MIDI channel track Chunk ------------------------ This chunk begins with a 2 byte header. The low nibble of the first byte indicates the channel number. The high nibble controls certain aspects of (dynamic) track channel/hardware channel mapping. The second byte tells us how many notes will be playing simultaneously in the channel. From the third byte onward is the MIDI track data which looks just like normal SCI0 MIDI track data, but all status bytes are targeted at one specific MIDI channel. Example, sound.833 from QfG2 (--without-header) ----------------------------------------------- offset data description ------------------------ 0000 00 Hardware ID for first track list 0001 00 Track list continuation 0002 00 Same hardware device 0003 003F Data Chunk pointer (Little Endian) 0005 0013 Data Chunk length (LE) 0007 00 Track list continuation 0008 00 Same hardware device 0009 006A Data Chunk pointer (LE) 000B 0015 Data Chunk length (LE) 000D FF Next track list 000E 09 for hardware device 0x09 000F 00 Track list continuation 0010 00 Same hardware device 0011 003F Data Chunk pointer (LE) 0013 0013 Data Chunk length (LE) 0015 00 Track list continuation 0016 00 Same hardware device 0017 0052 Data Chunk pointer (LE) 0019 0018 Data Chunk length (LE) 001B 00 Track list continuation 001C 00 Same hardware device 001D 0094 Data Chunk pointer (LE) 001F 0012 Data Chunk length (LE) 0021 FF Next track list 0022 0C for hardware device 0x0C 0023 00 Track list continuation 0024 00 Same hardware device 0025 003F Data Chunk pointer (LE) 0027 0013 Data Chunk length (LE) 0029 00 Track list continuation 002A 00 Same hardware device 002B 0052 Data Chunk pointer (LE) 002D 0018 Data Chunk length (LE) 002F FF Next track list 0030 13 for hardware device 0x13 0031 00 Track list continuation 0032 00 Same hardware device 0033 003F Data Chunk pointer (LE) 0035 0013 Data Chunk length (LE) 0037 00 Track list continuation 0038 00 Same hardware device 0039 007F Data Chunk pointer (LE) 003B 0015 Data Chunk length (LE) 003D FF FF Sequence Control - End of Sequence Blocks ------------------------------------------------------------ 003F 0F MIDI Track channel 15 (control channel) 0040 01 One note playing on track (probably just to satisfy the MIDI engine) 0041 MIDI Track data like SCI0 0052 02 MIDI Track channel 2 0053 02 Two notes playing on track 0054 MIDI Track data like SCI0 006A 03 MIDI Track channel 3 006B 01 One note playing on track 006C MIDI Track data like SCI0 007F 0A MIDI Track channel 10 0080 01 One note playing on track 0081 MIDI Track data like SCI0 0094 02 MIDI Track channel 2 0095 01 One note playing on track 0096 MIDI Track data like SCI0 Addendum (provided by Lars Skovlund) ------------------------------------ First of all, tracks do not loop individually. No loop signals are reported. Absolute cues are generally stored in the signal selector, and cumulative cues are generally stored in the dataInc selector, with some interesting twists: 1. The server's record of the absolute cue value is reset as part of UPDATE_CUES. 2. When a cumulative cue is reported to the VM object, it will be placed in _both_ fields. In such a case, a constant of 0x7f will be added to the _signal_ selector only, to be able to distinguish the two kinds of cue (this has already been coded). 3. The above only happens if the sound does not use absolute cues (i.e. if the signal is 0 a priori). Note that, because of 1) above, this does not cause problems neither with successive cumulative cues nor with mixed cumulative/absolute cues. 4. A signal of 0xff will stop the sound object playing. This may be for purely internal purposes. 5. There no longer is a field indicating the amount of increment for a cue.