Browse Source

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>.
tags/v0.99.beta17
Sam Hocevar sam 15 years ago
parent
commit
d09cd5c3b1
2 changed files with 132 additions and 40 deletions
  1. +90
    -10
      caca/caca_conio.c
  2. +42
    -30
      caca/caca_conio.h

+ 90
- 10
caca/caca_conio.c View File

@@ -31,6 +31,9 @@
static caca_canvas_t *cv;
static caca_display_t *dp;

static caca_timer_t refresh_timer = {0, 0};
static uint64_t refresh_ticks;

static int unget_ch = -1;
static int kbhit_ch = -1;
static char pass_buffer[BUFSIZ];
@@ -40,6 +43,9 @@ static void conio_init(void);
static void conio_refresh(void);
static void conio_fini(void);

int caca_conio_directvideo;
int caca_conio__wscroll;

/** \brief DOS conio.h cgets() equivalent */
char * caca_conio_cgets(char *str)
{
@@ -56,7 +62,11 @@ void caca_conio_clreol(void)
{
conio_init();

/* TODO: implement this function */
/* FIXME: must work within the currently active text window */
caca_fill_box(cv, caca_wherex(cv), caca_wherey(cv),
caca_get_width(cv), caca_wherey(cv), ' ');

conio_refresh();
}

/** \brief DOS conio.h clrscr() equivalent */
@@ -109,12 +119,28 @@ int caca_conio_cscanf(char *format, ...)
return 0;
}

/** \brief DOS conio.h delay() equivalent */
void caca_conio_delay(int i)
/** \brief DOS dos.h delay() equivalent */
void caca_conio_delay(unsigned int milliseconds)
{
int64_t usec = (int64_t)milliseconds * 1000;
caca_timer_t timer = {0, 0};

conio_init();

_caca_sleep(i * 1000);
_caca_getticks(&timer);

/* Refresh screen as long as we have enough time */
while(usec > 5000)
{
conio_refresh();
_caca_sleep(5000);
usec -= _caca_getticks(&timer);
}

if(usec > 0)
_caca_sleep(usec);

conio_refresh();
}

/** \brief DOS conio.h delline() equivalent */
@@ -129,6 +155,7 @@ void caca_conio_delline(void)
int caca_conio_getch(void)
{
caca_event_t ev;
int ret;

conio_init();

@@ -146,8 +173,14 @@ int caca_conio_getch(void)
return tmp;
}

caca_get_event(dp, CACA_EVENT_KEY_PRESS, &ev, -1);
return caca_get_event_key_ch(&ev);
while(caca_get_event(dp, CACA_EVENT_KEY_PRESS, &ev, 1000) == 0)
conio_refresh();

ret = caca_get_event_key_ch(&ev);

conio_refresh();

return ret;
}

/** \brief DOS conio.h getche() equivalent */
@@ -219,10 +252,23 @@ void caca_conio_insline(void)
/** \brief DOS conio.h kbhit() equivalent */
int caca_conio_kbhit(void)
{
static caca_timer_t timer = {0, 0};
static int last_failed = 0;
caca_event_t ev;

conio_init();

/* If last call failed and this call is made less than 100µs
* afterwards, we assume the caller is in a busy loop and we
* delay it slightly to avoid resource leakage. */
if(last_failed && _caca_getticks(&timer) < 100)
{
_caca_sleep(1000);
conio_refresh();
}

last_failed = 0;

if(kbhit_ch >= 0)
return 1;

@@ -232,6 +278,8 @@ int caca_conio_kbhit(void)
return 1;
}

last_failed = 1;

return 0;
}

@@ -262,7 +310,7 @@ void caca_conio_normvideo(void)
/* TODO: implement this function */
}

/** \brief DOS conio.h nosound() equivalent */
/** \brief DOS dos.h nosound() equivalent */
void caca_conio_nosound(void)
{
conio_init();
@@ -317,8 +365,32 @@ void caca_conio__setcursortype(int cur_t)
/* TODO: implement this function */
}

/** \brief DOS conio.h sound() equivalent */
void caca_conio_sound(int i)
/** \brief DOS dos.h sleep() equivalent */
void caca_conio_sleep(unsigned int seconds)
{
int64_t usec = (int64_t)seconds * 1000000;
caca_timer_t timer = {0, 0};

conio_init();

_caca_getticks(&timer);

/* Refresh screen as long as we have enough time */
while(usec > 5000)
{
conio_refresh();
_caca_sleep(5000);
usec -= _caca_getticks(&timer);
}

if(usec > 0)
_caca_sleep(usec);

conio_refresh();
}

