[console] Switch to using a canvas for the console

While the console background is broken in that alpha doesn't work, it's
now rendered correctly in all renderers.
This commit is contained in:
Bill Currie 2023-01-22 03:45:50 +09:00
parent 89afcfcb6d
commit a561558748
4 changed files with 164 additions and 117 deletions

View file

@ -52,6 +52,10 @@ typedef struct console_data_s {
void (*quit) (void); void (*quit) (void);
struct cbuf_s *cbuf; struct cbuf_s *cbuf;
struct view_s *status_view; struct view_s *status_view;
const struct component_s *components;
uint32_t num_components;
uint32_t component_base;
struct canvas_system_s *canvas_sys;
float lines; float lines;
int (*exec_line)(void *data, const char *line); int (*exec_line)(void *data, const char *line);
void *exec_data; void *exec_data;

View file

@ -45,6 +45,7 @@
#include "QF/screen.h" #include "QF/screen.h"
#include "QF/plugin/console.h" #include "QF/plugin/console.h"
#include "QF/plugin/general.h"
#include "QF/plugin/vid_render.h" #include "QF/plugin/vid_render.h"
#include "QF/scene/scene.h" #include "QF/scene/scene.h"
@ -146,10 +147,10 @@ scr_draw_views (void)
if (!_vs->intermission) { if (!_vs->intermission) {
r_funcs->Draw_Crosshair ();//FIXME canvas_func r_funcs->Draw_Crosshair ();//FIXME canvas_func
} }
Con_DrawConsole ();
Canvas_Draw (cl_canvas_sys); Canvas_Draw (cl_canvas_sys);
SCR_CShift ();//FIXME canvas_func SCR_CShift ();//FIXME canvas_func
Sbar_DrawCenterPrint ();//FIXME canvas_func Sbar_DrawCenterPrint ();//FIXME canvas_func
Con_DrawConsole ();//FIXME canvas_func
} }
static SCR_Func scr_funcs[] = { static SCR_Func scr_funcs[] = {
@ -194,6 +195,12 @@ CL_Init_Screen (void)
__auto_type reg = ECS_NewRegistry (); __auto_type reg = ECS_NewRegistry ();
Canvas_InitSys (&cl_canvas_sys, reg); Canvas_InitSys (&cl_canvas_sys, reg);
if (con_module) {
__auto_type cd = con_module->data->console;
cd->component_base = ECS_RegisterComponents (reg, cd->components,
cd->num_components);
cd->canvas_sys = &cl_canvas_sys;
}
HUD_Init (reg); HUD_Init (reg);
ECS_CreateComponentPools (reg); ECS_CreateComponentPools (reg);

View file

@ -57,14 +57,12 @@
#include "QF/plugin/console.h" #include "QF/plugin/console.h"
#include "QF/plugin/vid_render.h" #include "QF/plugin/vid_render.h"
#include "QF/ui/canvas.h"
#include "QF/ui/inputline.h" #include "QF/ui/inputline.h"
#include "QF/ui/view.h" #include "QF/ui/view.h"
#include "compat.h" #include "compat.h"
static general_data_t plugin_info_general_data;
console_data_t con_data;
static con_buffer_t *con; static con_buffer_t *con;
static float con_cursorspeed = 4; static float con_cursorspeed = 4;
@ -152,8 +150,8 @@ static cvar_t cl_conmode_cvar = {
.value = { .type = &cl_conmode_type, .value = &con_data.exec_line }, .value = { .type = &cl_conmode_type, .value = &con_data.exec_line },
}; };
static ecs_registry_t *client_reg;
static uint32_t client_base; static uint32_t client_base;
static uint32_t canvas_base;
static uint32_t view_base; static uint32_t view_base;
static con_state_t con_state; static con_state_t con_state;
@ -170,40 +168,37 @@ typedef struct {
} con_input_t; } con_input_t;
enum { enum {
client_href,
client_input, client_input,
client_charbuff,
client_cursor, client_cursor,
client_comp_count client_comp_count
}; };
static const component_t client_components[client_comp_count] = { static const component_t client_components[client_comp_count] = {
[client_href] = {
.size = sizeof (hierref_t),
.name = "href",
},
[client_input] = { [client_input] = {
.size = sizeof (con_input_t *), .size = sizeof (con_input_t *),
.name = "input", .name = "input",
}, },
[client_charbuff] = {
.size = sizeof (draw_charbuffer_t *),
.name = "charbuff",
},
[client_cursor] = { [client_cursor] = {
.size = sizeof (con_input_t *), .size = sizeof (con_input_t *),
.name = "cursor", .name = "cursor",
}, },
}; };
console_data_t con_data = {
.components = client_components,
.num_components = client_comp_count,
};
#define MAXCMDLINE 256 #define MAXCMDLINE 256
static qpic_t *conback;
static con_input_t cmd_line; static con_input_t cmd_line;
static con_input_t say_line; static con_input_t say_line;
static inputline_t *chat_input; static inputline_t *chat_input;
static inputline_t *team_input; static inputline_t *team_input;
static uint32_t screen_canvas;
static view_t screen_view; static view_t screen_view;
static view_t console_view; static view_t console_view;
static view_t buffer_view; static view_t buffer_view;
@ -247,12 +242,84 @@ con_setcomponent (view_t view, uint32_t comp, void *data)
return Ent_SetComponent (view.id, comp, view.reg, data); return Ent_SetComponent (view.id, comp, view.reg, data);
} }
static void
con_setfunc (view_t view, uint32_t comp, canvas_update_f func)
{
con_setcomponent (view, canvas_base + comp, &func);
}
static void
con_setinput (view_t view, con_input_t *input)
{
con_setcomponent (view, client_base + client_input, &input);
}
static con_input_t *
con_getinput (view_t view)
{
return *(con_input_t**)con_getcomponent (view, client_base + client_input);
}
static int
con_hasinput (view_t view)
{
return con_hascomponent (view, client_base + client_input);
}
static void
con_setfitpic (view_t view, qpic_t *pic)
{
con_setcomponent (view, canvas_base + canvas_fitpic, &pic);
}
static void
con_setcharbuf (view_t view, draw_charbuffer_t *buffer)
{
con_setcomponent (view, canvas_base + canvas_charbuff, &buffer);
}
static void
con_setcursor (view_t view, con_input_t *input)
{
con_setcomponent (view, client_base + client_cursor, &input);
}
static inline void static inline void
con_remcomponent (view_t view, uint32_t comp) con_remcomponent (view_t view, uint32_t comp)
{ {
Ent_RemoveComponent (view.id, comp, view.reg); Ent_RemoveComponent (view.id, comp, view.reg);
} }
static void
con_remfunc (view_t view, uint32_t comp)
{
con_remcomponent (view, canvas_base + comp);
}
static inline void
con_remcharbuf (view_t view)
{
con_remcomponent (view, canvas_base + canvas_charbuff);
}
static inline void
con_remcursor (view_t view)
{
con_remcomponent (view, client_base + client_cursor);
}
static void
load_conback (const char *path)
{
qpic_t *p;
if (strlen (path) < 4 || strcmp (path + strlen (path) - 4, ".lmp")
|| !(p = (qpic_t *) QFS_LoadFile (QFS_FOpenFile (path), 0))) {
return;
}
conback = r_funcs->Draw_MakePic (p->width, p->height, p->data);
free (p);
}
static void static void
ClearNotify (void) ClearNotify (void)
{ {
@ -495,10 +562,10 @@ input_line_draw (inputline_t *il)
static void static void
resize_input (view_t view, view_pos_t len) resize_input (view_t view, view_pos_t len)
{ {
if (!con_hascomponent (view, client_input)) { if (!con_hasinput (view)) {
return; return;
} }
__auto_type inp = *(con_input_t **) con_getcomponent (view, client_input); __auto_type inp = con_getinput (view);
if (inp->buffer) { if (inp->buffer) {
Draw_DestroyBuffer (inp->buffer); Draw_DestroyBuffer (inp->buffer);
@ -578,7 +645,7 @@ resize_console_text (view_t view, view_pos_t len)
con_linewidth = width; con_linewidth = width;
Draw_DestroyBuffer (console_buffer); Draw_DestroyBuffer (console_buffer);
console_buffer = Draw_CreateBuffer (width, height); console_buffer = Draw_CreateBuffer (width, height);
con_setcomponent (buffer_view, client_charbuff, &console_buffer); con_setcharbuf (buffer_view, console_buffer);
clear_console_text (); clear_console_text ();
} }
} }
@ -607,45 +674,20 @@ draw_con_scrollback (void)
} }
static void static void
draw_cursor (void) draw_cursor (view_t view)
{ {
if (!con_data.realtime) {
return;
}
float t = *con_data.realtime * con_cursorspeed; float t = *con_data.realtime * con_cursorspeed;
int ch = 10 + ((int) (t) & 1); int ch = 10 + ((int) (t) & 1);
ecs_pool_t *pool = &client_reg->comp_pools[client_cursor]; __auto_type inp = con_getinput (view);
con_input_t **inp = pool->data; __auto_type buff = inp->buffer;
uint32_t *id = pool->dense; __auto_type il = inp->input_line;
if (!il->cursor) {
for (uint32_t i = pool->count; i-- > 0; ) { return;
__auto_type buff = (*inp)->buffer;
__auto_type il = (*inp++)->input_line;
view_t v = { .reg = client_reg, .id = *id++,
.comp = screen_view.comp };
if (!il->cursor) {
continue;
}
view_pos_t pos = View_GetAbs (v);
int x = (buff->cursx + il->linepos - il->scroll) * 8;
r_funcs->Draw_Character (pos.x + x, pos.y, ch);
}
}
static void
draw_buffer (void)
{
ecs_pool_t *pool = &client_reg->comp_pools[client_charbuff];
draw_charbuffer_t **buffer = pool->data;
uint32_t *id = pool->dense;
for (uint32_t i = pool->count; i-- > 0; ) {
view_t v = { .reg = client_reg, .id = *id++,
.comp = screen_view.comp };
view_pos_t pos = View_GetAbs (v);
Draw_CharBuffer (pos.x, pos.y, *buffer++);
} }
view_pos_t pos = View_GetAbs (view);
int x = (buff->cursx + il->linepos - il->scroll) * 8;
r_funcs->Draw_Character (pos.x + x, pos.y, ch);
} }
static void static void
@ -662,36 +704,12 @@ update_notify (void)
} }
} }
static void
draw_console (view_t view)
{
byte alpha;
view_pos_t len = View_GetLen (screen_view);
if (con_data.lines > 0) {
// draw the background
if (con_state == con_fullscreen) {
alpha = 255;
} else {
float y = len.y * con_size;
alpha = 255 * con_alpha * len.y / y;
alpha = min (alpha, 255);
}
r_funcs->Draw_ConsoleBackground (con_data.lines, alpha);
}
update_notify ();
// draw everything else
draw_buffer ();
draw_cursor ();
}
static void static void
resize_notify (view_t view, view_pos_t len) resize_notify (view_t view, view_pos_t len)
{ {
Draw_DestroyBuffer (notify_buffer); Draw_DestroyBuffer (notify_buffer);
notify_buffer = Draw_CreateBuffer (len.x / 8, NOTIFY_LINES + 1); notify_buffer = Draw_CreateBuffer (len.x / 8, NOTIFY_LINES + 1);
con_setcomponent (notify_view, client_charbuff, &notify_buffer); con_setcharbuf (notify_view, notify_buffer);
ClearNotify (); ClearNotify ();
} }
@ -759,35 +777,39 @@ C_DrawConsole (void)
return; return;
} }
if (con_state == con_message) { if (!con_data.lines && con_state == con_message) {
con_setcomponent (say_view, client_charbuff, &say_line.buffer); con_setcharbuf (say_view, say_line.buffer);
con_input_t *inp = &say_line; con_setcursor (say_view, &say_line);
con_setcomponent (say_view, client_cursor, &inp); con_setfunc (say_view, canvas_lateupdate, draw_cursor);
} else { } else {
con_remcomponent (say_view, client_charbuff); con_remcharbuf (say_view);
con_remcomponent (say_view, client_cursor); con_remcursor (say_view);
con_remfunc (say_view, canvas_lateupdate);
} }
if (con_data.lines) { if (con_data.lines) {
con_setcomponent (command_view, client_charbuff, &cmd_line.buffer); con_remcharbuf (notify_view);
con_input_t *inp = &cmd_line; con_setcharbuf (command_view, cmd_line.buffer);
con_setcomponent (command_view, client_cursor, &inp); con_setcursor (command_view, &cmd_line);
con_setfunc (command_view, canvas_lateupdate, draw_cursor);
} else { } else {
con_remcomponent (command_view, client_charbuff); con_setcharbuf (notify_view, notify_buffer);
con_remcomponent (command_view, client_cursor); con_remcharbuf (command_view);
con_remcursor (command_view);
con_remfunc (command_view, canvas_lateupdate);
} }
if (con_data.dl_name && *con_data.dl_name->str) { if (con_data.dl_name && *con_data.dl_name->str) {
if (!download_buffer) { if (!download_buffer) {
view_pos_t len = View_GetLen (download_view); view_pos_t len = View_GetLen (download_view);
download_buffer = Draw_CreateBuffer (len.x / 8, 1); download_buffer = Draw_CreateBuffer (len.x / 8, 1);
con_setcomponent (download_view, client_charbuff, &download_buffer); con_setcharbuf (download_view, download_buffer);
} }
update_download (); update_download ();
} else if (download_buffer) { } else if (download_buffer) {
Draw_DestroyBuffer (download_buffer); Draw_DestroyBuffer (download_buffer);
con_remcomponent (download_view, client_charbuff); con_remcharbuf (download_view);
} }
draw_console (screen_view); update_notify ();
} }
static void static void
@ -1015,13 +1037,9 @@ C_InitCvars (void)
static void static void
C_Init (void) C_Init (void)
{ {
client_reg = ECS_NewRegistry (); client_base = con_data.component_base;
client_base = ECS_RegisterComponents (client_reg, client_components, canvas_base = con_data.canvas_sys->base;
client_comp_count); view_base = con_data.canvas_sys->view_base;
view_base = ECS_RegisterComponents (client_reg, view_components,
view_comp_count);
ECS_CreateComponentPools (client_reg);
#ifdef __QNXNTO__ #ifdef __QNXNTO__
setlocale (LC_ALL, "C-TRADITIONAL"); setlocale (LC_ALL, "C-TRADITIONAL");
#endif #endif
@ -1033,8 +1051,9 @@ C_Init (void)
con_debuglog = COM_CheckParm ("-condebug"); con_debuglog = COM_CheckParm ("-condebug");
// The console will get resized, so assume initial size is 320x200 // The console will get resized, so assume initial size is 320x200
ecs_system_t sys = { client_reg, view_base }; ecs_system_t sys = { con_data.canvas_sys->reg, view_base };
screen_view = View_New (sys, nullview); screen_canvas = Canvas_New (*con_data.canvas_sys);
screen_view = Canvas_GetRootView (*con_data.canvas_sys, screen_canvas);
console_view = View_New (sys, screen_view); console_view = View_New (sys, screen_view);
buffer_view = View_New (sys, console_view); buffer_view = View_New (sys, console_view);
command_view = View_New (sys, console_view); command_view = View_New (sys, console_view);
@ -1043,6 +1062,15 @@ C_Init (void)
say_view = View_New (sys, screen_view); say_view = View_New (sys, screen_view);
menu_view = View_New (sys, screen_view); menu_view = View_New (sys, screen_view);
View_SetVisible (screen_view, 1);
View_SetVisible (console_view, 1);
View_SetVisible (buffer_view, 1);
View_SetVisible (command_view, 1);
View_SetVisible (download_view, 1);
View_SetVisible (notify_view, 1);
View_SetVisible (say_view, 1);
View_SetVisible (menu_view, 1);
View_SetGravity (screen_view, grav_northwest); View_SetGravity (screen_view, grav_northwest);
View_SetGravity (console_view, grav_northwest); View_SetGravity (console_view, grav_northwest);
View_SetGravity (buffer_view, grav_southwest); View_SetGravity (buffer_view, grav_southwest);
@ -1078,6 +1106,11 @@ C_Init (void)
View_SetLen (say_view, 320, 8); View_SetLen (say_view, 320, 8);
View_SetLen (menu_view, 320, 200); View_SetLen (menu_view, 320, 200);
load_conback ("gfx/conback.lmp");
if (conback) {
con_setfitpic (console_view, conback);
}
cmd_line.prompt = ""; cmd_line.prompt = "";
cmd_line.input_line = Con_CreateInputLine (32, MAXCMDLINE, ']'); cmd_line.input_line = Con_CreateInputLine (32, MAXCMDLINE, ']');
cmd_line.input_line->complete = Con_BasicCompleteCommandLine; cmd_line.input_line->complete = Con_BasicCompleteCommandLine;
@ -1101,14 +1134,8 @@ C_Init (void)
team_input->user_data = &say_line; team_input->user_data = &say_line;
team_input->draw = input_line_draw; team_input->draw = input_line_draw;
{ con_setinput (say_view, &say_line);
con_input_t *inp = &say_line; con_setinput (command_view, &cmd_line);
con_setcomponent (say_view, client_input, &inp);
}
{
con_input_t *inp = &cmd_line;
con_setcomponent (command_view, client_input, &inp);
}
view_pos_t len; view_pos_t len;
@ -1116,18 +1143,17 @@ C_Init (void)
len = View_GetLen (buffer_view); len = View_GetLen (buffer_view);
console_buffer = Draw_CreateBuffer (len.x / 8, len.y / 8); console_buffer = Draw_CreateBuffer (len.x / 8, len.y / 8);
Draw_ClearBuffer (console_buffer); Draw_ClearBuffer (console_buffer);
con_setcomponent (buffer_view, client_charbuff, &console_buffer); con_setcharbuf (buffer_view, console_buffer);
con_main = Con_CreateBuffer (CON_BUFFER_SIZE, CON_LINES); con_main = Con_CreateBuffer (CON_BUFFER_SIZE, CON_LINES);
len = View_GetLen (command_view); len = View_GetLen (command_view);
cmd_line.buffer = Draw_CreateBuffer (len.x / 8, len.y / 8); cmd_line.buffer = Draw_CreateBuffer (len.x / 8, len.y / 8);
Draw_ClearBuffer (cmd_line.buffer); Draw_ClearBuffer (cmd_line.buffer);
con_setcomponent (command_view, client_charbuff, &cmd_line.buffer); con_setcharbuf (command_view, cmd_line.buffer);
len = View_GetLen (notify_view); len = View_GetLen (notify_view);
notify_buffer = Draw_CreateBuffer (len.x / 8, NOTIFY_LINES + 1); notify_buffer = Draw_CreateBuffer (len.x / 8, NOTIFY_LINES + 1);
Draw_ClearBuffer (notify_buffer); Draw_ClearBuffer (notify_buffer);
con_setcomponent (notify_view, client_charbuff, &notify_buffer);
len = View_GetLen (say_view); len = View_GetLen (say_view);
say_line.buffer = Draw_CreateBuffer (len.x / 8, len.y / 8); say_line.buffer = Draw_CreateBuffer (len.x / 8, len.y / 8);
@ -1170,6 +1196,8 @@ C_shutdown (void)
IE_Remove_Handler (con_event_id); IE_Remove_Handler (con_event_id);
} }
static general_data_t plugin_info_general_data;
static general_funcs_t plugin_info_general_funcs = { static general_funcs_t plugin_info_general_funcs = {
.init = C_InitCvars, .init = C_InitCvars,
.shutdown = C_shutdown, .shutdown = C_shutdown,

View file

@ -56,6 +56,7 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$";
#include "QF/plugin/console.h" #include "QF/plugin/console.h"
#include "QF/plugin/vid_render.h" #include "QF/plugin/vid_render.h"
#include "QF/ui/canvas.h"
#include "QF/ui/font.h" #include "QF/ui/font.h"
#include "QF/ui/text.h" #include "QF/ui/text.h"
@ -84,6 +85,7 @@ quit_f (void)
static progs_t *bi_rprogs; static progs_t *bi_rprogs;
static pr_func_t qc2d; static pr_func_t qc2d;
static int event_handler_id; static int event_handler_id;
static canvas_system_t canvas_sys;
static void static void
bi_2d (void) bi_2d (void)
@ -94,7 +96,7 @@ bi_2d (void)
static SCR_Func bi_2dfuncs[] = { static SCR_Func bi_2dfuncs[] = {
bi_2d, bi_2d,
Con_DrawConsole, // Con_DrawConsole,
0, 0,
}; };
@ -355,13 +357,19 @@ BI_Graphics_Init (progs_t *pr)
IE_Set_Focus (event_handler_id); IE_Set_Focus (event_handler_id);
Con_Load ("client"); Con_Load ("client");
__auto_type reg = ECS_NewRegistry ();
Canvas_InitSys (&canvas_sys, reg);
if (con_module) { if (con_module) {
con_module->data->console->realtime = &con_realtime; __auto_type cd = con_module->data->console;
con_module->data->console->frametime = &con_frametime; cd->realtime = &con_realtime;
con_module->data->console->quit = quit_f; cd->frametime = &con_frametime;
con_module->data->console->cbuf = qwaq_cbuf; cd->quit = quit_f;
//con_module->data->console->screen_view = r_data->scr_view; cd->cbuf = qwaq_cbuf;
cd->component_base = ECS_RegisterComponents (reg, cd->components,
cd->num_components);
cd->canvas_sys = &canvas_sys;
} }
ECS_CreateComponentPools (reg);
//Key_SetKeyDest (key_game); //Key_SetKeyDest (key_game);
Con_Init (); Con_Init ();