HOW THE MUSIC WORKS

The demo ships two S3M modules by Purple Motion and plays them through STMIK, Future Crew's own player, resident in memory across every part. The port replaces STMIK with libopenmpt in an AudioWorklet, but everything around it is reproduced.

IT IS COPY-PROTECTED

The .s3m files in the release are scrambled. Each pattern's data is XORed with a key derived from its byte offset, so the files load in a tracker as garbage. STARTMUS.C unscrambles them in memory at start-up; the port runs the same routine in the browser before the bytes reach the player. The files on disk are never modified.

THE TEMPO IS PATCHED AT RUNTIME

STARTMUS.C also writes one byte — module offset 50, the initial tempo — from 125 down to 120 BPM before playback. Every music-derived timing constant in the demo is therefore in patched time, 25/24 slower than the file suggests.

TWO MODULES, ONE TIMELINE

MUSIC0 carries the intro. The loader itself, not any part, switches to MUSIC1 the instant the title logo finishes — so the demo's clock is MUSIC0's elapsed time up to that point and MUSIC1's after it.

HOW THE PORT UNSCRAMBLES IT

The .s3m files in unreal2/assets/ are the release's own bytes, still scrambled. Nothing was unscrambled and checked in — the demo would not be shipping its own protection if it had been. The whole sequence happens after the fetch, in this order:

  1. patch      byte 50 = 0x78. The tempo patch, before anything
                else, because every later number is in patched time.

  2. descramble walk the pattern-pointer table at 0x60 + orders +
                instruments*2, and for each pattern XOR its body
                with the keystream STARTMUS.C used:

                    n = (i >> 1) + 1
                    key(i) = ((n ^ (n >> 2)) << 3) | ((5i + 2) & 7)

                i counts from the pattern's first byte, so the key
                restarts at every pattern.

  3. play       hand the descrambled buffer to libopenmpt running
                in an AudioWorklet, and read the clock back off the
                worklet's reported position.

The buffer is descrambled in place, in memory, exactly as STARTMUS.C did it — the file on disk is never rewritten. The same descramble() feeds the offline timeline simulator in s3msim.js, which is where the sync gates come from, so the music the browser plays and the music the timings were derived from cannot drift apart.

THE TRACKER ON THIS BOARD IS THE SAME ENGINE

The Play the music screen is a working ST3 playing these two modules, and it is not a second implementation of any of the above. It imports the demo's own pieces:

  the files      unreal2/assets/music0.s3m — the very bytes the
                 demo loads, still scrambled on disk
  descramble()   imported from s3msim.js, the same routine
  buildTimeline() also from s3msim.js, for exact song length
  the engine     libopenmpt in the same AudioWorklet

What it adds is a reader. s3msim.js decodes only the cells that affect tempo, because tempo is all the demo needs to know to place its gates; a pattern display needs notes, instruments, volumes and effects, so the tracker page carries a full S3M parser of its own.

The display is slaved to the audio, the same trick the demo's visuals use. The worklet reports its order, pattern and row back on every audio block, and the highlighted row is whatever that feed says — so what you are watching is the playing position, not a re-simulation of it running alongside and hoping to agree. The same reason the demo's wipes land on the beat is the reason this cursor lands on the right row.