Music: Marshall Mathers, Dido Armstrong, and Paul Herman
General
This is a new BBC music demo of Eminem's STAN featuring lyrics being displayed in time to the music, a scrolling backdrop and dancing objects based on words from the song. If not loading from the EUG menu, PAGE must be set to &2100 before the main control program is CHAINed.
The main control program is STANDEM, which loads SPRITSS (the sprite, logo and music data) into memory at &1100. I have used ideas from several of my recent articles including LINEIT, CHARIT and Scrolling STARS - see the relevant issues of EUG for details. Press ESCAPE when you've had enough!
Technical Notes
Procedures:
assem | Assembles the machine code, discussed below |
def(A%) | Defines one block of 32 VDU characters by peeking the data from memory at A% |
img(X%,V%,C%) | Draws the logo at (X%,V%) in colour C%, adapted from my LINEIT article. The line data is compacted into a string of ASCII characters in the data statement at lines 2900-2910. It is printed at successive positions to give a 3D graffiti-like look. |
lyric | Prints the next set of lyrics. T%(X) is the time X at which W$(X) will appear. Because the SOUND channels queue note data before playing, a lag time, lg%, is necessary to ensure that the lyrics don't appear too soon after the sound data is sent to the sound channels. |
mnm | Initialises the small spinning EMINEM logo by printing graphics on the Mode 5 screen and peeking/poking them as sprites. |
mnm2 | Prints the large red EMINEM logo. |
note |
Plays a note and advances the lyric timer if the note was on channel 3 (the melody channel). I%(X,Y) contains the instruments (envelope numbers). Y corresponds to the channel number and X the musical repeat number:
Channel Repeat 0 1 2 3 Envelope 1: plucked guitar-like sound 0 1 2 1 0 Envelope 2: electric organ sound 1 1 2 1 3 Envelope 3: struck xylophone-like sound 2 1 1 2 0 (0 = channel silent) 3 0 1 1 1 You can have another repeat if you add the ENVELOPE numbers to the data statement and change line 290 to something like I%=(I%+1)MOD5 for five choruses. |
Functions:
z(X%) | Advances P% by X% number of bytes to reserve space for data. |
Machine Code Routines:
MESS | Reads characters from the string at BUF and sends them to DH. &78 text pointer. |
DH | Plots letter, adapted from the Basic II Rom routine at &CFEE. It obtains the character data (pattern) via OSWORD 10 at &80-8, manipulates and pokes it into the screen Ram for speed. &70/71 = screen address of letter to be plotted, &75=index into character pattern/index into the masks used for each row of the definition stored at COL. &76=row pointer, &77=byte mask (colour). |
IEVNT | Initialise centisecond clock so that the event routines are called every tenth of a second: spin the EMINEM logo, move any objects dancing on the screen, and reset the timer value, TIMV. |
MOVE | Move stars, adapted from the Scrolling Stars article. Each star has a screen address (two bytes) and a third byte indexing into a pixel value. The third byte is set to &80 if the byte at the star's new position is non-zero, giving the appearance of it moving behind solid objects like the EMINEM logo. |
BCKDRP | Plot the stars. |
SPIN | Spins the small EMINEM logo. Bottom 3 bits of &55 used as index into frame, FRMI. EMI is a table of addresses into the sprite data itself originally stored as graphics character definitions but expanded into Mode 5 sprite data. |
MVOBS | Move mug of tea, person in bed, raincloud, and picture. ?&57=&FF if no objects and they are to start appearing on the screen. Incremented for each object appearing on screen. OBX and OBY are tables containing objects' X and Y coordinates. OBF object frame. OBD object direction, 0=east, 1=south, 2=west, 3=north, &80=disappeared off screen. When all OBDs are &80 and ?&57=3 there will be no items appearing on the screen. |
CALC | Calculate screen address of object and sprite address, = &1100 + object*&200 + frame*&80. |
SHTTR | Shutter blind effect. &70/71 screen address. &72 row pointer (7..0). &73 value to be written to screen Ram, 15=red then 0=black. |