mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 06:10:56 +00:00
[renderer] Add a buffer print function
It handles basic cursor motion respecting \r \n \f and \t (might be a problem for id chars), wraps at the right edge, and automatically scrolls when the cursor tries to pass the bottom of the screen. Clearing the buffer resets its cursor to the upper left.
This commit is contained in:
parent
c5099d30b1
commit
437e447b6b
3 changed files with 65 additions and 0 deletions
|
@ -50,6 +50,8 @@ typedef struct draw_charbuffer_s {
|
|||
int width; ///< width in character cells
|
||||
int height; ///< height in character cells
|
||||
char *chars; ///< width * height characters
|
||||
int cursx; ///< horizontal cursor position
|
||||
int cursy; ///< vertical cursor position
|
||||
} draw_charbuffer_t;
|
||||
|
||||
draw_charbuffer_t *Draw_CreateBuffer (int width, int height);
|
||||
|
@ -57,6 +59,7 @@ void Draw_DestroyBuffer (draw_charbuffer_t *buffer);
|
|||
void Draw_ClearBuffer (draw_charbuffer_t *buffer);
|
||||
void Draw_ScrollBuffer (draw_charbuffer_t *buffer, int lines);
|
||||
void Draw_CharBuffer (int x, int y, draw_charbuffer_t *buffer);
|
||||
void Draw_PrintBuffer (draw_charbuffer_t *buffer, const char *str);
|
||||
|
||||
extern byte *draw_chars;
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ Draw_CreateBuffer (int width, int height)
|
|||
buffer->width = width;
|
||||
buffer->height = height;
|
||||
buffer->chars = (char *) (buffer + 1);
|
||||
buffer->cursx = buffer->cursy = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -56,6 +57,7 @@ VISIBLE void
|
|||
Draw_ClearBuffer (draw_charbuffer_t *buffer)
|
||||
{
|
||||
memset (buffer->chars, ' ', buffer->height * buffer->width);
|
||||
buffer->cursx = buffer->cursy = 0;
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
|
@ -86,3 +88,51 @@ Draw_CharBuffer (int x, int y, draw_charbuffer_t *buffer)
|
|||
{
|
||||
r_funcs->Draw_CharBuffer (x, y, buffer);
|
||||
}
|
||||
|
||||
#define TAB 8
|
||||
|
||||
VISIBLE void
|
||||
Draw_PrintBuffer (draw_charbuffer_t *buffer, const char *str)
|
||||
{
|
||||
char *dst = buffer->chars;
|
||||
char c;
|
||||
int tab;
|
||||
dst += buffer->cursy * buffer->width + buffer->cursx;
|
||||
while ((c = *str++)) {
|
||||
switch (c) {
|
||||
case '\r':
|
||||
dst -= buffer->cursx;
|
||||
buffer->cursx = 0;
|
||||
break;
|
||||
case '\n':
|
||||
dst -= buffer->cursx;
|
||||
buffer->cursx = 0;
|
||||
dst += buffer->width;
|
||||
buffer->cursy++;
|
||||
break;
|
||||
case '\f':
|
||||
dst += buffer->width;
|
||||
buffer->cursy++;
|
||||
break;
|
||||
case '\t':
|
||||
tab = TAB - buffer->cursx % TAB;
|
||||
buffer->cursx += tab;
|
||||
dst += tab;
|
||||
break;
|
||||
default:
|
||||
*dst++ = c;
|
||||
buffer->cursx++;
|
||||
break;
|
||||
}
|
||||
if (buffer->cursx >= buffer->width) {
|
||||
buffer->cursx -= buffer->width;
|
||||
buffer->cursy++;
|
||||
}
|
||||
if (buffer->cursy >= buffer->height) {
|
||||
int lines = buffer->cursy - buffer->height + 1;
|
||||
Draw_ScrollBuffer (buffer, lines);
|
||||
dst -= lines * buffer->width;
|
||||
buffer->cursy -= lines;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -462,6 +462,17 @@ bi_Draw_CharBuffer (progs_t *pr, void *_res)
|
|||
Draw_CharBuffer (x, y, cbuff->buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Draw_PrintBuffer (progs_t *pr, void *_res)
|
||||
{
|
||||
draw_resources_t *res = _res;
|
||||
pr_ptr_t cbuff_handle = P_POINTER (pr, 0);
|
||||
bi_charbuff_t *cbuff = get_charbuff (pr, res, __FUNCTION__, cbuff_handle);
|
||||
const char *str = P_GSTRING (pr, 1);
|
||||
|
||||
Draw_PrintBuffer (cbuff->buffer, str);
|
||||
}
|
||||
|
||||
static const char *
|
||||
bi_draw_get_key (const void *p, void *unused)
|
||||
{
|
||||
|
@ -527,6 +538,7 @@ static builtin_t builtins[] = {
|
|||
bi(Draw_ClearBuffer, 1, p(ptr)),
|
||||
bi(Draw_ScrollBuffer, 2, p(ptr), p(int)),
|
||||
bi(Draw_CharBuffer, 3, p(int), p(int), p(ptr)),
|
||||
bi(Draw_PrintBuffer, 2, p(ptr), p(string)),
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue