{ S921878@MINYOS.XX.RMIT.OZ.AU, Daniel John Lee Parnell I have received several requests for the source code to the scrolly demo I posted to this group. Sorry about posting a binary. I didn't know it was not allowed on this group. Anyway the following is the source code to the scrolly. It is not a unit. It uses one 286 instruction so it wont work on an XT :( } {$G+} program ColorBars; uses DOS, CRT; const maxBars = 7; maxStars = 100; maxLines = 7; m : array [1..maxLines] of string = ('Welcome to my first scrolly demo on the PC. It was written using ', 'Turbo Pascal 6.0 on the 7th of October 1993. This program took me ', 'about 2 hours to write and I had a lot of fun writing it! ', 'I suppose I''d better put in some greets I guess...............', 'Greetings go to Robyn Adam Rowan Mandy ', ' Weng Speed Shane Iceberg Inc. And anybody ', 'else out there whom I have forgotten about...... '); var colors : array [0..768] of byte; rMsk, gMsk, bMsk : array [0..255] of byte; y, dy, s : array [1..maxBars] of integer; sx, sy, sdx : array [1..maxStars] of integer; tx, ty : array [0..640] of integer; dot : integer; ticks : word; scrly : array [0..360] of integer; mpos, mlen : integer; procedure SetMode(m : integer); { Set video mode } var regs : registers; begin regs.ax := m; intr($10, regs); end; procedure WaitRetrace; { Wait for vertical retrace } begin repeat { Nothing } until (Port[$03da] and 8) <> 0; end; procedure WaitNotRetrace; { Wait for not vertical retrace } begin repeat { Nothing } until (Port[$03da] and 8) <> 8; end; procedure InitScreen; { Sets up the colored bars } var i, j : integer; begin for i := 0 to 199 do for j := 0 to 319 do mem[$a000 : i * 320 + j] := i; end; procedure InitColors; { Zeros the first 200 colors } var i : integer; begin for i := 0 to 199 * 3 do colors[i] := 0; end; procedure SetColors; assembler; { Loads the colors into the regs } asm @ntrace: { Wait for not retrace } mov dx, $03da in al, dx test al, 8 jnz @vtrace @vtrace: { Now wait for retrace } mov dx, $03da in al, dx test al, 8 jz @vtrace mov dx, $03c8 { Start changeing colors from color # 1 } mov al, 1 out dx, al inc dx { Make DX point to the color register } mov cx, 199*3 { The number of bytes to put into the color register } mov si, offset colors { Load the address of the color array } rep outsb { Now change the colors } end; procedure CalcBars; { Calculate the color bars } var i, j, k : integer; begin for i := 0 to 199 * 3 do { Zero all the colors } colors[i] := 0; for i := 1 to maxBars do { Now process each bar in turn } begin y[i] := y[i] + dy[i]; { Move the bar } if (y[i] < 4) or (y[i] > 190) then { Has it hit the top or the bottom? } begin dy[i] := -dy[i]; { Yes, so make it bounce } y[i] := y[i] + dy[i]; end; for j := (y[i] - s[i]) to (y[i] + s[i]) do { Now update the color array } begin if j < y[i] then { Calculate the intensity } k := 63 - (y[i] - j) * 4 else k := 63 - (j - y[i]) * 4; if j > 0 then { If it is a valid color change it } begin colors[j * 3] := (colors[j * 3] + (k and rMsk[i])); { Do red } colors[j * 3 + 1] := (colors[j * 3 + 1] + (k and gMsk[i])); { Do green } colors[j * 3 + 2] := (colors[j * 3 + 2] + (k and bMsk[i])); { Do blue } end; end; end; end; procedure InitBars; { Set up the bars randomly } var i : integer; begin for i := 1 to MaxBars do begin y[i] := random(150)+4; { Starting pos } s[i] := random(6)+4; { Size } rMsk[i] := random(2)*255; { Red mask } gMsk[i] := random(2)*255; { Green mask } bMsk[i] := random(2)*255; { Blue mask } repeat { Calc direction } dy[i] := random(6) - 3; until dy[i] <> 0; end; end; procedure InitStars; { Set up the stars } var i : integer; begin port[$03c8] := $f8; { Change the colors for stars } for i := 7 downto 0 do begin port[$03c9] := 63 - (i shl 2); port[$03c9] := 63 - (i shl 2); port[$03c9] := 63 - (i shl 2); end; for i := 1 to maxStars do begin sx[i] := random(320); { Choose X pos } sy[i] := random(200); { Y pos } sdx[i] := 1 shl random(3); { Speed } end; end; procedure InitScroll; { Initialize the scrolly } const k = 3.141 / 180; var i : integer; begin mlen := 0; { Calc length of scroll text } for i := 1 to maxLines do mlen := mlen + length(m[i]); for i := 0 to 640 do { Zero all the star positions } tx[i] := -1; for i := 0 to 360 do { Calculate the scroll path } scrly[i] := round(100 + 50 * sin(i * k)); end; procedure UpdateStars; { Draw the stars } var i, ad : integer; begin for i := 1 to maxStars do begin ad := sx[i] + sy[i] * 320; { Calc star address in video ram } mem[$a000 : ad] := sy[i]; { Unplot old star pos } sx[i] := sx[i] + sdx[i]; { Calc new star pos } if sx[i] > 319 then { Is it past the end of the screen? } begin sy[i] := random(200); { Yes, generate a new star } sx[i] := 0; sdx[i] := 1 shl random(3); ad := sx[i] + sy[i] * 320; end; mem[$a000:ad + sdx[i]] := $f7 + (sdx[i]) * 2; end; end; function msg(var i : integer) : char; { Get a char from the scroll text } var j, t, p : integer; begin if i > mlen then { Is I longer then the text? } i := 1; j := 0; { Find which line it is in } t := 0; repeat inc(j); t := t + length(m[j]); until i 0 then msg := m[j][p] else msg := chr(0); inc(i); { Increment text position } end; procedure NextChar; { Create nex character in scroll text } var ad : word; i, j, q, c : integer; begin c := ord(msg(mpos)); { Get the char } ad := $fa6e + (c * 8); { Calc address of character image in ROM } for i := 0 to 7 do begin q := mem[$f000 : ad + i]; { Get a byte of the image } for j := 0 to 7 do begin if odd(q) then { Is bit 0 set? } begin tx[dot] := 320 + (7 - j) * 4; { If so add a dot to the list } ty[dot] := i * 4; inc(dot); if dot > 640 then dot := 0; end; q := q shr 1; { Shift the byte one pos to the right } end; end; end; procedure DisplayScroll; { Display scrolly and update dot positions } var i : integer; ad : word; begin if (ticks mod 32) = 0 then { Is it time for the next char? } NextChar; for i := 0 to 640 do if tx[i] > 0 then { Is this dot being used? } begin if tx[i] < 320 then { Is it on the screen? } begin ad := tx[i] + (ty[i] + scrly[tx[i]]) * 320; { Calc old position } mem[$a000:ad] := ty[i] + scrly[tx[i]]; { Clear old dot } end; dec(tx[i]); { Move dot to the left } ad := tx[i] + (ty[i] + scrly[tx[i]]) * 320; { Calc new position } if (tx[i] > 0) and (tx[i] < 320) then { Is it on the screen? } mem[$a000:ad] := $ff - (ty[i] shr 2); { Plot new dot } end; end; begin randseed := 4845267; { Set up the random seed } SetMode($13); { Go to 320*200*256 mode } InitColors; { Blank the color array } SetColors; { Set the colors to black } InitScreen; { Set up the colored bars } InitBars; { Set up the bar positions } InitStars; { Set up the stars } InitScroll; { Set up the scrolly } dot := 0; { Set the dot counter to 0 } mpos := 1; { Set up the text pos } repeat CalcBars; { Calculate the color bars } DisplayScroll; { Display the scrolly text } UpdateStars; { Update & display the stars } SetColors; { Set the colors } inc(ticks); { Update the tick counter } until KeyPressed; SetMode(3); { Return to text mode } end.