2
0

tclock.pp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. program tclock;
  2. {$MODE OBJFPC}
  3. uses
  4. ncurses, sysutils, initc;
  5. procedure setlocale(cat : integer; p : pchar); cdecl; external clib;
  6. const
  7. LC_ALL = 6;
  8. const
  9. ASPECT = 2.2;
  10. _2PI = 2.0 * PI;
  11. function sign(_x: Integer): Integer;
  12. begin
  13. if _x < 0 then
  14. sign := -1
  15. else
  16. sign := 1
  17. end;
  18. function A2X(angle,radius: Double): Integer; inline;
  19. begin
  20. A2X := round(ASPECT * radius * sin(angle))
  21. end;
  22. function A2Y(angle,radius: Double): Integer; inline;
  23. begin
  24. A2Y := round(radius * cos(angle))
  25. end;
  26. type
  27. PRchar = ^TRchar;
  28. TRchar = record
  29. ry,rx: Smallint;
  30. rch: chtype;
  31. end;
  32. procedure restore( rest: PRchar );
  33. var
  34. i: Longint = 0;
  35. begin
  36. while rest[i].rch <> 0 do
  37. begin
  38. with rest[i] do
  39. mvaddch(ry, rx, rch);
  40. Inc(i);
  41. end;
  42. freemem(rest)
  43. end;
  44. (* Draw a diagonal(arbitrary) line using Bresenham's alogrithm. *)
  45. procedure dline(from_y, from_x, end_y, end_x: Smallint; ch: chtype; var rest: PRchar);
  46. var
  47. dx, dy: Smallint;
  48. ax, ay: Smallint;
  49. sx, sy: Smallint;
  50. x, y, d, i: Smallint;
  51. begin
  52. dx := end_x - from_x;
  53. dy := end_y - from_y;
  54. ax := abs(dx * 2);
  55. ay := abs(dy * 2);
  56. sx := sign(dx);
  57. sy := sign(dy);
  58. x := from_x;
  59. y := from_y;
  60. i := 0;
  61. if (ax > ay) then
  62. begin
  63. getmem(rest, sizeof(TRchar)*(abs(dx)+3));
  64. d := ay - (ax DIV 2);
  65. while true do
  66. begin
  67. move(y, x);
  68. with rest[i] do
  69. begin
  70. rch := inch;
  71. ry := y;
  72. rx := x;
  73. Inc(i)
  74. end;
  75. addch(ch);
  76. if (x = end_x) then
  77. begin
  78. rest[i].rch := 0;
  79. exit;
  80. end;
  81. if (d >= 0) then
  82. begin
  83. y += sy;
  84. d -= ax;
  85. end;
  86. x += sx;
  87. d += ay;
  88. end
  89. end
  90. else
  91. begin
  92. getmem(rest, sizeof(TRchar)*(abs(dy)+3));
  93. d := ax - (ay DIV 2);
  94. while true do
  95. begin
  96. move(y, x);
  97. with rest[i] do
  98. begin
  99. rch := inch;
  100. ry := y;
  101. rx := x;
  102. Inc(i)
  103. end;
  104. addch(ch);
  105. if (y = end_y) then
  106. begin
  107. rest[i].rch := 0;
  108. exit;
  109. end;
  110. if (d >= 0) then
  111. begin
  112. x += sx;
  113. d -= ay;
  114. end;
  115. y += sy;
  116. d += ax;
  117. end
  118. end
  119. end;
  120. var
  121. cx, cy: Integer;
  122. cr, sradius, mradius, hradius: Double;
  123. procedure clockinit;
  124. const
  125. title1 = 'Free pascal';
  126. title2 = 'ncurses clock';
  127. title3 = 'Press F10 or q to exit';
  128. var
  129. i: Integer;
  130. vstr, tstr: AnsiString;
  131. angle: Double;
  132. begin
  133. cx := (COLS - 1) DIV 2;
  134. cy := LINES DIV 2;
  135. if (cx / ASPECT < cy) then
  136. cr := cx / ASPECT
  137. else
  138. cr := cy;
  139. sradius := (8 * cr) / 9;
  140. mradius := (3 * cr) / 4;
  141. hradius := cr / 2;
  142. for i := 1 to 24 do
  143. begin
  144. angle := i * _2PI / 24.0;
  145. if (i MOD 2) = 0 then
  146. begin
  147. Str (i DIV 2, tstr);
  148. attron(A_BOLD OR COLOR_PAIR(5));
  149. mvaddstr(cy - A2Y(angle, sradius), cx + A2X(angle, sradius), @tstr[1]);
  150. attroff(A_BOLD OR COLOR_PAIR(5));
  151. end
  152. else
  153. begin
  154. attron(COLOR_PAIR(1));
  155. mvaddch(cy - A2Y(angle, sradius), cx + A2X(angle, sradius), chtype('.'));
  156. attroff(COLOR_PAIR(1));
  157. end
  158. end;
  159. vstr := curses_version;
  160. attron(A_DIM OR COLOR_PAIR(2));
  161. mvhline(cy , cx - round(sradius * ASPECT) + 1, ACS_HLINE, round(sradius * ASPECT) * 2 - 1);
  162. mvvline(cy - round(sradius) + 1, cx , ACS_VLINE, round(sradius) * 2 - 1);
  163. attroff(A_DIM OR COLOR_PAIR(1));
  164. attron(COLOR_PAIR(3));
  165. mvaddstr(cy - 5, cx - Length(title1) DIV 2, title1);
  166. mvaddstr(cy - 4, cx - Length(title2) DIV 2, title2);
  167. mvaddstr(cy - 3, cx - Length(vstr) DIV 2, PChar(vstr));
  168. attroff(COLOR_PAIR(3));
  169. attron(A_UNDERLINE);
  170. mvaddstr(cy + 2, cx - Length(title3) DIV 2, title3);
  171. attroff(A_UNDERLINE);
  172. end;
  173. var
  174. angle: Double;
  175. ch: chtype = 0;
  176. Hour, Min, Sec, Msec: Word;
  177. Hrest, Mrest, Srest: PRchar;
  178. timestr: AnsiString;
  179. my_bg: Smallint = COLOR_BLACK;
  180. begin
  181. setlocale(LC_ALL, '');
  182. try
  183. initscr();
  184. noecho();
  185. cbreak();
  186. halfdelay(10);
  187. keypad(stdscr, TRUE);
  188. curs_set(0);
  189. if (has_colors()) then
  190. begin
  191. start_color();
  192. if (use_default_colors() = OK) then
  193. my_bg := -1;
  194. init_pair(1, COLOR_YELLOW, my_bg);
  195. init_pair(2, COLOR_RED, my_bg);
  196. init_pair(3, COLOR_GREEN, my_bg);
  197. init_pair(4, COLOR_CYAN, my_bg);
  198. init_pair(5, COLOR_YELLOW, COLOR_BLACK) ;
  199. end;
  200. clockinit;
  201. repeat
  202. if (ch = KEY_RESIZE) then
  203. begin
  204. flash();
  205. erase();
  206. wrefresh(curscr);
  207. clockinit;
  208. end;
  209. decodeTime(Time, Hour, Min, Sec, Msec);
  210. Hour := Hour MOD 12;
  211. timestr := DateTimeToStr(Now);
  212. mvaddstr(cy + round(sradius) - 4, cx - Length(timestr) DIV 2, PChar(timestr));
  213. angle := Hour * _2PI / 12;
  214. dline(cy, cx, cy - A2Y(angle, hradius), cx + A2X(angle, hradius), chtype('*'),Hrest);
  215. angle := Min * _2PI / 60;
  216. dline(cy, cx, cy - A2Y(angle, mradius), cx + A2X(angle, mradius), chtype('*'),Mrest);
  217. angle := Sec * _2PI / 60;
  218. dline(cy, cx, cy - A2Y(angle, sradius), cx + A2X(angle, sradius), chtype('.'),Srest);
  219. ch := getch();
  220. restore(Srest);
  221. restore(Mrest);
  222. restore(Hrest);
  223. until (ch = chtype('q')) OR (ch = KEY_F(10));
  224. finally
  225. curs_set(1);
  226. endwin();
  227. end;
  228. end.