[Back to SOUND SWAG index]  [Back to Main SWAG index]  [Original]

{
From: jurip@clinet.fi (Juri Pakaste)

Hopefully someone here has experience reading S3M headers...
I'm trying to read the S3M header. I get the name right, I think
I get the number of instruments right, but I can't get the number
of patterns right. If I understand correctly the file which comes
with Scream Tracker 3.01 (see below), the number of patterns
should be located in bytes 35-36 (why on earth two bytes? Who
would use over 255 patterns?). The numbers I get have nothing to
do with numbers DMP and Inertia Player give, though. My little test-
program, S3MREAD.EXE, tells me, for example, that a module that has
55 (I think) patterns, has in fact 99. Just great. Some of the values
it gives manage to get pretty near the ones DMP and IPlay give,
but... you get the idea.

Here is there relevant part of S3M technical documentation:

------------------------------------8<----------------------------------
 
                                Song/Module header
          0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
        -----------------------------------------------------------------
  0000: | Song name, max 28 chars (incl. NUL)                           |
        |---------------------------------------------------------------|
  0010: |                                               |1Ah|Typ| x | x |
        |---------------------------------------------------------------|
  0020: |OrdNum |InsNum |PatNum | Flags | Cwt/v |  Ffv  |'S'|'C'|'R'|'M'|
        |---------------------------------------------------------------|
  0030: |m.v|i.s|i.t|m.m| x | x | x | x | x | x | x | x | x | x | x | x |
        |---------------------------------------------------------------|
  0040: |Channel settings for 32 channels, 255=unused,+128=disabled     |
        |---------------------------------------------------------------|
  0050: |                                                               |
        |---------------------------------------------------------------|
  0060: |Orders; length=OrdNum (must be even)                           |
        |---------------------------------------------------------------|
  xxxx: |Parapointers to instruments; length=InsNum*2                   |
        |---------------------------------------------------------------|
  xxxx: |Parapointers to patterns; length=PatNum*2                      |
        -----------------------------------------------------------------

 
        Typ     = File type: 16=module,17=song
        Ordnum  = Number of orders in file
        Insnum  = Number of instruments in file
        Patnum  = Number of patterns in file
        Cwt/v   = Created with tracker / version: &0xfff=version, >>12=tracker
                        ST30:0x1300
        Ffv     = File format version;
                        1=original
                        2=original BUT samples unsigned
        Parapointers are OFFSET/16 relative to the beginning of the header.
 
        PLAYING AFFECTORS / INITIALIZERS:
        Flags   =  +1:st2vibrato 
                   +2:st2tempo
                   +4:amigaslides
                   +8:0vol optimizations
                   +16:amiga limits
                   +32:enable filter/sfx
        m.v     = master volume
        m.m     = master multiplier (&15) + stereo(=+16)
        i.s     = initial speed (command A)
        i.t     = initial tempo (command T)
 
        Channel types:
        &128=on, &127=type: (127=unused)
        8  - L-Adlib-Melody 1 (A1)      0  - L-Sample 1 (S1)
        9  - L-Adlib-Melody 2 (A2)      1  - L-Sample 2 (S2)
        10 - L-Adlib-Melody 3 (A3)      2  - L-Sample 3 (S3)
        11 - L-Adlib-Melody 4 (A4)      3  - L-Sample 4 (S4)
        12 - L-Adlib-Melody 5 (A5)      4  - R-Sample 5 (S5)
        13 - L-Adlib-Melody 6 (A6)      5  - R-Sample 6 (S6)
        14 - L-Adlib-Melody 7 (A7)      6  - R-Sample 7 (S7)
        15 - L-Adlib-Melody 8 (A8)      7  - R-Sample 8 (S8)
        16 - L-Adlib-Melody 9 (A9)
                                        26 - L-Adlib-Bassdrum (AB)
        17 - R-Adlib-Melody 1 (B1)      27 - L-Adlib-Snare    (AS)
        18 - R-Adlib-Melody 2 (B2)      28 - L-Adlib-Tom      (AT)
        19 - R-Adlib-Melody 3 (B3)      29 - L-Adlib-Cymbal   (AC)
        20 - R-Adlib-Melody 4 (B4)      30 - L-Adlib-Hihat    (AH)
        21 - R-Adlib-Melody 5 (B5)      31 - R-Adlib-Bassdrum (BB)
        22 - R-Adlib-Melody 6 (B6)      32 - R-Adlib-Snare    (BS)
        23 - R-Adlib-Melody 7 (B7)      33 - R-Adlib-Tom      (BT)
        24 - R-Adlib-Melody 8 (B8)      34 - R-Adlib-Cymbal   (BC)
        25 - R-Adlib-Melody 9 (B9)      35 - R-Adlib-Hihat    (BH)

So, shouldn't this piece of code be able to read the name,
number of instruments and number of patterns right:

}
Program S3MReader;
Var
   NameArray       :       Array [1..28] Of Char;
   InstrArray, PatArray : Array [1..2] Of Byte;
   InstrByte, PatByte   :       Byte;
   f : File;
   i       :       Integer;
   j       :       Integer;
   S3MName :       String;

Begin
   WriteLn;
   WriteLn;
   If ParamCount = 1 Then
   Begin
      Assign(f,ParamStr(1));
      Reset(f,1);
      BlockRead(f,NameArray,28,i);
      For j := 1 To 28 Do S3MName := S3MName + NameArray[j];
      j := 28;
      While (Ord(S3MName[Length(S3MName)]) = 0) Or (Ord(S3MName
   (continues...)[Length(S3MName)]) = 32) Do
      Begin
         j := j - 1;
         S3MName[0] := Chr(j);
      End;
      Seek(f,33);
      BlockRead(f,InstrArray,2,i);
      InstrByte := InstrArray[1] + InstrArray[2];
      BlockRead(f,PatArray,2,i);
      PatByte := PatArray[1] + PatArray[2];
      WriteLn('Name: ',S3MName);
      WriteLn('Number of instruments: ',InstrByte);
      WriteLn('Number of patterns: ',PatByte);
      Close(f);
   End;
End.


[Back to SOUND SWAG index]  [Back to Main SWAG index]  [Original]