unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls,
BGRABitmap, BGRABitmapTypes, BGRAVirtualScreen, mmsystem;
type // structure chr !
TChr = record
Char: Char;
Angle: Single;
Rotations: Integer;
Age: Integer;
end;
{ TForm1 }
TForm1 = class(TForm)
BGRAVirtualScreen1: TBGRAVirtualScreen;
Timer1: TTimer;
procedure BGRAVirtualScreen1Redraw(Sender: TObject; Bitmap: TBGRABitmap);
procedure FormCreate(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
txt: string;
ChrArray: array of TChr;
CCharIndex: Integer;
FrameCount: Integer;
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
const
sflag = snd_Loop or snd_Async;
begin
Caption := 'Rotating Scroll Text V1.0 Gigatron';
txt := ' GIGATRON PRESENTS ROTATING SCROLL TEXT MADE WITH LAZARUS FPC ON 5.5.2025 GREETINGS TO SAVAGE & TRONIC DESIGN & PARANOIMIA-ITALY ...... SEE YOU BYE ............................';
CCharIndex := 0;
FrameCount := 0;
SetLength(ChrArray, 0);// reserve mem chrtab
BGRAVirtualScreen1.Align := alClient;
playsound('mbis.wav', 0, sflag); // mono
end;
procedure TForm1.BGRAVirtualScreen1Redraw(Sender: TObject; Bitmap: TBGRABitmap);
var
centerX, centerY, radius: Integer;
i: Integer;
x, y: Integer;
begin
Bitmap.Fill(BGRA(0, 0, 0));
centerX := BGRAVirtualScreen1.Width div 2;
centerY := BGRAVirtualScreen1.Height div 2;
radius := 250;
bitmap.FontFullHeight := 72;
bitmap.FontName := 'Arial';
bitmap.FontStyle := [fsBold];
for i := Length(ChrArray) - 1 downto 0 do
begin
// Calcul de la position
x := centerX + Round(radius * Cos(ChrArray[i].Angle));
y := centerY + Round(radius * Sin(ChrArray[i].Angle));
bitmap.TextOut(x, y-30, ChrArray[i].Char, BGRA(255, 255, 255));
bitmap.TextOut(x+4, y-30, ChrArray[i].Char, BGRA(0, 0, 255));
end;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
BGRAVirtualScreen1.Invalidate;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
i: Integer;
angleStep: Single;
newAngle: Single;
posfree: Boolean;
angleDiff: Single;
charAppearSpeed: Integer;
rotationSpeed: Single;
totalChr: Integer;
chrFullRotated: Single;
begin
charAppearSpeed := 11; // Frame chr space
rotationSpeed := 1.2 * Pi / 180;
totalchr := 60; // max visible chr
angleStep := (2 * Pi) / totalChr;
// Add chr if
if (FrameCount mod charAppearSpeed = 0) and (CCharIndex < Length(txt) * 2) then
begin
posfree := False;
newAngle := 0; // Commence à l'angle 0
for i := 0 to Length(ChrArray) - 1 do
begin
angleDiff := Abs(ChrArray[i].Angle - newAngle);
if angleDiff < angleStep * 0.8 then // Marge de sécurité
begin
posfree := True;
Break;
end;
end;
if not posfree then
begin
SetLength(ChrArray, Length(ChrArray) + 1);
ChrArray[Length(ChrArray) - 1].Char := txt[(CCharIndex mod Length(txt)) + 1];
ChrArray[Length(ChrArray) - 1].Angle := newAngle;
ChrArray[Length(ChrArray) - 1].Rotations := 0;
ChrArray[Length(ChrArray) - 1].Age := 0;
Inc(CCharIndex);
end;
end;
for i := Length(ChrArray) - 1 downto 0 do
begin
ChrArray[i].Angle := ChrArray[i].Angle - rotationSpeed;
ChrArray[i].Age := ChrArray[i].Age + 1;
chrFullRotated := 2 * Pi - (40 * Pi / 180);
if Abs(ChrArray[i].Angle) >= chrFullRotated then
begin
if i < Length(ChrArray) - 1 then
ChrArray[i] := ChrArray[Length(ChrArray) - 1];
SetLength(ChrArray, Length(ChrArray) - 1);
Continue;
end;
if ChrArray[i].Angle <= -2 * Pi then
begin
ChrArray[i].Angle := ChrArray[i].Angle + 2 * Pi;
ChrArray[i].Rotations := ChrArray[i].Rotations + 1;
end;
end;
// Restart scroll txt
if (CCharIndex >= Length(txt)) and (Length(ChrArray) = 0) then
CCharIndex := 0;
Inc(FrameCount);
BGRAVirtualScreen1.RedrawBitmap;
end;
end.