program squaring;
{$mode objfpc}{$h+}
{.$define draw_tile_as_rectangle}
{$define draw_tile_as_circle}
uses
{$ifdef linux}
cthreads,
{$endif}
classes,
sysutils, fptimer,
ptccrt, ptcgraph;
{$if sizeof(colortype) = 4}
{$define FPC_GRAPH_SUPPORTS_TRUECOLOR}
{$endif}
type
TEvents = object
procedure DoTimer(Sender: TObject);
end;
const
FPS_TO_AIM_FOR = 50; // 25;
const
TILES_SPEED = 4; // 0..16
TILES_SQUARESIZE = 32;
TILES_SKIPDELAY = 100; // 7; // 5..255
TILES_COLCOUNT = 40;
TILES_ROWCOUNT = 10;
TILES_AMP = TILES_SQUARESIZE - 2; // 10..20
// dirty dimensions
XOFS = 20;
YOFS = 20;
WIDTH = TILES_COLCOUNT * TILES_SQUARESIZE;
HEIGHT = TILES_ROWCOUNT * TILES_SQUARESIZE;
var
Events : TEvents;
Timer : TFPTimer;
framecount : integer = 0;
procedure Render;
var
i,j,p,r,x,y : integer;
rs,sx,sy : double;
col : Colortype;
cc : byte;
begin
p := 0;
r := 0;
for i := 0 to TILES_COLCOUNT-1 do
begin
r := r + 1;
for j := 0 to TILES_ROWCOUNT-1 do
begin
p := p + TILES_SKIPDELAY;
x := i * TILES_SQUARESIZE;
y := j * TILES_SQUARESIZE;
rs := sin((p+r+framecount*(PI/180)*TILES_SPEED)); // speed
sx := TILES_AMP*rs;
sy := TILES_AMP*rs;
sx := abs(sx);
sy := abs(sy);
x := XOFS + round(x + (TILES_AMP-sx)/2);
y := YOFS + round(y + (TILES_AMP-sy)/2);
{$ifdef FPC_GRAPH_SUPPORTS_TRUECOLOR}
cc := round(sy * 255 / TILES_AMP);
col := cc shl 16 + cc shl 8 + cc shl 0;
{$else}
// TODO:
// col := index to palette
{$endif}
{$if defined(draw_tile_as_rectangle)}
SetColor(col);
Rectangle(x,y,round(x+sx),round(y+sy));
{$elseif defined(draw_tile_as_circle)}
SetColor(col);
Circle(x + TILES_AMP shr 1, y + TILES_AMP shr 1, round(sx/2));
{$else}
SetFillStyle(SolidFill, col);
Bar(x,y,round(x+sx),round(y+sy));
{$endif}
end;
end;
end;
procedure TEvents.DoTimer(Sender: TObject);
const
ActivePage : integer = 1;
begin
inc(framecount);
// Swap buffers
ActivePage := 1 - ActivePage;
SetActivePage(ActivePage);
// Clear buffer and render view
ClearDevice;
Render;
// Update view
SetVisualPage(ActivePage);
end;
procedure CheckGraphResult;
var
ErrorCode: Integer;
begin
ErrorCode := GraphResult;
if ErrorCode <> grOk then
begin
CloseGraph;
Writeln(ErrorCode, ': ', GraphErrorMsg(ErrorCode));
Readln;
Halt(1);
end;
end;
procedure GfxModeInfo;
var
n : smallint;
color : RGBRec;
begin
writeln('BGColor = ', GetBkColor);
writeln('FGColor = ', GetColor);
writeln('PaletteSize = ', GetPaletteSize);
writeln('DirectVideo = ', GetDirectVideo);
writeln('DriverName = ', GetDriverName);
writeln('maxColor = ', GetMaxColor);
writeln('GraphMode = ', GetGraphMode);
writeln('ModeName = ', GetModeName(GetGraphMode));
// info on some random colors
for n := 0 to 9 do
begin
GetRGBPalette(n, color.Red, color.Green, color.Blue);
writeln('$', color.Red.ToHexString, '.', color.Green.ToHexString, '.', color.Blue.ToHexString);
end;
end;
var
gd, gm: smallint;
begin
gd := detect;
gm := 0;
InitGraph(gd,gm,'');
CheckGraphResult;
{$ifndef FPC_GRAPH_SUPPORTS_TRUECOLOR}
// TODO: set palette
SetRGBPalette(1, $FF, $0, $0);
CheckGraphResult;
{$endif}
GfxModeInfo;
writeln('Effect:');
writeln('PixelWidth = ', WIDTH);
writeln('PixelHeight = ', HEIGHT);
writeln;
Timer := TFPTimer.Create(nil);
Timer.Enabled := false;
Timer.UseTimerThread := true;
Timer.Interval := round(1000 / FPS_TO_AIM_FOR);
Timer.OnTimer := @Events.DoTimer;
Timer.Enabled := true;
// let Timer do its job and wait for user intervention
repeat
delay(10);
until keypressed;
Timer.Free;
CloseGraph;
end.