mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-25 04:19:12 +02:00
270 lines
5.1 KiB
ObjectPascal
270 lines
5.1 KiB
ObjectPascal
program tclock;
|
|
{$MODE OBJFPC}
|
|
|
|
uses
|
|
libc, ncurses, sysutils;
|
|
|
|
const
|
|
ASPECT = 2.2;
|
|
_2PI = 2.0 * PI;
|
|
|
|
function sign(_x: Integer): Integer;
|
|
begin
|
|
if _x < 0 then
|
|
sign := -1
|
|
else
|
|
sign := 1
|
|
end;
|
|
|
|
function A2X(angle,radius: Double): Integer; inline;
|
|
begin
|
|
A2X := round(ASPECT * radius * sin(angle))
|
|
end;
|
|
|
|
function A2Y(angle,radius: Double): Integer; inline;
|
|
begin
|
|
A2Y := round(radius * cos(angle))
|
|
end;
|
|
|
|
type
|
|
PRchar = ^TRchar;
|
|
TRchar = record
|
|
ry,rx: Smallint;
|
|
rch: chtype;
|
|
end;
|
|
|
|
procedure restore( rest: PRchar );
|
|
var
|
|
i: Longint = 0;
|
|
begin
|
|
while rest[i].rch <> 0 do
|
|
begin
|
|
with rest[i] do
|
|
mvaddch(ry, rx, rch);
|
|
Inc(i);
|
|
end;
|
|
freemem(rest)
|
|
end;
|
|
|
|
(* Draw a diagonal(arbitrary) line using Bresenham's alogrithm. *)
|
|
procedure dline(from_y, from_x, end_y, end_x: Smallint; ch: chtype; var rest: PRchar);
|
|
var
|
|
dx, dy: Smallint;
|
|
ax, ay: Smallint;
|
|
sx, sy: Smallint;
|
|
x, y, d, i: Smallint;
|
|
begin
|
|
dx := end_x - from_x;
|
|
dy := end_y - from_y;
|
|
|
|
ax := abs(dx * 2);
|
|
ay := abs(dy * 2);
|
|
|
|
sx := sign(dx);
|
|
sy := sign(dy);
|
|
|
|
x := from_x;
|
|
y := from_y;
|
|
|
|
i := 0;
|
|
if (ax > ay) then
|
|
begin
|
|
getmem(rest, sizeof(TRchar)*(abs(dx)+3));
|
|
d := ay - (ax DIV 2);
|
|
|
|
while true do
|
|
begin
|
|
move(y, x);
|
|
with rest[i] do
|
|
begin
|
|
rch := inch;
|
|
ry := y;
|
|
rx := x;
|
|
Inc(i)
|
|
end;
|
|
addch(ch);
|
|
if (x = end_x) then
|
|
begin
|
|
rest[i].rch := 0;
|
|
exit;
|
|
end;
|
|
|
|
if (d >= 0) then
|
|
begin
|
|
y += sy;
|
|
d -= ax;
|
|
end;
|
|
x += sx;
|
|
d += ay;
|
|
end
|
|
end
|
|
else
|
|
begin
|
|
getmem(rest, sizeof(TRchar)*(abs(dy)+3));
|
|
d := ax - (ay DIV 2);
|
|
|
|
while true do
|
|
begin
|
|
move(y, x);
|
|
with rest[i] do
|
|
begin
|
|
rch := inch;
|
|
ry := y;
|
|
rx := x;
|
|
Inc(i)
|
|
end;
|
|
addch(ch);
|
|
if (y = end_y) then
|
|
begin
|
|
rest[i].rch := 0;
|
|
exit;
|
|
end;
|
|
|
|
if (d >= 0) then
|
|
begin
|
|
x += sx;
|
|
d -= ay;
|
|
end;
|
|
y += sy;
|
|
d += ax;
|
|
end
|
|
end
|
|
end;
|
|
|
|
|
|
var
|
|
cx, cy: Integer;
|
|
cr, sradius, mradius, hradius: Double;
|
|
|
|
|
|
procedure clockinit;
|
|
const
|
|
title1 = 'Free pascal';
|
|
title2 = 'ncurses clock';
|
|
title3 = 'Press F10 or q to exit';
|
|
var
|
|
i: Integer;
|
|
vstr, tstr: AnsiString;
|
|
angle: Double;
|
|
begin
|
|
cx := (COLS - 1) DIV 2;
|
|
cy := LINES DIV 2;
|
|
if (cx / ASPECT < cy) then
|
|
cr := cx / ASPECT
|
|
else
|
|
cr := cy;
|
|
|
|
sradius := (8 * cr) / 9;
|
|
mradius := (3 * cr) / 4;
|
|
hradius := cr / 2;
|
|
|
|
|
|
for i := 1 to 24 do
|
|
begin
|
|
angle := i * _2PI / 24.0;
|
|
|
|
|
|
if (i MOD 2) = 0 then
|
|
begin
|
|
Str (i DIV 2, tstr);
|
|
attron(A_BOLD OR COLOR_PAIR(5));
|
|
mvaddstr(cy - A2Y(angle, sradius), cx + A2X(angle, sradius), @tstr[1]);
|
|
attroff(A_BOLD OR COLOR_PAIR(5));
|
|
end
|
|
else
|
|
begin
|
|
attron(COLOR_PAIR(1));
|
|
mvaddch(cy - A2Y(angle, sradius), cx + A2X(angle, sradius), chtype('.'));
|
|
attroff(COLOR_PAIR(1));
|
|
end
|
|
end;
|
|
|
|
vstr := curses_version;
|
|
|
|
attron(A_DIM OR COLOR_PAIR(2));
|
|
mvhline(cy , cx - round(sradius * ASPECT) + 1, ACS_HLINE, round(sradius * ASPECT) * 2 - 1);
|
|
mvvline(cy - round(sradius) + 1, cx , ACS_VLINE, round(sradius) * 2 - 1);
|
|
attroff(A_DIM OR COLOR_PAIR(1));
|
|
attron(COLOR_PAIR(3));
|
|
mvaddstr(cy - 5, cx - Length(title1) DIV 2, title1);
|
|
mvaddstr(cy - 4, cx - Length(title2) DIV 2, title2);
|
|
mvaddstr(cy - 3, cx - Length(vstr) DIV 2, PChar(vstr));
|
|
attroff(COLOR_PAIR(3));
|
|
attron(A_UNDERLINE);
|
|
mvaddstr(cy + 2, cx - Length(title3) DIV 2, title3);
|
|
attroff(A_UNDERLINE);
|
|
end;
|
|
|
|
|
|
var
|
|
angle: Double;
|
|
ch: chtype;
|
|
Hour, Min, Sec, Msec: Word;
|
|
Hrest, Mrest, Srest: PRchar;
|
|
timestr: AnsiString;
|
|
my_bg: NC_FPC_COLOR = COLOR_BLACK;
|
|
begin
|
|
setlocale(LC_ALL, '');
|
|
|
|
try
|
|
initscr();
|
|
noecho();
|
|
cbreak();
|
|
|
|
halfdelay(10);
|
|
keypad(stdscr, TRUE);
|
|
curs_set(0);
|
|
|
|
if (has_colors()) then
|
|
begin
|
|
start_color();
|
|
if (use_default_colors() = OK) then
|
|
my_bg := -1;
|
|
|
|
init_pair(1, COLOR_YELLOW, my_bg);
|
|
init_pair(2, COLOR_RED, my_bg);
|
|
init_pair(3, COLOR_GREEN, my_bg);
|
|
init_pair(4, COLOR_CYAN, my_bg);
|
|
init_pair(5, COLOR_YELLOW, COLOR_BLACK) ;
|
|
end;
|
|
|
|
clockinit;
|
|
repeat
|
|
if (ch = KEY_RESIZE) then
|
|
begin
|
|
flash();
|
|
erase();
|
|
wrefresh(curscr);
|
|
clockinit;
|
|
end;
|
|
|
|
decodeTime(Time, Hour, Min, Sec, Msec);
|
|
Hour := Hour MOD 12;
|
|
|
|
timestr := DateTimeToStr(Now);
|
|
mvaddstr(cy + round(sradius) - 4, cx - Length(timestr) DIV 2, PChar(timestr));
|
|
|
|
angle := Hour * _2PI / 12;
|
|
dline(cy, cx, cy - A2Y(angle, hradius), cx + A2X(angle, hradius), chtype('*'),Hrest);
|
|
|
|
angle := Min * _2PI / 60;
|
|
dline(cy, cx, cy - A2Y(angle, mradius), cx + A2X(angle, mradius), chtype('*'),Mrest);
|
|
|
|
angle := Sec * _2PI / 60;
|
|
dline(cy, cx, cy - A2Y(angle, sradius), cx + A2X(angle, sradius), chtype('.'),Srest);
|
|
|
|
wsyncup(stdscr);
|
|
refresh;
|
|
ch := getch();
|
|
|
|
restore(Srest);
|
|
restore(Mrest);
|
|
restore(Hrest);
|
|
|
|
until (ch = chtype('q')) OR (ch = KEY_F(10));
|
|
finally
|
|
curs_set(1);
|
|
endwin();
|
|
end;
|
|
end.
|