/** \brief DOS dos.h sound() equivalent */
void caca_conio_sound(unsigned int frequency)
{
conio_init();

@@ -405,7 +477,10 @@ static void conio_init(void)
if(!dp)
{
dp = caca_create_display(cv);
caca_refresh_display(dp);
caca_set_cursor(dp, 1);
_caca_getticks(&refresh_timer);
refresh_ticks = 0;
#if defined HAVE_ATEXIT
atexit(conio_fini);
#endif
@@ -414,7 +489,12 @@ static void conio_init(void)

static void conio_refresh(void)
{
caca_refresh_display(dp);
refresh_ticks += _caca_getticks(&refresh_timer);
if(refresh_ticks > 10000)
{
refresh_ticks -= 10000;
caca_refresh_display(dp);
}
}

static void conio_fini(void)


+ 42
- 30
caca/caca_conio.h View File

@@ -38,28 +38,34 @@ extern "C"
{
#endif

/* conio.h defines and global variables */
#define CACA_CONIO_BLINK 128
#define CACA_CONIO_BLACK 0
#define CACA_CONIO_BLUE 1
#define CACA_CONIO_GREEN 2
#define CACA_CONIO_CYAN 3
#define CACA_CONIO_RED 4
#define CACA_CONIO_MAGENTA 5
#define CACA_CONIO_BROWN 6
#define CACA_CONIO_LIGHTGRAY 7
#define CACA_CONIO_DARKGRAY 8
#define CACA_CONIO_LIGHTBLUE 9
#define CACA_CONIO_LIGHTGREEN 10
#define CACA_CONIO_LIGHTCYAN 11
#define CACA_CONIO_LIGHTRED 12
#define CACA_CONIO_LIGHTMAGENTA 13
#define CACA_CONIO_YELLOW 14
#define CACA_CONIO_WHITE 15
/* conio.h enums and global variables */
enum CACA_CONIO_COLORS
{
CACA_CONIO_BLINK = 128,
CACA_CONIO_BLACK = 0,
CACA_CONIO_BLUE = 1,
CACA_CONIO_GREEN = 2,
CACA_CONIO_CYAN = 3,
CACA_CONIO_RED = 4,
CACA_CONIO_MAGENTA = 5,
CACA_CONIO_BROWN = 6,
CACA_CONIO_LIGHTGRAY = 7,
CACA_CONIO_DARKGRAY = 8,
CACA_CONIO_LIGHTBLUE = 9,
CACA_CONIO_LIGHTGREEN = 10,
CACA_CONIO_LIGHTCYAN = 11,
CACA_CONIO_LIGHTRED = 12,
CACA_CONIO_LIGHTMAGENTA = 13,
CACA_CONIO_YELLOW = 14,
CACA_CONIO_WHITE = 15,
};
__extern int caca_conio_directvideo;
#define CACA_CONIO__NOCURSOR 0
#define CACA_CONIO__SOLIDCURSOR 1
#define CACA_CONIO__NORMALCURSOR 2
enum CACA_CONIO_CURSOR
{
CACA_CONIO__NOCURSOR = 0,
CACA_CONIO__SOLIDCURSOR = 1,
CACA_CONIO__NORMALCURSOR = 2,
};
struct caca_conio_text_info
{
unsigned char winleft; /* left window coordinate */
@@ -75,13 +81,16 @@ struct caca_conio_text_info
unsigned char curx; /* x-coordinate in current window */
unsigned char cury; /* y-coordinate in current window */
};
#define CACA_CONIO_LASTMODE -1
#define CACA_CONIO_BW40 0
#define CACA_CONIO_C40 1
#define CACA_CONIO_BW80 2
#define CACA_CONIO_C80 3
#define CACA_CONIO_MONO 7
#define CACA_CONIO_C4350 64
enum CACA_CONIO_MODE
{
CACA_CONIO_LASTMODE = -1,
CACA_CONIO_BW40 = 0,
CACA_CONIO_C40 = 1,
CACA_CONIO_BW80 = 2,
CACA_CONIO_C80 = 3,
CACA_CONIO_MONO = 7,
CACA_CONIO_C4350 = 64,
};
__extern int caca_conio__wscroll;

#if !defined _DOXYGEN_SKIP_ME && !defined __LIBCACA__
@@ -154,7 +163,7 @@ __extern void caca_conio_clrscr(void);
__extern int caca_conio_cprintf(const char *format, ...);
__extern int caca_conio_cputs(const char *str);
__extern int caca_conio_cscanf(char *format, ...);
__extern void caca_conio_delay(int);
__extern void caca_conio_delay(unsigned int);
__extern void caca_conio_delline(void);
__extern int caca_conio_getch(void);
__extern int caca_conio_getche(void);
@@ -176,7 +185,8 @@ __extern int caca_conio_putch(int ch);
__extern int caca_conio_puttext(int left, int top, int right, int bottom,
void *destin);
__extern void caca_conio__setcursortype(int cur_t);
__extern void caca_conio_sound(int);
__extern void caca_conio_sleep(unsigned int);
__extern void caca_conio_sound(unsigned int);
__extern void caca_conio_textattr(int newattr);
__extern void caca_conio_textbackground(int newcolor);
__extern void caca_conio_textcolor(int newcolor);
@@ -237,6 +247,8 @@ __extern void caca_conio_window(int left, int top, int right, int bottom);
# define puttext caca_conio_puttext
# undef _setcursortype
# define _setcursortype caca_conio__setcursortype
# undef sleep
# define sleep caca_conio_sleep
# undef sound
# define sound caca_conio_sound
# undef textattr


Loading…
Cancel
Save