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