The status bar in the quakeworld server curses console finally does something. Currently only cpu usage, but as a proof-of-concept, it more than does its job.

This commit is contained in:
Bill Currie 2007-04-09 00:10:10 +00:00 committed by Jeff Teunissen
parent 0aaab839c6
commit 2894182ec5
9 changed files with 201 additions and 41 deletions

View file

@ -10,8 +10,8 @@ EXTRA_DIST = asm_i386.h alsa_funcs_list.h adivtab.h anorm_dots.h anorms.h \
logos.h net_dgrm.h net_loop.h net_udp.h net_vcr.h net_wins.h netchan.h \
netmain.h old_keys.h ops.h qstring.h quakeasm.h regex.h r_cvar.h \
r_dynamic.h r_local.h r_screen.h r_shared.h rua_internal.h sbar.h \
skin_stencil.h snd_render.h varrays.h vgamodes.h view.h vregset.h \
winquake.h world.h \
skin_stencil.h snd_render.h sv_console.h varrays.h vgamodes.h view.h \
vregset.h winquake.h world.h \
\
qw/bothdefs.h qw/msg_backbuf.h qw/msg_ucmd.h qw/pmove.h qw/protocol.h \
\

View file

@ -60,6 +60,7 @@ typedef struct console_data_s {
void (*quit)(void);
struct cbuf_s *cbuf;
struct view_s *view;
struct view_s *status_view;
float lines;
int (*exec_line)(void *data, const char *line);
void *exec_data;

18
include/sv_console.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef __sv_console_h
#define __sv_console_h
struct view_s;
typedef struct sv_view_s {
void *win;
void *obj;
void (*draw) (struct view_s *view);
void (*setgeometry) (struct view_s *view);
} sv_view_t;
typedef struct sv_sbar_s {
int width;
char *text;
} sv_sbar_t;
#endif//__sv_console_h

View file

@ -46,6 +46,9 @@ static __attribute__ ((used)) const char rcsid[] =
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
@ -70,6 +73,7 @@ static __attribute__ ((used)) const char rcsid[] =
#include "QF/view.h"
#include "compat.h"
#include "sv_console.h"
static console_data_t sv_con_data;
@ -81,13 +85,6 @@ static void C_KeyEvent (knum_t key, short unicode, qboolean down);
#ifdef HAVE_CURSES_H
typedef struct sv_view_s {
WINDOW *win;
void *obj;
void (*draw) (view_t *view);
void (*setgeometry) (view_t *view);
} sv_view_t;
enum {
sv_resize_x = 1,
sv_resize_y = 2,
@ -109,38 +106,62 @@ static int interrupted;
#define MAX_LINES 1024
static int view_offset;
static chtype attr_table[4] = {
#define CP_YELLOW_BLACK (1)
#define CP_GREEN_BLACK (2)
#define CP_RED_BLACK (3)
#define CP_CYAN_BLACK (4)
#define CP_MAGENTA_BLACK (5)
#define CP_YELLOW_BLUE (6)
#define CP_GREEN_BLUE (7)
#define CP_RED_BLUE (8)
#define CP_CYAN_BLUE (9)
#define CP_MAGENTA_BLUE (10)
static chtype attr_table[16] = {
A_NORMAL,
COLOR_PAIR(1),
COLOR_PAIR(2),
COLOR_PAIR(3),
COLOR_PAIR (CP_GREEN_BLACK),
COLOR_PAIR (CP_RED_BLACK),
0,
COLOR_PAIR (CP_YELLOW_BLACK),
COLOR_PAIR (CP_CYAN_BLACK),
COLOR_PAIR (CP_MAGENTA_BLACK),
0,
A_NORMAL,
COLOR_PAIR (CP_GREEN_BLUE),
COLOR_PAIR (CP_RED_BLUE),
0,
COLOR_PAIR (CP_YELLOW_BLUE),
COLOR_PAIR (CP_CYAN_BLUE),
COLOR_PAIR (CP_MAGENTA_BLUE),
0,
};
static const byte attr_map[256] = {
3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 3, 3, 0, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 0, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 3, 3, 0, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 6, 6, 0, 6, 6,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
};
static inline void
draw_fun_char (WINDOW *win, byte c)
draw_fun_char (WINDOW *win, byte c, int blue)
{
chtype ch = c;
ch = sys_char_map[ch] | attr_table[attr_map[ch]];
int offset = blue ? 8 : 0;
ch = sys_char_map[ch] | attr_table[attr_map[ch] + offset];
waddch (win, ch);
}
@ -221,7 +242,7 @@ draw_output (view_t *view)
}
}
while (len--)
draw_fun_char (win, *text++);
draw_fun_char (win, *text++, 0);
} while (cur_line < output_buffer->cur_line + view_offset);
}
@ -229,8 +250,20 @@ static void
draw_status (view_t *view)
{
sv_view_t *sv_view = view->data;
wbkgdset (sv_view->win, COLOR_PAIR(4));
wclear (sv_view->win);
WINDOW *win = sv_view->win;
sv_sbar_t *sb = sv_view->obj;
int i;
char *old = alloca (sb->width);
memcpy (old, sb->text, sb->width);
memset (sb->text, ' ', sb->width);
view_draw (view);
if (memcmp (old, sb->text, sb->width)) {
wbkgdset (win, COLOR_PAIR (CP_YELLOW_BLUE));
wmove (win, 0, 0);
for (i = 0; i < sb->width; i++)
draw_fun_char (win, sb->text[i], 1);
}
}
static void
@ -245,7 +278,7 @@ draw_input_line (inputline_t *il)
text = il->lines[il->edit_line] + il->scroll;
wmove (win, 0, 0);
if (il->scroll) {
waddch (win, '<' | COLOR_PAIR (5));
waddch (win, '<' | COLOR_PAIR (CP_CYAN_BLACK));
text++;
} else {
waddch (win, *text++);
@ -259,7 +292,7 @@ draw_input_line (inputline_t *il)
waddch (win, ' ');
}
if (*text) {
waddch (win, '>' | COLOR_PAIR (5));
waddch (win, '>' | COLOR_PAIR (CP_CYAN_BLACK));
} else {
waddch (win, ' ');
}
@ -281,6 +314,16 @@ setgeometry_input (view_t *view)
il->width = view->xlen;
}
static void
setgeometry_status (view_t *view)
{
sv_view_t *sv_view = view->data;
sv_sbar_t *sb = sv_view->obj;
sb->width = view->xlen;
sb->text = realloc (sb->text, sb->width);
memset (sb->text, 0, sb->width); // force an update
}
static void
sigwinch (int sig)
{
@ -437,7 +480,7 @@ print (char *txt)
Con_BufferAddText (sv_view->obj, txt);
if (!view_offset) {
while (*txt)
draw_fun_char (sv_view->win, (byte) *txt++);
draw_fun_char (sv_view->win, (byte) *txt++, 0);
sv_refresh (output);
// move the cursor back to the input line
sv_refresh (input);
@ -513,9 +556,10 @@ init (void)
status = create_window (sv_con_data.view,
0, 1, screen_x, 1, grav_southwest,
0,
sv_resize_x | sv_scroll,
draw_status, 0);
calloc (1, sizeof (sv_sbar_t)),
sv_resize_x,
draw_status, setgeometry_status);
sv_con_data.status_view = status;
input = create_window (sv_con_data.view,
0, 0, screen_x, 1, grav_southwest,
@ -524,11 +568,17 @@ init (void)
draw_input, setgeometry_input);
((inputline_t *) ((sv_view_t *) input->data)->obj)->user_data = input;
init_pair (1, COLOR_YELLOW, COLOR_BLACK);
init_pair (2, COLOR_GREEN, COLOR_BLACK);
init_pair (3, COLOR_RED, COLOR_BLACK);
init_pair (4, COLOR_YELLOW, COLOR_BLUE);
init_pair (5, COLOR_CYAN, COLOR_BLACK);
init_pair (CP_YELLOW_BLACK, COLOR_YELLOW, COLOR_BLACK);
init_pair (CP_GREEN_BLACK, COLOR_GREEN, COLOR_BLACK);
init_pair (CP_RED_BLACK, COLOR_RED, COLOR_BLACK);
init_pair (CP_CYAN_BLACK, COLOR_CYAN, COLOR_BLACK);
init_pair (CP_MAGENTA_BLACK, COLOR_MAGENTA, COLOR_BLACK);
init_pair (CP_YELLOW_BLUE, COLOR_YELLOW, COLOR_BLUE);
init_pair (CP_GREEN_BLUE, COLOR_GREEN, COLOR_BLUE);
init_pair (CP_RED_BLUE, COLOR_RED, COLOR_BLUE);
init_pair (CP_CYAN_BLUE, COLOR_CYAN, COLOR_BLUE);
init_pair (CP_MAGENTA_BLUE, COLOR_MAGENTA, COLOR_BLUE);
con_linewidth = screen_x;
@ -677,6 +727,10 @@ C_KeyEvent (knum_t key, short unicode, qboolean down)
static void
C_DrawConsole (void)
{
// only the status bar is drawn because the inputline and output views
// take care of themselves
if (sv_con_data.status_view)
sv_con_data.status_view->draw (sv_con_data.status_view);
}
static void

View file

@ -5,4 +5,5 @@ EXTRA_DIST = \
cl_cam.h cl_chat.h cl_demo.h cl_ents.h cl_http.h cl_input.h \
cl_main.h cl_parse.h cl_pred.h cl_skin.h cl_slist.h cl_tent.h \
client.h crudefile.h game.h host.h map_cfg.h server.h sv_gib.h \
sv_demo.h sv_pr_cmds.h sv_pr_qwe.h sv_progs.h sv_qtv.h sv_recorder.h
sv_demo.h sv_pr_cmds.h sv_pr_cpqw.h sv_pr_qwe.h sv_progs.h sv_qtv.h \
sv_recorder.h

View file

@ -457,6 +457,7 @@ extern struct cbuf_args_s *sv_args;
// FIXME: declare exported functions in their own relevant .h
void SV_Init (void);
void SV_Sbar_Init (void);
void SV_Progs_Init (void);
void SV_Progs_Init_Cvars (void);
void SV_PR_Cmds_Init (void);

View file

@ -72,7 +72,7 @@ EXTRA_DIST=sv_sys_win.c sv_sys_unix.c
libqw_server_a_SOURCES= \
crudefile.c sv_ccmds.c sv_demo.c sv_ents.c sv_gib.c sv_init.c sv_main.c \
sv_move.c sv_phys.c sv_pr_cmds.c sv_pr_cpqw.c sv_pr_qwe.c sv_progs.c \
sv_qtv.c sv_recorder.c sv_send.c sv_user.c world.c $(syssv_SRC)
sv_qtv.c sv_recorder.c sv_sbar.c sv_send.c sv_user.c world.c $(syssv_SRC)
qw_server_LIBS= \
$(SERVER_PLUGIN_STATIC_LIBS) \

View file

@ -2005,6 +2005,7 @@ SV_Frame (float time)
svs.stats.packets = 0;
svs.stats.count = 0;
svs.stats.demo = 0;
Con_DrawConsole ();
}
Con_ProcessInput (); //XXX evil hack to get the cursor in the right place
}
@ -2560,6 +2561,8 @@ SV_Init (void)
Cmd_StuffCmds (sv_cbuf);
Cbuf_Execute_Sets (sv_cbuf);
SV_Sbar_Init ();
Game_Init ();
COM_Init ();

