Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

graphics.c 4.8 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * libcaca ASCII-Art library
  3. * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the Do What The Fuck You Want To
  8. * Public License, Version 2, as published by Sam Hocevar. See
  9. * http://sam.zoy.org/wtfpl/COPYING for more details.
  10. */
  11. /** \file graphics.c
  12. * \version \$Id$
  13. * \author Sam Hocevar <sam@zoy.org>
  14. * \brief Character drawing
  15. *
  16. * This file contains character and string drawing functions.
  17. */
  18. #include "config.h"
  19. #include <stdio.h> /* BUFSIZ */
  20. #include <string.h>
  21. #include <stdlib.h>
  22. #if defined(HAVE_UNISTD_H)
  23. # include <unistd.h>
  24. #endif
  25. #include <stdarg.h>
  26. #include "caca.h"
  27. #include "caca_internals.h"
  28. #include "cucul.h"
  29. #include "cucul_internals.h"
  30. /*
  31. * Local functions
  32. */
  33. void _caca_handle_resize(caca_t *kk);
  34. /** \brief Set the window title.
  35. *
  36. * If libcaca runs in a window, try to change its title. This works with
  37. * the X11 and Win32 drivers.
  38. *
  39. * \param title The desired window title.
  40. * \return 0 upon success, a non-zero value if an error occurs.
  41. */
  42. int caca_set_window_title(caca_t *kk, char const *title)
  43. {
  44. return kk->drv.set_window_title(kk, title);
  45. }
  46. /** \brief Get the window width.
  47. *
  48. * If libcaca runs in a window, get the usable window width. This value can
  49. * be used for aspect ratio calculation. If libcaca does not run in a window
  50. * or if there is no way to know the font size, assume a 6x10 font is being
  51. * used. Note that the units are not necessarily pixels.
  52. *
  53. * \return The window width.
  54. */
  55. unsigned int caca_get_window_width(caca_t *kk)
  56. {
  57. return kk->drv.get_window_width(kk);
  58. }
  59. /** \brief Get the window height.
  60. *
  61. * If libcaca runs in a window, get the usable window height. This value can
  62. * be used for aspect ratio calculation. If libcaca does not run in a window
  63. * or if there is no way to know the font size, assume a 6x10 font is being
  64. * used. Note that the units are not necessarily pixels.
  65. *
  66. * \return The window height.
  67. */
  68. unsigned int caca_get_window_height(caca_t *kk)
  69. {
  70. return kk->drv.get_window_height(kk);
  71. }
  72. /** \brief Set the refresh delay.
  73. *
  74. * This function sets the refresh delay in microseconds. The refresh delay
  75. * is used by caca_display() to achieve constant framerate. See the
  76. * caca_display() documentation for more details.
  77. *
  78. * If the argument is zero, constant framerate is disabled. This is the
  79. * default behaviour.
  80. *
  81. * \param usec The refresh delay in microseconds.
  82. */
  83. void caca_set_delay(caca_t *kk, unsigned int usec)
  84. {
  85. kk->delay = usec;
  86. }
  87. /** \brief Get the average rendering time.
  88. *
  89. * This function returns the average rendering time, which is the average
  90. * measured time between two caca_display() calls, in microseconds. If
  91. * constant framerate was activated by calling caca_set_delay(), the average
  92. * rendering time will not be considerably shorter than the requested delay
  93. * even if the real rendering time was shorter.
  94. *
  95. * \return The render time in microseconds.
  96. */
  97. unsigned int caca_get_rendertime(caca_t *kk)
  98. {
  99. return kk->rendertime;
  100. }
  101. /** \brief Flush pending changes and redraw the screen.
  102. *
  103. * This function flushes all graphical operations and prints them to the
  104. * screen. Nothing will show on the screen until caca_display() is
  105. * called.
  106. *
  107. * If caca_set_delay() was called with a non-zero value, caca_display()
  108. * will use that value to achieve constant framerate: if two consecutive
  109. * calls to caca_display() are within a time range shorter than the value
  110. * set with caca_set_delay(), the second call will wait a bit before
  111. * performing the screen refresh.
  112. */
  113. void caca_display(caca_t *kk)
  114. {
  115. #if !defined(_DOXYGEN_SKIP_ME)
  116. #define IDLE_USEC 10000
  117. #endif
  118. int ticks = kk->lastticks + _caca_getticks(&kk->timer);
  119. kk->drv.display(kk);
  120. /* Once the display is finished, we can ack resizes */
  121. if(kk->resize.resized)
  122. {
  123. kk->resize.resized = 0;
  124. _caca_handle_resize(kk);
  125. }
  126. /* Wait until kk->delay + time of last call */
  127. ticks += _caca_getticks(&kk->timer);
  128. for(ticks += _caca_getticks(&kk->timer);
  129. ticks + IDLE_USEC < (int)kk->delay;
  130. ticks += _caca_getticks(&kk->timer))
  131. {
  132. _caca_sleep(IDLE_USEC);
  133. }
  134. /* Update the sliding mean of the render time */
  135. kk->rendertime = (7 * kk->rendertime + ticks) / 8;
  136. kk->lastticks = ticks - kk->delay;
  137. /* If we drifted too much, it's bad, bad, bad. */
  138. if(kk->lastticks > (int)kk->delay)
  139. kk->lastticks = 0;
  140. }
  141. /*
  142. * XXX: following functions are local
  143. */
  144. void _caca_handle_resize(caca_t *kk)
  145. {
  146. kk->drv.handle_resize(kk);
  147. /* Tell libcucul we changed size */
  148. if(kk->resize.w != kk->qq->width || kk->resize.h != kk->qq->height)
  149. _cucul_set_size(kk->qq, kk->resize.w, kk->resize.h);
  150. }