/* * @brief The input line scrolls horizontally if typing goes beyond the right edge */ static void Cl_DrawConsole_Input(void) { r_pixel_t cw, ch; R_BindFont("small", &cw, &ch); r_pixel_t x = 1, y = cl_console.height * ch; // draw the prompt R_DrawChar(0, y, ']', CON_COLOR_ALT); // and the input buffer, scrolling horizontally if appropriate const char *s = cl_console.input.buffer; if (cl_console.input.pos > cl_console.width - 2) { s += 2 + cl_console.input.pos - cl_console.width; } while (*s) { R_DrawChar(x * cw, y, *s, CON_COLOR_DEFAULT); s++; x++; } // and lastly cursor R_DrawChar((cl_console.input.pos + 1) * cw, y, 0x0b, CON_COLOR_DEFAULT); }
/* * @brief Draws at most len chars or size bytes of the specified string. Color escape * sequences are not visible chars. Returns the number of chars drawn. */ size_t R_DrawSizedString(r_pixel_t x, r_pixel_t y, const char *s, size_t len, size_t size, int32_t color) { size_t i, j; i = j = 0; while (*s && i < len && j < size) { if (IS_COLOR(s)) { // color escapes color = *(s + 1) - '0'; j += 2; s += 2; continue; } if (IS_LEGACY_COLOR(s)) { // legacy colors color = CON_COLOR_ALT; j++; s++; continue; } R_DrawChar(x, y, *s, color); x += r_draw.font->char_width; // next char position in line i++; j++; s++; } return i; }
/* ================ Draw_Alt_String ================ */ void Draw_Alt_String (int x, int y, const char *str) { while (*str) { R_DrawChar (x, y, (*str) | 0x80); str++; x += 8; } }
/* ================ Inv_DrawString ================ */ static void Inv_DrawString (int x, int y, const char *string) { while (*string) { R_DrawChar (x, y, *string); x+=8; string++; } }
void SCR_DrawCenterString (void) { char *start; int l; int j; int x, y; int remaining; RB_SetCanvas (CANVAS_MENU); // the finale prints the characters one at a time if (cl.intermission) remaining = scr_printspeed.value * (cl.time - scr_centertime_start); else remaining = 9999; scr_erase_center = 0; start = scr_centerstring; y = (200 - scr_center_lines * 8) * 0.10; do { // scan the width of the line for (l=0 ; l<40 ; l++) if (start[l] == '\n' || !start[l]) break; x = (320 - l * 8) / 2; for (j=0 ; j<l ; j++, x+=8) { R_DrawChar (x, y, start[j]); if (!remaining--) return; } y += 8; while (*start && *start != '\n') start++; if (!*start) break; start++; // skip the \n } while (1); }
/** * @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); } }
void CL_DrawInventory (void) { int i, j; int num, selected_num, item; int index[MAX_ITEMS]; char string[1024]; int x, y; char binding[1024]; const char *bind; int selected; int top; selected = cl.frame.playerstate.stats[STAT_SELECTED_ITEM]; num = 0; selected_num = 0; for (i=0 ; i<MAX_ITEMS ; i++) { if (i==selected) selected_num = num; if (cl.inventory[i]) { index[num] = i; num++; } } // determine scroll point top = selected_num - DISPLAY_ITEMS/2; if (num - top < DISPLAY_ITEMS) top = num - DISPLAY_ITEMS; if (top < 0) top = 0; x = (viddef.width-256)/2; y = (viddef.height-240)/2; // repaint everything next framed SCR_DirtyScreen (); re.DrawPic (x, y+8, "inventory"); y += 24; x += 24; Inv_DrawString (x, y, "hotkey ### item"); Inv_DrawString (x, y+8, "------ --- ----"); y += 16; for (i=top ; i<num && i < top+DISPLAY_ITEMS ; i++) { item = index[i]; // search for a binding Com_sprintf (binding, sizeof(binding), "use %s", cl.configstrings[CS_ITEMS+item]); bind = ""; for (j=0 ; j<256 ; j++) if (keybindings[j] && !Q_stricmp (keybindings[j], binding)) { bind = Key_KeynumToString(j); break; } Com_sprintf (string, sizeof(string), "%6s %3i %s", bind, cl.inventory[item], cl.configstrings[CS_ITEMS+item] ); if (item != selected) SetStringHighBit (string); else // draw a blinky cursor by the selected item { if ( (int)(cls.realtime*10) & 1) R_DrawChar (x-8, y, 15); } Inv_DrawString (x, y, string); y += 8; } }