You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

graphics.c 4.6 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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 "caca.h"
  20. #include "caca_internals.h"
  21. #include "cucul.h"
  22. #include "cucul_internals.h"
  23. /** \brief Set the window title.
  24. *
  25. * If libcaca runs in a window, try to change its title. This works with
  26. * the X11 and Win32 drivers.
  27. *
  28. * \param title The desired window title.
  29. * \return 0 upon success, a non-zero value if an error occurs.
  30. */
  31. int caca_set_window_title(caca_t *kk, char const *title)
  32. {
  33. return kk->drv.set_window_title(kk, title);
  34. }
  35. /** \brief Get the window width.
  36. *
  37. * If libcaca runs in a window, get the usable window width. This value can
  38. * be used for aspect ratio calculation. If libcaca does not run in a window
  39. * or if there is no way to know the font size, most drivers will assume a
  40. * 6x10 font is being used. Note that the units are not necessarily pixels.
  41. *
  42. * \return The window width.
  43. */
  44. unsigned int caca_get_window_width(caca_t *kk)
  45. {
  46. return kk->drv.get_window_width(kk);
  47. }
  48. /** \brief Get the window height.
  49. *
  50. * If libcaca runs in a window, get the usable window height. This value can
  51. * be used for aspect ratio calculation. If libcaca does not run in a window
  52. * or if there is no way to know the font size, assume a 6x10 font is being
  53. * used. Note that the units are not necessarily pixels.
  54. *
  55. * \return The window height.
  56. */
  57. unsigned int caca_get_window_height(caca_t *kk)
  58. {
  59. return kk->drv.get_window_height(kk);
  60. }
  61. /** \brief Set the refresh delay.
  62. *
  63. * This function sets the refresh delay in microseconds. The refresh delay
  64. * is used by caca_display() to achieve constant framerate. See the
  65. * caca_display() documentation for more details.
  66. *
  67. * If the argument is zero, constant framerate is disabled. This is the
  68. * default behaviour.
  69. *
  70. * \param usec The refresh delay in microseconds.
  71. */
  72. void caca_set_delay(caca_t *kk, unsigned int usec)
  73. {
  74. kk->delay = usec;
  75. }
  76. /** \brief Get the average rendering time.
  77. *
  78. * This function returns the average rendering time, which is the average
  79. * measured time between two caca_display() calls, in microseconds. If
  80. * constant framerate was activated by calling caca_set_delay(), the average
  81. * rendering time will not be considerably shorter than the requested delay
  82. * even if the real rendering time was shorter.
  83. *
  84. * \return The render time in microseconds.
  85. */
  86. unsigned int caca_get_rendertime(caca_t *kk)
  87. {
  88. return kk->rendertime;
  89. }
  90. /** \brief Flush pending changes and redraw the screen.
  91. *
  92. * This function flushes all graphical operations and prints them to the
  93. * screen. Nothing will show on the screen until caca_display() is
  94. * called.
  95. *
  96. * If caca_set_delay() was called with a non-zero value, caca_display()
  97. * will use that value to achieve constant framerate: if two consecutive
  98. * calls to caca_display() are within a time range shorter than the value
  99. * set with caca_set_delay(), the second call will wait a bit before
  100. * performing the screen refresh.
  101. */
  102. void caca_display(caca_t *kk)
  103. {
  104. #if !defined(_DOXYGEN_SKIP_ME)
  105. #define IDLE_USEC 10000
  106. #endif
  107. int ticks = kk->lastticks + _caca_getticks(&kk->timer);
  108. kk->drv.display(kk);
  109. /* Once the display is finished, we can ack resizes */
  110. if(kk->resize.resized)
  111. {
  112. kk->resize.resized = 0;
  113. _caca_handle_resize(kk);
  114. }
  115. /* Wait until kk->delay + time of last call */
  116. ticks += _caca_getticks(&kk->timer);
  117. for(ticks += _caca_getticks(&kk->timer);
  118. ticks + IDLE_USEC < (int)kk->delay;
  119. ticks += _caca_getticks(&kk->timer))
  120. {
  121. _caca_sleep(IDLE_USEC);
  122. }
  123. /* Update the sliding mean of the render time */
  124. kk->rendertime = (7 * kk->rendertime + ticks) / 8;
  125. kk->lastticks = ticks - kk->delay;
  126. /* If we drifted too much, it's bad, bad, bad. */
  127. if(kk->lastticks > (int)kk->delay)
  128. kk->lastticks = 0;
  129. }
  130. /*
  131. * XXX: following functions are local
  132. */
  133. void _caca_handle_resize(caca_t *kk)
  134. {
  135. kk->drv.handle_resize(kk);
  136. /* Tell libcucul we changed size */
  137. if(kk->resize.w != kk->qq->width || kk->resize.h != kk->qq->height)
  138. _cucul_set_size(kk->qq, kk->resize.w, kk->resize.h);
  139. }