82
qw/source/sv_sbar.c Normal file
View file

@ -0,0 +1,82 @@
/*
#FILENAME#
#DESCRIPTION#
Copyright (C) 2007 #AUTHOR#
Author: #AUTHOR#
Date: #DATE#
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((used)) const char rcsid[] =
"$Id: template.c 11394 2007-03-17 03:23:39Z taniwha $";
#include "QF/console.h"
#include "QF/plugin.h"
#include "QF/view.h"
#include "QF/va.h"
#include "server.h"
#include "sv_console.h"
static void
draw_cpu (view_t *view)
{
sv_view_t *sv_view = view->data;
sv_sbar_t *sb = sv_view->obj;
double cpu;
const char *cpu_str;
const char *s;
char *d;
cpu = (svs.stats.latched_active + svs.stats.latched_idle);
cpu = 100 * svs.stats.latched_active / cpu;
cpu_str = va ("[CPU: %3d%%]", (int) cpu);
for (s = cpu_str, d = sb->text + view->xrel; *s; s++)
*d++ = *s;
if (cpu > 70.0) {
int i;
for (i = 6; i < 9; i++)
sb->text[view->xrel + i] |= 0x80;
}
}
void
SV_Sbar_Init (void)
{
view_t *status;
view_t *view;
if (!con_module || !con_module->data->console->status_view)
return;
status = con_module->data->console->status_view;
view = view_new (0, 0, 11, 1, grav_northwest);
view->draw = draw_cpu;
view->data = status->data;
view_add (status, view);
}