tclock.pp 5.1 KB

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