-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathFS3MDOC.TXT
3450 lines (2823 loc) · 142 KB
/
FS3MDOC.TXT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* (tabstops=8)
°°°°°°°°°°°°°°±±±±±±±±±±±±±²²²²²²²²²²²²²²²²²²²²²²²²±±±±±±±±±±±±±°°°°°°°°°°°°°°
þ S3M Player Tutorial by FireLight þ Copyright (c) Brett Paterson 1994-95 þ
þ Last updated 20/11/95 þ
°°°°°°°°°°°°°°±±±±±±±±±±±±±²²²²²²²²²²²²²²²²²²²²²²²²±±±±±±±±±±±±±°°°°°°°°°°°°°°
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² : SECTION 0: ²±° ³
³ °±² Index ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Section 1 : INTRODUCTION
1.1 Notes.
1.2 Terminology.
1.3 Contacting FireLight and feedback.
Section 2 : THE LOADER
2.1 Notes.
2.2 Verification.
2.3 Load Module Name.
2.4 Rest of the Main Header - default/miscellaneous info.
2.5 Load channel settings
2.5.1 The 32 bytes.
2.5.2 Remapping the channels.
2.6 Load order data.
2.7 Parapointers.
2.8 Default pan positions.
2.8.1 Mono.
2.9 Instruments.
2.10 Loading pattern data.
2.10.1 Now 5 bytes?
2.11 Loading sample data.
Section 3 : EXTRA S3M FEATURES
3.1 Volume byte.
3.2 Panning.
3.3 New effects.
Section 4 : MORE PERIODS
4.1 Goodbye fine tune!!! - C2SPD.
4.2 9 octaves.
Section 5 : MISCELLANEOUS
5.1 The 10 steps in converting a MOD player to an S3M player.
5.2 Creating the ultimate internal format of your own.
Section 6 : EFFECTS
6.01 Quick Reference Chart
6.1 Effect Axx (Set speed)
6.2 Effect Bxx (Jump to order)
6.3 Effect Cxx (Break pattern to row)
6.4 Effect Dxx (Volume slide)
6.5 Effect Exx (Portamento Down)
6.6 Effect Fxx (Portamento Up)
6.7 Effect Gxx (Tone portamento)
6.8 Effect Hxy (Vibrato)
6.9 Effect Ixy (Tremor)
6.10 Effect Jxy (Arpeggio)
6.11 Effect Kxy (Vibrato + Volume slide)
6.12 Effect Lxy (Porta + Volume slide)
6.13 Effect Oxy (Set sample offset)
6.14 Effect Qxy (Retrig (+volumeslide) note)
6.15 Effect Rxy (Tremolo)
6.16 Effect Uxy (Fine Vibrato)
6.17 Effect S0x (Set filter)
6.18 Effect S1x (Set glissando control)
6.19 Effect S2x (Set finetune)
6.20 Effect S3x (Set vibrato waveform)
6.21 Effect S4x (Set tremolo waveform)
6.22 Effect S8x (Set channel pan position)
6.23 Effect SAx (Stereo control)
6.24 Effect SBx (Pattern loop)
6.25 Effect SCx (Notecut)
6.26 Effect SDx (Notedelay)
6.27 Effect SEx (Patterndelay)
6.28 Effect SFx (Funkrepeat)
6.29 Effect Txx (Set Tempo)
6.30 Effect Vxx (Set global volume)
Section 7 : APPENDIX
7.1 Notes
7.2 ScreamTracker 3 TECH.DOC (edited)
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² : SECTION 1: ²±° ³
³ °±² Introduction ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 1.1 Notes ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Assumptions:
============
Everything that was assumed in FMODDOC.TXT, and that you have actually
got a .MOD player working. I borrow from FMODDOC.TXT and even cut and paste
some of the parts.
Most of the theory and information about writing player code is found in
FMODDOC.TXT, this document is more about the actual S3M FILE format.
At this point I will just take the opportunity to say that coding a .MOD
player is quite beneficial, even though I hear you scoff and say who supports
.MOD any more? Well sorry to say but S3M in its playing theory borrows VERY,
VERY heavily from protracker, and if you code a .MOD player, it takes VERY
LITTLE effort to make that player an S3M player. My .MOD player took about
1 HOUR to convert to an S3M player after the loader, as the principles in
playing are very similar.
WRITE A MOD PLAYER FIRST THEN DO S3M, YOU WON'T REGRET IT.
S3M uses 90% of the .MOD effects, and as S3M has about 90% of .MOD lurking in the
background in other areas, I can't emphasize this enough. See section 5 on
the 10 simple steps in converting a MOD player to an S3M player to see what I
mean.
Your player will probably play the effects more accurately too if you get
it right under .MOD first, and then .S3M.
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 1.2 Terminology ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
TYPE LENGTH Bits RANGE WATCOM/BORLAND/TURBO C
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
byte 1 8 0-255 unsigned char
word 2 16 0-65,535 unsigned short
dword 4 32 0-4,294,967,295 unsigned long
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Throughout this text I use the terms BYTE,WORD, and DWORD, to make the
document more general to all languages. In C you can use typedefs to achieve
the use of byte,word,dword terminology, and in Pascal and asm the syntax is
already suited to this anyway.
ORDERS - orders are how the mod plays from 0 to length of song.
PATTERNS - patterns are played in any ORDER, and are the physical information.
TICK - I refer to a clock tick for the interrupt handler as a tick, some
others use the term FRAME. I will be using the term tick throughout the whole
document.
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 1.3 Contacting FireLight and feedback ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Contact is encouraged for any reason. After typing literally over 100
printed pages, I might have probably made some small mistakes here and there,
but I have proof read this document many many times and spell checked it etc.
email : [email protected]
post : Brett Paterson,
48/a Parr st,
Leongatha, 3953,
Victoria, Australia.
IRC : FireLight on #coders (#trax)
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² : SECTION 2 : ²±° ³
³ °±² The Loader ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 2.1 Notes ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
As S3M can be quite difficult to load for the inexperienced, I will explain
as much as possible about the quirkiness of this format and how to overcome
it.
If you have already written a .MOD loader, you will have to change your
storage variables around a little bit to compensate for S3M's new features.
The main differences are:
=========================
1. 32 channels
2. 9 octaves
3. volume column
4. a few extra effects
More about this will be discussed later on in the document, and see SECTION
5.1 on handling these differences.
As in FMODDOC.TXT I will split most sections into the following 4 sections,
to try and get optimal understanding of the matter.
- EXPLANATION (describes what the section is on about, for understanding)
- PSEUDOCODE (usually shows HOW to code it, but in English)
- STORAGE ISSUE (helps on how to store the information loaded)
- SUGGESTION (a helpful hint or suggestion to do after this step)
NOTE: Remember to follow this document along side TECH.DOC's map out of an
S3M file. (TECH.DOC is kept in the appendix at the end of this
document). It will make things easier to visualise. I'm not here to
re-write tech.doc but to explain how things work.
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 2.2 Verification ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Explanation:
============
Before we attempt to load a the S3M, we should check that it is in fact an
S3M.
Every S3M has a signature stored inside the file at offset 44 (2Ch), and
this should always be checked first.
PseudoCode:
===========
- Seek to offset 44 (2Ch) in the file
- read in 4 bytes
- compare them to "SCRM" - if it is a match we have an S3M file (apparently)
- otherwise exit and display error message.
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 2.3 Load Module Name ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Explanation:
============
This is a trivial part of the loader and just holds the Title or name of the
mod. It is the very first 28 bytes of the MOD.
PsuedoCode:
===========
- Seek back to position 0, the start of the file
- read in 28 bytes, store as MODULE_NAME.
Storage Issue:
==============
If your system originally was set up to hold a 20byte name for a module title,
then extend this to 28 bytes.
Suggestion:
===========
As always this point is a good time to see if it worked by printing out what
you read in and seeing if it is correct.
Note:
=====
From this point on I won't be going into as much detail or length for trivial
matters like this, but I will still make sure it is understood with a brief
explanation.
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 2.4 Rest of the Main Header - default/miscellaneous information ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Explanation:
============
With a .MOD loader, normally at this stage we would be now getting ready
to load in the 31 lots of sample information, but in S3M's case we have
a lot of other miscellaneous information we want to know first. These sorts
of things are default panning positions, global volume, initial tempo etc,
etc. This section covers these miscellaneous parts and explains what to
do with them.
Breaking away from the usual format I will display this section in more of
a map format, with the file offset and bytes to read displayed along with
a short description.
So after you have read in the name of the module, the following information
is stored in this order. "Size" is how much info to read in, in BYTES.
Remember when reading in a WORD, you should read it straight to the address
of the variable like so, 2 bytes at a time.
i.e. fread(&songlength, 2, 1, handle); (excuse my C).
Otherwise find out the proper value with (byte1*100h + byte2).
ÄÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Offset ³ Size³ Explanation.
ÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
0 ³ 28 ³ SONG NAME, you should already have loaded this.
28 (1Ch)³ 1 ³ 1Ah. This should be the hex value 1Ah. But sometimes it
³ ³ isn't. It's main purpose seems to be an end of file marker
³ ³ for using 'TYPE' under DOS. If you do a 'TYPE NAME.S3M' it
³ ³ will display the name of the song then go no further.
29 (1Dh)³ 1 ³ FILETYPE. This should be the FILETYPE. If it is 16, then it
³ ³ is an ST3 module. I don't know what else it might be unless
³ ³ it is for tracker identification (trackers that might write to
³ ³ S3M - heh as if!..
³ ³ .. reading the file is bad enough, but writing it is horror!)
30 (1Eh)³ 2 ³ These 2 bytes are currently for EXPANSION and can be ignored.
32 (20h)³ 2 ³ SONG LENGTH, or number of orders which count from 0 to this.
³ ³ See the order SECTION 2.6 for more on this because this
³ ³ figure is not entirely accurate.
34 (22h)³ 2 ³ NUMBER OF INSTRUMENTS.
³ ³ This is a new concept if you have coded a .MOD player as it
³ ³ is usually always 31. Add a NUM_INSTRUMENTS type variable to
³ ³ your routines now, and when loading mods just set it to 31 all
³ ³ the time. For S3M this will hold the number of samples we
³ ³ will be loading later on.
36 (24h)³ 2 ³ NUMBER OF PATTERNS. This part is the number of physical
³ ³ patterns stored in the file, regardless of how many orders
³ ³ there are. This figure isn't always the best method of
³ ³ finding out how many patterns there are in the song, as it
³ ³ also includes marker patterns etc, which have no pattern data.
³ ³ See SECTION 2.6 to find out more about this.
³ ³ (Remember to store this figure though as you MUST use it to
³ ³ know how many parapointers to load later.)
38 (26h)³ 2 ³ FLAGS. This is the flags section. You need to bitwise AND
³ ³ it with the following values to see if the corresponding flags
³ ³ are set. Most of them are for Scream Tracker specific
³ ³ information so can just about be ignored if you like.
³ ³ if ((value AND 1) >0) : st2vibrato (not supported in st3.01)
³ ³ if ((value AND 2) >0) : st2tempo (not supported in st3.01)
³ ³ if ((value AND 4) >0) : amigaslides (not supported in st3.01)
³ ³ if ((value AND 32) >0) : enable filter/sfx (not supported)
³ ³ if ((value AND 8) >0) : 0vol optimizations: Automatically
³ ³ turn off looping notes whose volume
³ ³ is 0 for >2 note rows. Don't bother
³ ³ with this.
³ ³ if ((value AND 16) >0) : amiga limits: Disallow any notes
³ ³ that go beyond the amiga hardware
³ ³ limits (like amiga does). This means
³ ³ that sliding up stops at B-5 etc.
³ ³ This also affects some minor amiga
³ ³ compatibility issues.
³ ³ if ((value AND 64) >0) : st3.00 volumeslides. Normally
³ ³ volumeslide is NOT performed on first
³ ³ frame of each row (this is according
³ ³ to amiga playing). If this is set,
³ ³ volumeslide is performed ALSO on the
³ ³ first row. This is set by default if
³ ³ the CWT/V value is 1300h.
³ ³ if ((value AND 128) >0): special custom data in file. If
³ ³ this is set then you can use the
³ ³ 'Special' pointer at offset 3Eh.
³ ³ See more about this when describing
³ ³ this special pointer.
40 (28h)³ 2 ³ CWT/V. This means 'Created with tracker / version'.
³ ³ It just tells us the tracker version used to write the tune.
³ ³ The upper 4 bits are the tracker, and the bottom 12 bits are
³ ³ the version. So to get the version, bitwise AND it with FFFh,
³ ³ and to find the tracker value, SHIFT RIGHT the value 12 bits.
³ ³ These are the values that are possible from scream tracker.
³ ³ ST3.00 : 1300h (NOTE: volumeslides on EVERY frame)
³ ³ ST3.01 : 1301h
³ ³ ST3.03 : 1303h
³ ³ ST3.20 : 1320h
³ ³ The part where it said volumeslides on every frame, is
³ ³ explained further in the effects section, SECTION 6.7
42 (2Ah)³ 2 ³ This part tells us whether the file stores its samples in
³ ³ unsigned format, or signed format. Remember this for loading
³ ³ your samples in later, but you don't really have to bother as
³ ³ they're usually unsigned. 1 = signed samples, 2 = unsigned.
44 (2Ch)³ 4 ³ 'SCRM' Here we are again at the "SCRM" signature. check this
³ ³ again or ignore it as you like.
48 (30h)³ 1 ³ GLOBAL VOLUME. You must have a global volume variable if you
³ ³ want to support S3M fully, and you may already have it in
³ ³ your .MOD player if you have a master volume switch.
³ ³ Global volume is quite simple, it just means when setting
³ ³ volumes while your mod is playing, you need to multiply the
³ ³ volume to be set by your global volume, then divide it by 64.
³ ³ i.e. final volume = volume[track]*globalvol/64 (from FMOD1.06)
49 (31h)³ 1 ³ INITIAL SPEED. This is the default speed to start at when
³ ³ playing your mod. Usually with a .MOD player we always set
³ ³ the default speed to 6, but with S3M we set it to this value.
³ ³ Speed means the number of clock ticks between each row, see
³ ³ FMODDOC.TXT for more information on ticks/frames/speed etc.
50 (32h)³ 1 ³ INITIAL TEMPO. This is the default tempo to start at when
³ ³ playing your mod. Usually with a .MOD player we always set
³ ³ the default speed to 125 (7Dh), but with S3M we set it to
³ ³ this value. Tempo means the speed we have the interrupt
³ ³ handler ticking, and in ticks per second we use the formula
³ ³ HZ = (SPEED*2)/5 to set our timer. See FMODDOC.TXT for more
³ ³ on this.
51 (33h)³ 1 ³ MASTER VOLUME. The lower 7 bits of this are the master
³ ³ volume. How is the master volume different to the global
³ ³ volume you ask? Well the master volume only affects the
³ ³ SoundBlaster, and the amount of sample multiplication.
³ ³ See FSBDOC.TXT for more information on SoundBlaster Mixing.
³ ³
³ ³ As this is the lower 7 bits, then high 8th bit is the
³ ³ stereo flag. To get this value shift the number right by
³ ³ 7 bits. If the bit is set (1), then we use stereo as normal,
³ ³ if it is not set (0), then we use mono. Mono is achieved by
³ ³ setting all panning values to the middle.
³ ³ See SECTION 2.8.1 for more on this.
52 (34h)³ 1 ³ ULTRACLICK REMOVAL. This is fairly ScreamTracker specific
³ ³ flag and should most definately be ignored. You should have
³ ³ your own Ultraclick removal system instead of PSi's method.
³ ³ The value divided by 2 is meant to be the guaranteed number
³ ³ of channels which are to be click free. Your player should
³ ³ have all channels click free though. (using interrupt driven
³ ³ ramping for example.)
³ ³ For more information on his method see the relevant section
³ ³ in the APPENDIX at the end of this document which contains
³ ³ TECH.DOC from ST3.
53 (35h)³ 1 ³ DEFAULT PANNING. This is the flag that tells us if we are
³ ³ using default panning or not.
³ ³ If the value = 252, then we use the default panning values
³ ³ stored later on in this file. They are described in Section
³ ³ 2.8 when we get to that position in the file.
³ ³ If it doesn't equal 252, then no attempt is made to load
³ ³ these panning values (most likely because they aren't there)
54 (36h)³ 8 ³ These 8 bytes are currently for EXPANSION and can be ignored.
62 (3Eh)³ 2 ³ SPECIAL. This is a pointer to special custom data (only if
³ ³ the special data flag was set at offset 38 (26h) in the file).
³ ³ As you have no idea what this data might be you can ignore it.
³ ³ It is mainly for your own use if you want to add some extra
³ ³ data in your own S3M writer I think.
ÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Once this is done we have all the information we have need to know about the
state that an S3M should be in before we start to play it. Now all we need
to do is load some channel settings, which is information specific to each
channel (like panning, and if it is disabled/enabled).
Suggestion:
===========
Now would be a good time to see if you loaded in your values right and check
which ones apply to you and which don't. A lot of them wont.
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 2.5 Load Channel Settings ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Explanation:
============
You were probably just asking then. WHERE WAS THE NUMBER OF CHANNELS VALUE??
Well this part will tell you that. This is about the biggest design flaw in
S3M I think and is a really messy way to do things. It is called the channel
settings.
The next 32 bytes are the settings for each channel. It tells us if a
channel is turned on, or off, and by counting all the channels that are
turned ON. This tells us how many channels that are used in total.
Say we have a 4 channel S3M. Normally you would expect it to save it like
this.
channels
0<ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ>31
0123--------------------------
but Scream Tracker 3 allows you to save a tune with channels enabled and
disabled, in this way for example. (using hex notation)
channels
0<ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ>31
--2----78-----E---------------
This way sees the first 2 channels as disabled, and then the 3rd channel
enabled and so on. It is still a 4 channel S3M, but it uses channels 2,7,8
and 14 to do it with!!
If you still don't understand this concept, then run ScreamTracker 3 and
experiment with it until you do.
So how do you find out how many channels there are in this tune? Well it
should be fairly obvious from these diagrams, that you just add 1 to a
counter every time you find a 'channel enabled' byte in the channel settings
are of the S3M - what we are reading right now.
So with our example, it would only increase the NUMBER_OF_CHANNELS variable
when it hits channel 2, 7, 8 and 14, thus telling us there is 4 channels.
The next section will explain how each of these 32 channel bytes work.
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 2.5.1 The 32 Bytes ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Explanation:
============
There are 32 bytes here. 1 byte per channel.
Read a byte. If it is smaller than 16 then its respective channel is enabled.
Otherwise it is disabled.
TECH.DOC from ST3 seems to say bit 8 set means that the channel is enabled.
This isn't true, it is only enabled if the byte is less than 16.
It most likely means that if bit 8 was set the channel is DISABLED, not
enabled.
255 = a channel is disabled, and so does any channel with bit 8 set. (i.e 128)
Pseudocode:
===========
for count = 0 to 31 {
read a byte
if (the byte is <16) CHANNELS = CHANNELS + 1
}
But wait!:
==========
But wait! there's more!
This byte also holds information if the channel is panned to the left or
the right.
- If the byte is smaller than or equal to 7, then it is panned to the LEFT
- if the byte is greater than 7 and smaller than 16, then it is panned to the
RIGHT.
This isn't panning information, it is information whether the channel is left
orientated, or right orientated. Panning comes later.
The usual default positions to pan channels to are 03h, and 0Ch.
(from an 00h-0Fh range)
Wait again! There's more!:
=========================
As the channels can be all over the place, it doesn't suit our 1234-----
type method. Let us now look at remapping the channels to suit our method.
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 2.5.2 Remapping the channels ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Let us look at our example again.
channels
0<ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ>31
--2----78-----E---------------
Everything from here in the actual S3M file, including pattern data is going
use these channel values, 2,7,8 and E instead of a normal 0,1,2,3.
What we have to do is remap the channel values into a more linear format
like 0123-------, so when S3M tells us it wants channel 2, it actually writes
to our channel 0, and if it asks for channel 7, then it actually writes to
our channel 1 etc.
The reason for this is that it would be stupid to allocate enough memory to
contain all channels up to 0Eh. It would be better to allocate only enough
for the 4 channels.
To do this we need to map the channels as we find them enabled like this.
channel value in file ³ what we want it to be stored as
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
2 ³ 0
7 ³ 1
8 ³ 2
14 ³ 3
The usual method is to declare a new 32 byte array called REMAP, for example,
and start looking for enabled channels. (by going through all 32 bytes in
the file)
- If an enabled channel is found, then use the channel number as the index to
your REMAP array, and store the current channel counter in it. ie. '0'.
so REMAP[2] = 0.
- If we find another channel, then use it as the index to the REMAP array,
and give it the new incremented channel counter. i.e. 1. so REMAP[7]=1
- If we find another channel, then use it as the index to the REMAP array,
and give it the new incremented channel counter. i.e. 1. so REMAP[8]=2
- If we find another channel, then use it as the index to the REMAP array,
and give it the new incremented channel counter. i.e. 1. so REMAP[14]=3
NOTE: The other remap values that are not used (i.e all those EXCEPT
2,7,8 and 14) should have previously been mapped to some impossible
value, i.e. 255, so we don't have any confusion later on.
Now we can safely reference the first channel of our system by looking up
the relevant remap value. So when an S3M file tells us it has something for
channel 2, it writes to our channel 0.
Pseudocode:
===========
declare a local 32 byte remap array called REMAP.
We are now at offset 64 (40h).
CHANNELS=0
set all 32 REMAP values to 255 first. (255 is an impossible channel value)
for count = 0 to 31 {
read a BYTE
if (the BYTE was < 16) then {
remap[count] = CHANNELS
if (the BYTE <= 7) then PAN_VALUE[CHANNELS] is panned to LEFT
else PAN_VALUE[CHANNELS] is panned to RIGHT
CHANNELS = CHANNELS + 1
}
}
Now we know how many channels are in the S3M, as we added 1 to CHANNELS every
time it was set, and also have set the pan values for each channel. 0,1,2 & 3.
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 2.6 Load Order Data ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Explanation:
============
This part is fairly simple. You read your order list in now, reading
SONG_LENGTH number of bytes, the length of the song in orders that we found
out in the main header at the start. (see SECTION 2.4)
Remember the order list is how the song plays the physical patterns, i.e.,
in what order it plays them in. See FMODDOC.TXT, and SECTION 2.5 for more
information on orders.
Earlier on I told you to ignore the NUMBER_OF_PATTERNS byte that was supplied
in the main header (SECTION 2.4), because it wasn't reliable. Well this is
the part where you actually find out the number of patterns for yourself,
by scanning through the order list and noting down the highest pattern number.
And that's it - the number of patterns.
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ You CAN just use the supplied figure, but you would be allocating extra ³
³ memory for patterns that aren't ever used, or that don't even exist. ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Apart from the actual pattern number, an order byte can have these two
values.
254 = Marker Pattern, ignored.
255 = End of Song Marker.
Pattern markers are just to be ignored, and an end of song marker tells us it
should be the end of the song. What does this mean? Well it means that even
though our original SONGLENGTH variable we read in was correct, it may
contain marker values and will have to be recalculated!
i.e., an order list is as follows.
ORDER 0 ³ 1 ³ 2 ³ 3 ³ 4 ³ 5 ³ 6 ³ 7
ÚÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ¿
PATTERN ³000³001³002³002³254³254³003³004³
ÀÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÙ
Now the header will tell us that the SONGLENGTH is 8 for this example. This
is right (0 - 7 including 0 equals 8 orders) but you see there are 2 marker
patterns (the ones stored as 254), and they shouldn't be counted. So this
means there are only really *6* orders that should be counted.
So now we need another variable to keep count of the actual songlength.
Look at the pseudocode below and see that I have used the variable A.
When it is finished reading the order bytes, then set the actual SONGLENGTH
to A.
We again have to do a form of remapping also, to REMOVE the marker patterns
from the order list. It is similar as we did in the channel settings
section, but isn't as complex though, it is just a matter of setting order A
to order COUNT.
A, will always be smaller or equal than COUNT, as A isn't incremented if it
encounters a marker pattern, but COUNT is.
Pseudocode:
===========
Should now be at offset 96 (60h).
A=0
for COUNT=0 to SONGLENGTH { <- songlength is the value we loaded 1st
if (ORDER[COUNT]<254) { <- if it is not a marker of any sort
ORDER[A] = ORDER[COUNT] <- this rewrites the order list
A = A + 1 <- now increment the actual songlength
if (ORDER[COUNT] > NUMBER_OF_PATTERNS) then
NUMBER_OF_PATTERNS = ORDER[COUNT] <- find highest pat#
}
}
SONG_LENGTH = A <- now we store the real song length
Storage issue:
==============
As it is possible to have 255 orders, an order array that is 256 or so bytes
big would be a good idea.
i.e. declare it as ORDER[256]
You will be safe with 256 orders as most songs are about 30 orders long and
never do they even approach the 256 mark. (Some reach the early 100's.)
Suggestion:
===========
Check your patterns/orders against a reliable player and see if you get the
same figures. It is pretty important to get right as you could do something
stupid like play past the end of your pattern data into garbage and it could
crash your player, or it could end the song too soon, i.e. before it should
stop.
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 2.7 Parapointers ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Explanation:
============
Before I explain how these work, you are probably wondering - what are they?
Well in S3M patterns and instruments are not saved in a rigid format like
.MOD, i.e. instruments, followed straight away by patterns.
In S3M they can literally be anywhere in the file, but they are all pointed
too by these 'parapointers'.
You must load these parapointers temporarily to find out where each
instrument and pattern is in the file.
The section in the file we are at now, contains these parapointers.
Instrument Parapointers:
========================
The first set of parapointers encountered in the file are the instrument
parapointers. The number of parapointers is the same as the number of
instruments (of course).
Each parapointer is stored as 2 bytes (a WORD), so the length in bytes for
the instrument parapointer field is NUMBER_OF_INSTRUMENTS * 2.
Store these away for later, using a WORD per parapointer.
See the storage issue below on information about storing the parapointers.
Pattern Parapointers:
=====================
After the instrument parapointers follow the pattern parapointers. They are
again 2 bytes each, and the number of pattern parapointers is the same as
the NUMBER_OF_PATTERNS byte read from the header, NOT any value you might
have calculated after throwing out marker patterns etc.
As an offset in the file:
=========================
To use the parapointers as a relevant value for the offset in the file,
multiply it by 16, or shift it left 4 bits, and that is where the start of
the data for that particular instrument or pattern is!
Storage issue:
==============
For the instrument and pattern parapointers, you could just declare an array
of WORDs that can hold them all, say 99 for instruments, and 256 for patterns.
this would require a 355 WORD array.
Another way to do it is dynamically declaring a pointer to store these
parapointers, and allocate only enough memory to hold all the parapointers.
This is pretty pedantic though, as 710 bytes is not a lot to allocate
locally/temporarily.
Conclusion:
===========
So in effect the number of bytes to read for the parapointer section is.
(NUMBER_OF_INSTRUMENTS + NUMBER_OF_PATTERNS) * 2
and,
To use them shift them left 4 bits, or multiply it by 16.
Remember again, these 2 values (NUMBER_OF_INSTRUMENTS and NUMBER_OF_PATTERNS)
are the values read in from the header at the start, not your final figures
that might have discarded marker patterns etc.
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 2.8 Default pan positions ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Once the parapointers have been loaded for later, there is the next section
in S3M that contains the default panning.
In the main header the default panning byte was read (d.p). If it was 252
(which is incidentally FC in hexadecimal - har har), then you are allowed to
read 32 bytes of panning information for each channel.
If it is not 252, then it is not read and the next section is jumped to.
Reading the panning bytes:
==========================
Its not just as simple as reading in the pan values, no, PSI decided to make
the pan values the bottom 4 bits of each byte, while the top 4 bits could
contain any garbage.. I'm still not sure why you would save a format like
this. (shrug).
Anyway. Just bitwise AND each byte with 0Fh (15), to get the bottom 4 bits.
Of course this means the pan values are from 0 to 15, considering it supports
only 16 position panning.
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 2.8.1 Mono ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
At this point it is the perfect time to check if bit 8 from the master volume
byte in main header was set. If it WASN'T (0), then the mono flag in ST3 was
set and all the panning values should be set to the MIDDLE, regardless of any
other panning information given before.
If the bit WAS set (1) then it should be stereo as normal and no further
action is taken.
Basic ways to check this bit are:
=================================
if ((mastervol AND 128) == 0) make song mono
if ((mastervol SHR 7) == 0) make song mono
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 2.9 Instruments ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
It is time to read in the instrument information. This is the first useful
data that we will be reading in now.
Remember SECTION 2.7 - parapointers, because this is where we first use them.
Reading an instrument is performed in the following fashion.
- Use a file SEEK function to skip to the value pointed to by the parapointer
value * 16. So seek to the relevant offset given by
offset = parapointer[instnumber] * 16.
(instnumber is the number of the instrument you are loading)
Now read the following information in this order once for every instrument.
In the following table, the term 'Offset' is described as relevant to the
given parapointer offset, and not the start of the file. They are displayed
as the decimal value first, followed by the hexadecimal value.
ÄÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Offset ³ Size³ Explanation.
ÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+0 00h³ 1 ³ TYPE - can equal 1 for sample, 2 for adlib melody, and 3 for
³ ³ adlib drum. We are only concerned about digital music
³ ³ here and want it to be 1, or 'sample'.
+1 01h³ 12 ³ DOS FILENAME - this is a 12 byte DOS filename and can be
³ ³ safely ignored.
+13 0Dh³ 3 ³ *MEMSEG - this section is explained below due to complexity.
ÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
* MEMSEG:
Memseg is another sort of parapointer to the actual sample data. You use it
to find out where to read in the sample data from. To get the real value you
multiply it by 16 again as you did with normal parapointers.
The only problem with it, is that it is stored as a 3 byte value.
The first byte is the upper part of the value, while the next 2 bytes are the
lower word of the value.
To get the real offset in bytes use the following method.
1. read a BYTE into PART1
2. read a WORD into PART2
3. sample_pos = (PART1 SHL 16) + PART2
You could also use this method reading 1 byte at a time.
1. read a byte into PART1
2. read a byte into PART2
3. read a byte into PART3
4. sample_pos = (PART1 SHL 16) + (PART3 SHL 8) + PART2
Storage issue:
==============
Just use an array of 99 words, one for each sample which should be perfectly
adequate.
Suggestion:
===========
When it is time to load these samples (you could actually do it now if you
like - but it is better to first see if there is enough memory for pattern
data before waiting for a long sample load), remember to multiply it by 16
to get the real offset in the file, and seek to it for each sample.
Now Continuing with the map of the instrument..
ÄÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Offset ³ Size³ Explanation.
ÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+13 0Dh³ 3 ³ MEMSEG - covered this just before..
+16 10h³ 4 ³ SAMPLE LENGTH - This is stored as a 4 byte value but as ST3
³ ³ only supported 64kb samples, the first 2 bytes are used and
³ ³ the second 2 bytes are discarded (high part).
³ ³ So read a word, this is the sample length, and skip a word
³ ³ as they are never used.
+20 14h³ 2+2 ³ LOOP BEGIN - This is stored as a 4 byte value also, but ST3
³ ³ only supports 64kb samples, so the first 2 bytes are used and
³ ³ the second 2 bytes are discarded (high part).
³ ³ So read a word, this is the sample length, and skip a word
³ ³ as they are never used.
³ ³ Even if a sample has loop points, it does not mean that it is
³ ³ a looping sample. The [F] flags byte below tells us if the
³ ³ sample loops or not.
+24 18h³ 2+2 ³ LOOP END - This is stored as a 4 byte value also, but ST3
³ ³ only supports 64kb samples, so the first 2 bytes are used and
³ ³ the second 2 bytes are discarded (high part).
³ ³ So read a word, this is the sample length, and skip a word
³ ³ as they are never used.
³ ³ Even if a sample has loop points, it doesn't mean that it is
³ ³ a looping sample. The [F] flags byte below tells us if the
³ ³ sample loops or not.
+28 1Ch³ 1 ³ VOLUME - this is the default volume of the sample. Read 1
³ ³ byte and store it as the sample's default volume.
+29 1Dh³ 1 ³ x - skip this byte it is unused
+30 1Eh³ 1 ³ [P] - PACKING SCHEME. All S3M's should have unpacked samples
³ ³ so this byte should normally be 0. No info is supplied on
³ ³ DP3's packing method anyway. (if it ever existed)
³ ³ 0 = unpacked
³ ³ 1 = DP30ADPCM packing
+31 1Fh³ 1 ³ [F] - FLAGS - There is only 1 value that should be checked
³ ³ here and that is the LOOP flag. It is checked by bitwise
³ ³ AND'ing it with 1. If the result is 1 then it is looped,
³ ³ otherwise it is not. The full range of bits are shown below.
³ ³ Stereo and 16 bit samples are not supported by ST3, so don't
³ ³ take any notice of them. (you may want to support 16 bit tho)
³ ³ BYTE AND 1 = Loop on.
³ ³ BYTE AND 2 = Stereo sample (not supported)
³ ³ BYTE AND 4 = 16 Bit sample (not supported)
+32 20h³ 2+2 ³ C2SPD - This is the Middle C rate in HZ of the sample. It is
³ ³ used instead of finetuning from .MOD, and is explained in more
³ ³ detail in SECTION 4.1.
³ ³ ST3 only uses the first WORD (first 2 bytes), to store the
³ ³ C2SPD in, so ignore the second WORD (3rd and 4th byte).
+36 24h³ 12 ³ UNUSED bytes. ST3 may store values in here but they are
³ ³ totally irrelevant to us. Some of the values that ST3 stores
³ ³ here are things like where to position the sample in the GUS
³ ³ etc. Hopefully you will ignore this and put them wherever
³ ³ you like. See TECH.DOC for more on this useless information.
+48 30h³ 28 ³ SAMPLE NAME - This is the name of the sample and should be
³ ³ stored if you are prepared to print it out for an interface.
+76 4Ch³ 4 ³ 'SCRS' label. This is here mainly for verification. Check
³ ³ that these 4 bytes are indeed 'SCRS' if you feel the need.
ÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Storage Issue:
==============
In this case it might be better to use a more dynamic system of instrument
storage, instead of rigidly having an array of 99 instrument structures like
was used in .MOD (31 in that case).
Especially seeing as though S3M can actually have a variable number of
instruments, using memory for instruments that are not used is wasteful.
If you are considering expanding to bigger formats like XM, then it is
fairly necessary considering XM can contain 256 instruments which are rather
large in themselves.
Make the instrument structure a pointer to a structure instead, and allocate
memory dynamically for it as it comes along, and deallocate the memory when
the song is stopped.
Suggestion:
===========
Make sure all your values are loaded in properly by printing them out one
after the other, and comparing them with Scream Tracker 3 or any other
reputable player. (I wouldn't compare the sample lengths to FMOD, as FMOD
clips samples at their loop end points - but otherwise FMOD is fine)
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ °±² 2.10 Loading pattern data ²±° ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
This is the "trickiest" part of loading S3M, although it isn't very hard if
you set it out logically.
Each pattern consists of 64 rows, and the number of channels is defined by
the value you worked out previously.
If you are using one big pattern data buffer, then is time to allocate the
memory for all of your pattern data buffer. The size of the buffer must be
determined first.
ie. NUMBER_OF_PATTERNS * CHANNELS * 64 * 5. (5 if you use 5 bytes per note)
See SECTION 2.10.1 for more information on why 5 it should be bytes per note.
Otherwise if you are using separate pattern buffers, ie one buffer for each
pattern, then you should be allocating each pattern as it comes along, using
the same formula above but removing the NUMBER_OF_PATTERNS part.
ie. CHANNELS * 64 * 5.
See FMODDOC.TXT and SECTION 2.6 for more information on issues concerning
pattern storage.
Remember to only load and allocate memory for the number of patterns you
worked out previously, skipping marker patterns. If you include marker
patterns then you are allocating memory that is never used and is wasted.
See SECTION 2.6 on more about skipping marker patterns etc.
Reading a pattern:
==================
At this point in the file you should be seeking to each pattern as it comes,
using the pattern parapointers.
If you stored the instrument parapointers and the pattern parapointers in the
one parapointer array, then of course the pattern parapointers come after the
instrument parapointers. So start checking the parapointers from the offset
given by the NUMBER_OF_INSTRUMENTS+1, as this is where the pattern
parapointers would begin.
Then do the same by looping NUMBER_OF_PATTERNS number of times, seeking to
each parapointer value multiplied by 16 each time.
Now here is some information on how to read in 1 pattern. Repeat this
process for as many times as there are patterns.
Top of the pattern:
===================
Read 2 bytes. This is the length of the packed pattern data. This doesn't
usually need to be bothered with as you know when to stop
after reading 64 rows worth of data.
This value is usually in case you want to read in the whole
packed pattern into memory first, and then unpack it from
memory, not disk.
Now repeat from here until you have reached row 64:
===================================================
Read 1 byte. If this is 0 then the end of the row has been read, increment
the row to the next one and repeat this step.
If row 64 has been reached, then start again from the top.
If row 64 still hasn't been reached and the byte is > 0 then continue below.
AND the byte with 31. This is the channel the following information belongs
too....
AND the byte with 32. If this is bigger than 0, then 2 more bytes follow to
be read. The NOTE value, and the INSTRUMENT number.
AND the byte with 64. If this is bigger than 0, then 1 more byte follows to
be read. This is the VOLUME BYTE value.
AND the byte with 128. If this is bigger than 0, then 2 more bytes follow to
be read. The EFFECT number, and the EFFECT_PARAMETER.
Channels Remapped:
==================
Simple huh, but remember about the REMAPPED CHANNELS, if you have done so.
Remember SECTION 2.5.2 and how S3M allows the song to be written using any
channels you like from 1 to 32, but take the example - as long as only
channels 4 and 15 are used, it is only a 2 channel song.
Our method was to remap these used channels into a linear format that goes
in order from 0,1,2,3 onwards. So from above, 4 would be remapped to 0, and
15 would be remapped to 1.
This was achieved by using an array of remap values, and each literal used
channel value contained the linear value of the channel.
ie.
REMAP[0] = 255 <-- impossible value
REMAP[1] = 255 <-- impossible value
REMAP[2] = 255 <-- impossible value
REMAP[3] = 255 <-- impossible value