2
0

tclock.pp 5.0 KB

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