keyboard: render some keys

This commit is contained in:
Zihao Yu 2024-01-09 13:05:33 +08:00
parent 43c32540e9
commit 5f1ce6df88
2 changed files with 89 additions and 10 deletions

View File

@ -1,42 +1,52 @@
#include <nvboard.h>
#include <SDL_ttf.h>
static SDL_Texture* font[128] = { NULL };
static TTF_Font *font;
static SDL_Texture* font_texture[128] = { NULL };
void init_font(SDL_Renderer *renderer) {
int ret = TTF_Init();
assert(ret != -1);
std::string nvboard_home = getenv("NVBOARD_HOME");
TTF_Font *f = TTF_OpenFont((nvboard_home + "/resources/font/" + "FreeMono.ttf").c_str(), 16);
assert(f != NULL);
TTF_SetFontHinting(f, TTF_HINTING_MONO);
TTF_SetFontStyle(f, TTF_STYLE_BOLD);
font = TTF_OpenFont((nvboard_home + "/resources/font/" + "FreeMono.ttf").c_str(), 16);
assert(font != NULL);
TTF_SetFontHinting(font, TTF_HINTING_MONO);
TTF_SetFontStyle(font, TTF_STYLE_BOLD);
SDL_Color fg = {.r = 0x00, .g = 0x00, .b = 0x00 };
SDL_Color bg = {.r = 0xff, .g = 0xff, .b = 0xff };
for (int i = 1; i < 128; i ++) {
SDL_Surface *s = TTF_RenderGlyph_Shaded(f, i, fg, bg);
SDL_Surface *s = TTF_RenderGlyph_Shaded(font, i, fg, bg);
if (s == NULL) {
printf("error = %s\n", SDL_GetError());
assert(s != NULL);
}
assert(s != NULL);
assert(s->w == 10);
assert(s->h == 16);
SDL_Texture *t = SDL_CreateTextureFromSurface(renderer, s);
assert(t != NULL);
font[i] = t;
font_texture[i] = t;
SDL_FreeSurface(s);
}
}
TTF_CloseFont(f);
SDL_Surface* get_font_surface(const char *str) {
SDL_Color fg = {.r = 0x00, .g = 0x00, .b = 0x00 };
SDL_Surface *s = TTF_RenderText_Solid_Wrapped(font, str, fg, 0);
if (s == NULL) {
printf("error = %s\n", SDL_GetError());
assert(s != NULL);
}
return s;
}
SDL_Texture* get_font_texture(uint8_t ch) {
assert(ch < 128);
return font[ch == 0 ? ' ' : ch];
return font_texture[ch == 0 ? ' ' : ch];
}
void close_font() {
TTF_CloseFont(font);
TTF_Quit();
}

View File

@ -1,9 +1,12 @@
#include <keyboard.h>
#include <pins.h>
#include <configs.h>
#include "at_scancode.h"
#include <string>
static KEYBOARD* kb = NULL;
bool is_kb_idle = true;
SDL_Surface* get_font_surface(const char *str);
#define FILL_KEYMAP_FIRST(a) keymap_first[SDL_PREFIX(a)] = GET_FIRST(AT_PREFIX(a));
#define FILL_KEYMAP_DECOND(a) keymap_second[SDL_PREFIX(a)] = GET_SECOND(AT_PREFIX(a));
@ -62,6 +65,70 @@ void KEYBOARD::update_state(){
}
}
static SDL_Surface* new_key_shape(int w, int h) {
SDL_Surface *s = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0);
uint32_t black = SDL_MapRGB(s->format, 0, 0, 0);
uint32_t white = SDL_MapRGB(s->format, 0xff, 0xff, 0xff);
SDL_FillRect(s, NULL, white);
SDL_Rect r;
r = (SDL_Rect){.x = 0, .y = 0, .w = 1, .h = h}; SDL_FillRect(s, &r, black);
r = (SDL_Rect){.x = 0, .y = 0, .w = w, .h = 1}; SDL_FillRect(s, &r, black);
r = (SDL_Rect){.x = w - 1, .y = 0, .w = 1, .h = h}; SDL_FillRect(s, &r, black);
r = (SDL_Rect){.x = 0, .y = h - 1, .w = w, .h = 1}; SDL_FillRect(s, &r, black);
return s;
}
static SDL_Surface* surdup(SDL_Surface *src) {
SDL_Surface *s = SDL_CreateRGBSurface(0, src->w, src->h, 32, 0, 0, 0, 0);
SDL_BlitSurface(src, NULL, s, NULL);
return s;
}
static SDL_Texture* gen_key(SDL_Renderer *renderer, const char *desc_up,
const char *desc_down, SDL_Surface *key_shape) {
std::string desc = std::string(desc_up) + '\n' + desc_down;
SDL_Surface *s = surdup(key_shape);
SDL_Surface *s_desc = get_font_surface(desc.c_str());
SDL_Rect r = { .x = 1, .y = 1 };
SDL_BlitSurface(s_desc, NULL, s, &r);
SDL_Texture *t = SDL_CreateTextureFromSurface(renderer, s);
SDL_FreeSurface(s_desc);
SDL_FreeSurface(s);
return t;
}
static void render_keyboard(SDL_Renderer *renderer) {
const int key_unit_width = 34;
const int key_gap = key_unit_width / 14;
const int x_top_left = WINDOW_WIDTH / 2 + 1;
const int key_gap_before_extend_keys = key_unit_width / 3;
SDL_Surface *s_1p0 = new_key_shape(key_unit_width, key_unit_width);
SDL_Surface *s_1p5 = new_key_shape(key_unit_width + key_gap + key_unit_width / 2, key_unit_width);
SDL_Texture *t_1 = gen_key(renderer, "!", "1", s_1p0);
SDL_Texture *t_backspace = gen_key(renderer, "<-", "", s_1p5);
SDL_Rect r_1p0 = {.x = x_top_left, .y = WINDOW_HEIGHT / 2 + 50, .w = s_1p0->w, .h = s_1p0->h };
SDL_Rect r_1p5 = {.x = x_top_left, .y = WINDOW_HEIGHT / 2 + 50, .w = s_1p5->w, .h = s_1p5->h };
SDL_FreeSurface(s_1p0);
SDL_FreeSurface(s_1p5);
SDL_Rect r = r_1p0;
for (int i = 0; i < 13; i ++) {
SDL_RenderCopy(renderer, t_1, NULL, &r);
r.x += r_1p0.w + key_gap;
}
r.w = r_1p5.w;
SDL_RenderCopy(renderer, t_backspace, NULL, &r);
r.x += r_1p5.w + key_gap_before_extend_keys;
r.w = r_1p0.w;
for (int i = 0; i < 3; i ++) {
SDL_RenderCopy(renderer, t_1, NULL, &r);
r.x += r_1p0.w + key_gap;
}
}
void init_keyboard(SDL_Renderer *renderer) {
kb = new KEYBOARD(renderer, 0, 0, KEYBOARD_TYPE);
for (int p = PS2_CLK; p <= PS2_DAT; p ++) {
@ -69,6 +136,8 @@ void init_keyboard(SDL_Renderer *renderer) {
}
MAP(SCANCODE_LIST, FILL_KEYMAP_FIRST)
MAP(SCANCODE_LIST, FILL_KEYMAP_DECOND)
render_keyboard(renderer);
}
void kb_update() {