'=========================================================================== ' Subject: S3M FILE FORMAT Date: Unknown Date (00:00) ' Author: Unknown Author(s) Code: TEXT ' Origin: S3M,FORMAT Packet: SOUND.ABC '=========================================================================== Here's the S3M file format.. offset in file length description 0 28 name of song 28 2 WORD - 1A10H (can be used to identify) 30 2 ? (Unknown!) 32 2 Sequence table length. 34 2 # of instruments. 36 2 # of patterns. 38 6 filler (?) 44 4 BYTE - "SCRM" (ID) 48 1 Volume (range is UNKNOWN) 49 1 Tempo (6 in 6/125) 50 1 BPM (125 in 6/125, divide by 2.5 to get divisor) 51 13 filler 64 32 Channel maps. Channel map: Logical voice = offset into channel map. Voices 0-7 = LEFT speaker, Voices 8-15 = RIGHT speaker. FF means that the voice is OFF. (Try getting into PANIC and changing the table.) 96 sequencelen Sequence table - BYTE, FF=pattern N/A. 96+sequencelen nInst*2 Instrument pointer table. NOTE though that these pointers point to the 32- byte information section and NOT the instrument itself - WORD. SHL 4 to get actual offset. 96+sequencelen+nInst*2 nPatt*2 Pattern pointer table. Same as Instrument pointer table except that these point to ACTUAL patterns. Padded to paragraph boundary with 80h. Instrument information section: Relative offset length description 0 1 Boolean flag - if instrument is used. 1 13 BYTE - DOS name. 14 2 Absolute pointer to Instrument SHR 4. 16 4 DWORD - size in bytes. 20 4 DWORD - repeat start. 24 4 DWORD - repeat END. (Not LENGTH!) 28 2 WORD - volume. (Max 64) 30 1 filler (?) 31 1 Boolean flag - instrument looped? 32 2 C-2 Hz/finetune. (1) 34 14 filler 48 28 BYTE - instrument name. 76 4 BYTE - "SCRS". Pattern reading: Start of pattern: There is a word at the very beginning. That is the pattern size in bytes. Subtract 2 to get ACTUAL length after word. (logic START) Loop01: Read byte at location & increment pointer. (OPTIONAL - decrement length; each pattern is ALWAYS 64-rows long.) Byte is bitmapped: bits 0-4 = channel # (0-31). (See it REALLY was a 32-channel format!) bit 5 = 0=no note event, 1=note event. bit 6 = 0=no vol. event, 1=vol. event. bit 7 = 0=no effect, 1=effect. (DO IN ORDER) If bit 5=1 then read 2 bytes & increment pointer. First byte = note - upper 4 bits=octave, lower 4=note. NOTE MUST NOT EXCEED 0BH. Subtract 2 from octave to get ACTUAL octave. Second byte = sample. If bit 6=1 then read byte & increment pointer. Byte = volume. Max=40h. If bit 7=1 then read 2 bytes & increment pointer. Second byte=effect argument. First byte = effect. Effect map is after this. Loop to Loop01 until bitmapped byte = 00. Then increment row. Loop until 64 rows are read and/or End of Pattern. Instruments follow Patterns. They are in unsigned (signed? whatever, they'll play properly without modification on a SB) format. Effect map: 00 = ? 01 = Set tempo 02 = Jump pattern 03 = End pattern 04 = Volume Slide. If lower 4 bits of ARGUMENT are SET & the argument is > 0FH, then this is a fine Volume Slide UP and upper 4 = argument. If upper 4 bits are SET, this is a fine volume slide DOWN and lower 4 = argument. If neither conditions are met, then this is a normal volume slide (upper 4=amount up and lower 4=amount down.) 05 = Porta down. If upper 4 are set then this is FINE and lower 4 = argument, otherwise this is a normal porta down. 06 = Porta up. Same with porta down. 07 = Porta to Note. Same as ProTracker. 08 = Vibrato. Same as ProTracker. 09 = Tremolo. Same as ProTracker. 0A = Arppegio. Same as SoundTracker. 0B = Tone/Vibrato + Volume. 0C = same as 0B I think. 0D = ? 0E = ? 0F = Sample Offset. 10-13 = ? 14 = Set BPM. 15-FF = ? NOTE: Patterns, Instrument definitions, and Instruments all start on paragraph boundaries.