Ignore:
Timestamp:
Aug 2, 2009, 1:09:05 PM (10 years ago)
Author:
Sam Hocevar
Message:

Fix <conio.h> delay(), getch() and kbhit() to avoid busy loops and ensure
frequent screen refreshes.
Implement <conio.h> clreol() (incomplete) and <dos.h> sleep() functions.
Replace some defines with enums in <caca_conio.h>.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/caca/caca_conio.c

    r3596 r3601  
    3232static caca_display_t *dp;
    3333
     34static caca_timer_t refresh_timer = {0, 0};
     35static uint64_t refresh_ticks;
     36
    3437static int unget_ch = -1;
    3538static int kbhit_ch = -1;
     
    4144static void conio_fini(void);
    4245
     46int caca_conio_directvideo;
     47int caca_conio__wscroll;
     48
    4349/** \brief DOS conio.h cgets() equivalent */
    4450char * caca_conio_cgets(char *str)
     
    5763    conio_init();
    5864
    59     /* TODO: implement this function */
     65    /* FIXME: must work within the currently active text window */
     66    caca_fill_box(cv, caca_wherex(cv), caca_wherey(cv),
     67                  caca_get_width(cv), caca_wherey(cv), ' ');
     68
     69    conio_refresh();
    6070}
    6171
     
    110120}
    111121
    112 /** \brief DOS conio.h delay() equivalent */
    113 void caca_conio_delay(int i)
    114 {
    115     conio_init();
    116 
    117     _caca_sleep(i * 1000);
     122/** \brief DOS dos.h delay() equivalent */
     123void caca_conio_delay(unsigned int milliseconds)
     124{
     125    int64_t usec = (int64_t)milliseconds * 1000;
     126    caca_timer_t timer = {0, 0};
     127
     128    conio_init();
     129
     130    _caca_getticks(&timer);
     131
     132    /* Refresh screen as long as we have enough time */
     133    while(usec > 5000)
     134    {
     135        conio_refresh();
     136        _caca_sleep(5000);
     137        usec -= _caca_getticks(&timer);
     138    }
     139
     140    if(usec > 0)
     141        _caca_sleep(usec);
     142
     143    conio_refresh();
    118144}
    119145
     
    130156{
    131157    caca_event_t ev;
     158    int ret;
    132159
    133160    conio_init();
     
    147174    }
    148175
    149     caca_get_event(dp, CACA_EVENT_KEY_PRESS, &ev, -1);
    150     return caca_get_event_key_ch(&ev);
     176    while(caca_get_event(dp, CACA_EVENT_KEY_PRESS, &ev, 1000) == 0)
     177        conio_refresh();
     178
     179    ret = caca_get_event_key_ch(&ev);
     180
     181    conio_refresh();
     182
     183    return ret;
    151184}
    152185
     
    220253int caca_conio_kbhit(void)
    221254{
     255    static caca_timer_t timer = {0, 0};
     256    static int last_failed = 0;
    222257    caca_event_t ev;
    223258
    224259    conio_init();
     260
     261    /* If last call failed and this call is made less than 100µs
     262     * afterwards, we assume the caller is in a busy loop and we
     263     * delay it slightly to avoid resource leakage. */
     264    if(last_failed && _caca_getticks(&timer) < 100)
     265    {
     266        _caca_sleep(1000);
     267        conio_refresh();
     268    }
     269
     270    last_failed = 0;
    225271
    226272    if(kbhit_ch >= 0)
     
    232278        return 1;
    233279    }
     280
     281    last_failed = 1;
    234282
    235283    return 0;
     
    263311}
    264312
    265 /** \brief DOS conio.h nosound() equivalent */
     313/** \brief DOS dos.h nosound() equivalent */
    266314void caca_conio_nosound(void)
    267315{
     
    318366}
    319367
    320 /** \brief DOS conio.h sound() equivalent */
    321 void caca_conio_sound(int i)
     368/** \brief DOS dos.h sleep() equivalent */
     369void caca_conio_sleep(unsigned int seconds)
     370{
     371    int64_t usec = (int64_t)seconds * 1000000;
     372    caca_timer_t timer = {0, 0};
     373
     374    conio_init();
     375
     376    _caca_getticks(&timer);
     377
     378    /* Refresh screen as long as we have enough time */
     379    while(usec > 5000)
     380    {
     381        conio_refresh();
     382        _caca_sleep(5000);
     383        usec -= _caca_getticks(&timer);
     384    }
     385
     386    if(usec > 0)
     387        _caca_sleep(usec);
     388
     389    conio_refresh();
     390}
     391
     392/** \brief DOS dos.h sound() equivalent */
     393void caca_conio_sound(unsigned int frequency)
    322394{
    323395    conio_init();
     
    406478    {
    407479        dp = caca_create_display(cv);
     480        caca_refresh_display(dp);
    408481        caca_set_cursor(dp, 1);
     482        _caca_getticks(&refresh_timer);
     483        refresh_ticks = 0;
    409484#if defined HAVE_ATEXIT
    410485        atexit(conio_fini);
     
    415490static void conio_refresh(void)
    416491{
    417     caca_refresh_display(dp);
     492    refresh_ticks += _caca_getticks(&refresh_timer);
     493    if(refresh_ticks > 10000)
     494    {
     495        refresh_ticks -= 10000;
     496        caca_refresh_display(dp);
     497    }
    418498}
    419499
Note: See TracChangeset for help on using the changeset viewer.