/** * @brief */ static void Cl_DrawConsole_Buffer(void) { r_pixel_t cw, ch, height; R_BindFont("small", &cw, &ch); if (cls.state == CL_ACTIVE) { height = r_context.height * 0.5; R_DrawFill(0, 0, r_context.width, height, 7, 0.3); } else { height = r_context.height; R_DrawFill(0, 0, r_context.width, height, 0, 1.0); } cl_console.width = r_context.width / cw; cl_console.height = (height / ch) - 1; char *lines[cl_console.height]; const size_t count = Con_Tail(&cl_console, lines, cl_console.height); r_pixel_t y = (cl_console.height - count) * ch; for (size_t i = 0; i < count; i++) { R_DrawString(0, y, lines[i], CON_COLOR_DEFAULT); g_free(lines[i]); y += ch; } }
/** * @brief */ static void Sv_DrawConsole_Buffer(void) { char *lines[sv_console.height]; const size_t count = Con_Tail(&sv_console, lines, sv_console.height); size_t row = sv_console.height; for (size_t i = 0; i < count; i++) { const size_t j = count - i - 1; char *line = lines[j]; char *s = line; Sv_DrawConsole_Color(j ? StrrColor(lines[j - 1]) : CON_COLOR_DEFAULT); size_t col = 1; while (*s) { if (IS_LEGACY_COLOR(s)) { Sv_DrawConsole_Color(CON_COLOR_ALT); } else if (IS_COLOR(s)) { Sv_DrawConsole_Color(*(s + 1) - '0'); s++; } else if (isascii(*s)) { mvaddch((int32_t) row, (int32_t) col++, *s); } s++; } g_free(line); row--; } Sv_DrawConsole_Color(CON_COLOR_DEFAULT); }
/** * @brief Draws the last few lines of output transparently over the game top */ void Cl_DrawNotify(void) { r_pixel_t cw, ch; if (!cl_draw_notify->value) { return; } R_BindFont("small", &cw, &ch); console_t con = { .width = r_context.width / cw, .height = Clamp(cl_notify_lines->integer, 1, 12), .level = (PRINT_MEDIUM | PRINT_HIGH), }; if (cl.systime > cl_notify_time->value * 1000) { con.whence = cl.systime - cl_notify_time->value * 1000; } char *lines[con.height]; const size_t count = Con_Tail(&con, lines, con.height); r_pixel_t y = 0; for (size_t i = 0; i < count; i++) { R_DrawString(0, y, lines[i], CON_COLOR_DEFAULT); g_free(lines[i]); y += ch; } R_BindFont(NULL, NULL, NULL); } /** * @brief Draws the chat history and, optionally, the chat input string. */ void Cl_DrawChat(void) { r_pixel_t cw, ch; R_BindFont("small", &cw, &ch); r_pixel_t x = 1, y = r_view.y + r_view.height * 0.66; cl_chat_console.width = r_context.width / cw / 3; cl_chat_console.height = Clamp(cl_chat_lines->integer, 0, 8); if (cl_draw_chat->value && cl_chat_console.height) { if (cl.systime > cl_chat_time->value * 1000) { cl_chat_console.whence = cl.systime - cl_chat_time->value * 1000; } char *lines[cl_chat_console.height]; const size_t count = Con_Tail(&cl_chat_console, lines, cl_chat_console.height); for (size_t i = 0; i < count; i++) { R_DrawString(0, y, lines[i], CON_COLOR_DEFAULT); g_free(lines[i]); y += ch; } } if (cls.key_state.dest == KEY_CHAT) { const int32_t color = cls.chat_state.team_chat ? CON_COLOR_TEAMCHAT : CON_COLOR_CHAT; // draw the prompt R_DrawChar(0, y, ']', color); // and the input, scrolling horizontally if appropriate const char *s = cl_chat_console.input.buffer; if (cl_chat_console.input.pos > cl_chat_console.width - 2) { s += 2 + cl_chat_console.input.pos - cl_chat_console.width; } while (*s) { R_DrawChar(x * cw, y, *s, CON_COLOR_DEFAULT); s++; x++; } // and lastly cursor R_DrawChar(x * cw, y, 0x0b, CON_COLOR_DEFAULT); } }