unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls,
BGRAVirtualScreen, BGRABitmap, BGRABitmapTypes,BGRATransform,mmsystem;
type
TWaveScanner = class(TBGRAAffineBitmapTransform)
Time: integer;
function GetOffset({%H-}X, Y: Single): Single;
{ fast integer scanning (used by PutImage) }
procedure ScanMoveTo(X, Y: Integer); override;
{ slow floating point scanning }
function ScanAt(X, Y: Single): TBGRAPixel; override;
constructor Create(ASource: TBGRACustomBitmap; ARepeatX,ARepeatY: boolean);
end;
{ TForm1 }
TForm1 = class(TForm)
BGRAVirtualScreen1: TBGRAVirtualScreen;
Timer1: TTimer;
procedure BGRAVirtualScreen1Redraw(Sender: TObject; Bitmap: TBGRABitmap);
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
function cs(agl : Single) : Single;
private
public
MyAudio_File: AnsiString;
WavStream : TMemoryStream;
gtr_scanner,phx_scanner: TWaveScanner;
end;
var
Form1: TForm1;
ddr_table: Array[0..15] of integer =(0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1); // sinus movement factor table
tx: Array[0..13] Of String =(' ',
' GIGATRON PRESENTS ',
' THE GREAT GIANA SISTERS ',
' CRACKED ON 08/06/2024 ',
' GREETINGS TO MEMBERS OF ',
' TRONIC-SYSTEM AND SUB-SERO',
' ALL LAZARUS AND FPC TEAM ',
' SFX BY : KARSTEN OBARSKI ',
' GFX BY : RED-MAX ',
' @ LAZARUS FPC RULEZ @ ',
' THE BEST COMPONENT BGRA ',
' THANX TO CIRCULAR ',
' SEE YOU ON NEXT PRODUCTION',
' GOTO SUB-QUANTUM ');
// attention tx vars !
tm,tx_id,dir,x,y,vx : integer ;
g,vy : single ;
groundLevel : integer;
// logo phenix,gtr
phenix,gtr : TBGRABitmap;
// ddr table index !
ddr : integer;
// dot plot
s,a,a2 : single;
rot : Boolean;
rot_dir,rot_timer : integer;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
// init text vars
tm := 0;
tx_id := 0;
dir := 1; // vers la droite
g := 0.6; // acceleration gravity
x := 0; // initial horizontal position
y := -400; // initial vertical position out of scene
vx := 0; // initial horizontal speed in case ; unused !!
vy := 0; // initial vertical speed
groundLevel := 500;
ddr := 0; // table index
// plot fx
s := 255/sqrt(3)*2/30;
a := 0.0; // angle
a2:= 0.0;
rot := false;
rot_dir := 0;
rot_timer :=0;
BGRAVirtualScreen1.Color := $00776655;
phenix := TBGRABitmap.Create('phex.png');
gtr := TBGRABitmap.Create('gtr.png');
gtr_scanner := TWaveScanner.Create(gtr,false, false); // bitmap
gtr_scanner.Translate(140,-40);
phx_scanner := TWaveScanner.Create(phenix,false, false); // bitmap
phx_scanner.Translate(110,80);
// audio
// audio stream
MyAudio_File := 'blueberry.wav';
WavStream := TMemoryStream.Create;
WavStream.LoadFromFile(MyAudio_File);
PlaySound(WavStream.Memory, 0, SND_NODEFAULT or SND_LOOP or SND_ASYNC or SND_MEMORY);
end;
procedure TForm1.BGRAVirtualScreen1Redraw(Sender: TObject; Bitmap: TBGRABitmap);
var
xx,yy : integer;
z,x1,x2,y1,y2 : single;
begin
// plot fx
for xx:=15 downto -15 do
begin
for yy:=15 downto -15 do
begin
z := cs(sqrt(xx*xx+yy*yy)/30-a)*30;
x2 := xx*cos(2*a2*PI/180)-yy*sin(a2*PI/180);
y2 := xx*sin(2*a2*PI/180)+yy*cos(a2*PI/180);
x1 := round(360+(y2-x2)*s*sqrt(3)/2);
y1 := round(360+z-(y2+x2)*s/2);
bitmap.Rectangle(Rect(Round(x1), Round(y1),Round(x1+2), Round(y1+2)),BGRA(255,255,255),dmSet);
end;
end;
a := a + 0.005;
if(rot) and (rot_dir=1) then a2 := a2 + 0.2;
if(rot) and (rot_dir=2) then a2 := a2 - 0.2;
//***********************************
// le logo phenix en premier
Bitmap.Fill(phx_scanner,dmFastBlend);
dec(phx_scanner.Time,1);
// puis le logo gtr
inc(gtr_scanner.Time,1);
Bitmap.Fill(gtr_scanner,dmFastBlend);
// puis le texte ligne par ligne !
Bitmap.FontName := 'AmigaDigital'; // your ttf font
Bitmap.FontHeight := 60;
Bitmap.TextOut(x+4, y+2, tx[tx_id],BGRA(50,50,50));
Bitmap.TextOut(x, y, tx[tx_id],BGRA(255,255,255));
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
vy := vy + Frac(g);
y := y + Round(vy);
if (y >= groundLevel ) then // if text hits the ground
begin
y := groundLevel; // reposition it at the ground
vy := vy * Frac(-0.6); // then reverse and reduce its vertical speed
end;
if( y = groundLevel) then
begin
tm := tm +1;
if(tm>=80) then
begin
if (dir=1) then x := x + 20 ; // on va aller vite !!
if (dir=2) then x := x - 20 ;
if( x>= 800) Or (x <=-800 ) then
begin // si x >< sort de l'ecran reset all vars ;
tm := 0;
x := 0;
y := -400;
rot := true;
ddr := ddr +1; // commence le sinus movement !
if(ddr>=14) then ddr := 1;
dir := dir + 1;
if(dir>2) then dir := 1;
tx_id := tx_id +1;
if(tx_id>=14 ) then tx_id := 0;
end;
end;
end;
inc(rot_timer);
if(rot_timer>=1000) then rot_dir := 1;
if(rot_timer>=2000) then rot_dir := 2;
if(rot_timer>=3000) then rot_timer :=0;
BGRAVirtualScreen1.RedrawBitmap;
end;
function TForm1.cs(agl : single) : single;
begin
result := cos(2*PI*agl);
end;
{ TWaveScanner }
function TWaveScanner.GetOffset(X, Y: Single): Single;
begin
result := ddr_table[ddr] * sin((Y + Time) * 30/5 * PI / 180);
end;
procedure TWaveScanner.ScanMoveTo(X, Y: Integer);
begin
inherited ScanMoveTo(X + round(GetOffset(X, Y)), Y);
end;
function TWaveScanner.ScanAt(X, Y: Single): TBGRAPixel;
begin
Result:=inherited ScanAt(X + GetOffset(X, Y), Y);
end;
constructor TWaveScanner.Create(ASource: TBGRACustomBitmap;
ARepeatX,ARepeatY: boolean);
begin
inherited Create(ASource, ARepeatX, ARepeatY);
Time := 0;
end;
// end of demo
end.