segs7: draw surrounding lines

This commit is contained in:
Zihao Yu 2024-01-10 00:37:03 +08:00
parent a8c9c54e87
commit 3d6f4f3af1
12 changed files with 203 additions and 59 deletions

View File

@ -71,13 +71,4 @@ void add_component(Component *c);
void update_components(SDL_Renderer *renderer);
void delete_components();
static inline SDL_Rect operator+(const SDL_Rect &A, const SDL_Rect &B) {
SDL_Rect ret;
ret.x = A.x + B.x;
ret.y = A.y + B.y;
ret.w = A.w + B.w;
ret.h = A.h + B.h;
return ret;
}
#endif

19
include/font.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef __FONT_H__
#define __FONT_H__
#include <SDL.h>
#define CH_WIDTH 10
#define CH_HEIGHT 16
SDL_Surface* str2surface(const char *str, uint32_t fg);
SDL_Surface* str2surface(const char *str, uint32_t fg, uint32_t bg);
SDL_Texture* str2texture(SDL_Renderer *renderer, const char *str, uint32_t fg);
SDL_Texture* str2texture(SDL_Renderer *renderer, const char *str, uint32_t fg, uint32_t bg);
SDL_Surface* ch2surface(uint8_t ch, uint32_t fg);
SDL_Surface* ch2surface(uint8_t ch, uint32_t fg, uint32_t bg);
SDL_Texture* ch2texture(SDL_Renderer *renderer, uint8_t ch, uint32_t fg);
SDL_Texture* ch2texture(SDL_Renderer *renderer, uint8_t ch, uint32_t fg, uint32_t bg);
SDL_Texture* ch2texture_term(uint8_t ch);
#endif

View File

@ -2,9 +2,10 @@
#define __NVBOARD_H__
#include <pins.h>
#include <string>
#include <font.h>
#include <component.h>
#include <configs.h>
#include <string>
#include <SDL.h>
#include <SDL_image.h>

38
include/render.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef __RENDER_H__
#define __RENDER_H__
#include <SDL.h>
#define BOARD_BG_COLOR 0x00008060
static inline SDL_Point Point(int x, int y) {
return (SDL_Point){ .x = x, .y = y };
}
static inline SDL_Point operator+(const SDL_Point &A, const SDL_Point &B) {
return Point(A.x + B.x, A.y + B.y);
}
static inline SDL_Point operator-(const SDL_Point &A, const SDL_Point &B) {
return Point(A.x - B.x, A.y - B.y);
}
static inline SDL_Rect Rect(int x, int y, int w, int h) {
return (SDL_Rect){ .x = x, .y = y, .w = w, .h = h };
}
static inline SDL_Rect Rect(const SDL_Point &top_left, int w, int h) {
return Rect(top_left.x, top_left.y, w, h);
}
static inline SDL_Rect Rect(const SDL_Point &top_left, const SDL_Point &size) {
return Rect(top_left, size.x, size.y);
}
static inline SDL_Rect operator+(const SDL_Rect &A, const SDL_Rect &B) {
return Rect(A.x + B.x, A.y + B.y, A.w + B.w, A.h + B.h);
}
void draw_thicker_line(SDL_Renderer *renderer, const SDL_Point *point, int n);
#endif

View File

@ -1,5 +1,5 @@
#ifndef _NVBOARD_TERM_H
#define _NVBOARD_TERM_H
#ifndef __TERM_H__
#define __TERM_H__
class Term {
private:

View File

@ -1,5 +1,5 @@
#ifndef _NVBOARD_UART_H
#define _NVBOARD_UART_H
#ifndef __UART_H__
#define __UART_H__
#include <component.h>
#include <term.h>

View File

@ -2,14 +2,15 @@
#include <SDL_ttf.h>
static TTF_Font *font;
static SDL_Texture* font_texture[128] = { NULL };
static SDL_Texture* font_texture_term[128] = { NULL };
SDL_Texture* surface2texture(SDL_Renderer *renderer, SDL_Surface *s);
void init_font(SDL_Renderer *renderer) {
int ret = TTF_Init();
assert(ret != -1);
std::string nvboard_home = getenv("NVBOARD_HOME");
font = TTF_OpenFont((nvboard_home + "/resources/font/" + "FreeMono.ttf").c_str(), 16);
font = TTF_OpenFont((nvboard_home + "/resources/font/" + "FreeMono.ttf").c_str(), CH_HEIGHT);
assert(font != NULL);
TTF_SetFontHinting(font, TTF_HINTING_MONO);
TTF_SetFontStyle(font, TTF_STYLE_BOLD);
@ -18,32 +19,61 @@ void init_font(SDL_Renderer *renderer) {
SDL_Color bg = {.r = 0xff, .g = 0xff, .b = 0xff };
for (int i = 1; i < 128; i ++) {
SDL_Surface *s = TTF_RenderGlyph_Shaded(font, i, fg, bg);
if (s == NULL) {
printf("error = %s\n", SDL_GetError());
assert(s != NULL);
}
assert(s->w == 10);
assert(s->h == 16);
SDL_Texture *t = SDL_CreateTextureFromSurface(renderer, s);
assert(t != NULL);
font_texture[i] = t;
SDL_FreeSurface(s);
assert(s->w == CH_WIDTH);
assert(s->h == CH_HEIGHT);
font_texture_term[i] = surface2texture(renderer, s);
}
}
SDL_Surface* get_font_surface(const char *str) {
SDL_Color fg = {.r = 0x00, .g = 0x00, .b = 0x00 };
SDL_Surface *s = TTF_RenderText_Blended_Wrapped(font, str, fg, 0);
if (s == NULL) {
printf("error = %s\n", SDL_GetError());
assert(s != NULL);
}
SDL_Surface* str2surface(const char *str, uint32_t fg) {
SDL_Color c_fg = {.r = (uint8_t)(fg >> 16), .g = (uint8_t)(fg >> 8), .b = (uint8_t)fg };
SDL_Surface *s = TTF_RenderText_Blended_Wrapped(font, str, c_fg, 0);
assert(s != NULL);
return s;
}
SDL_Texture* get_font_texture(uint8_t ch) {
SDL_Surface* str2surface(const char *str, uint32_t fg, uint32_t bg) {
SDL_Color c_fg = {.r = (uint8_t)(fg >> 16), .g = (uint8_t)(fg >> 8), .b = (uint8_t)fg };
SDL_Color c_bg = {.r = (uint8_t)(bg >> 16), .g = (uint8_t)(bg >> 8), .b = (uint8_t)bg };
SDL_Surface *s = TTF_RenderText_LCD_Wrapped(font, str, c_fg, c_bg, 0);
assert(s != NULL);
return s;
}
SDL_Texture* str2texture(SDL_Renderer *renderer, const char *str, uint32_t fg) {
return surface2texture(renderer, str2surface(str, fg));
}
SDL_Texture* str2texture(SDL_Renderer *renderer, const char *str, uint32_t fg, uint32_t bg) {
return surface2texture(renderer, str2surface(str, fg, bg));
}
SDL_Surface* ch2surface(uint8_t ch, uint32_t fg) {
SDL_Color c_fg = {.r = (uint8_t)(fg >> 16), .g = (uint8_t)(fg >> 8), .b = (uint8_t)fg };
SDL_Surface *s = TTF_RenderGlyph_Blended(font, ch, c_fg);
assert(s != NULL);
return s;
}
SDL_Surface* ch2surface(uint8_t ch, uint32_t fg, uint32_t bg) {
SDL_Color c_fg = {.r = (uint8_t)(fg >> 16), .g = (uint8_t)(fg >> 8), .b = (uint8_t)fg };
SDL_Color c_bg = {.r = (uint8_t)(bg >> 16), .g = (uint8_t)(bg >> 8), .b = (uint8_t)bg };
SDL_Surface *s = TTF_RenderGlyph_LCD(font, ch, c_fg, c_bg);
assert(s != NULL);
return s;
}
SDL_Texture* ch2texture(SDL_Renderer *renderer, uint8_t ch, uint32_t fg) {
return surface2texture(renderer, ch2surface(ch, fg));
}
SDL_Texture* ch2texture(SDL_Renderer *renderer, uint8_t ch, uint32_t fg, uint32_t bg) {
return surface2texture(renderer, ch2surface(ch, fg, bg));
}
SDL_Texture* ch2texture_term(uint8_t ch) {
assert(ch < 128);
return font_texture[ch == 0 ? ' ' : ch];
return font_texture_term[ch == 0 ? ' ' : ch];
}
void close_font() {

View File

@ -11,7 +11,6 @@ typedef struct {
static KEYBOARD* kb = NULL;
bool is_kb_idle = true;
SDL_Surface* get_font_surface(const char *str);
static Key keys[256] = {};
KEYBOARD::KEYBOARD(SDL_Renderer *rend, int cnt, int init_val, int ct):
@ -98,7 +97,7 @@ static SDL_Texture* gen_key_texture(SDL_Renderer *renderer, const char *desc1,
uint32_t color_up = SDL_MapRGBA(key_shape->format, 0xf0, 0xf0, 0xf0, 0xff);
uint32_t color_dn = SDL_MapRGBA(key_shape->format, 0xc0, 0xc0, 0xc0, 0xff);
SDL_Surface *s = surdup(key_shape, is_down ? color_dn : color_up);
SDL_Surface *s_desc = get_font_surface(desc.c_str());
SDL_Surface *s_desc = str2surface(desc.c_str(), 0);
SDL_Rect r = { .x = 1, .y = 1 };
SDL_BlitSurface(s_desc, NULL, s, &r);
SDL_Texture *t = SDL_CreateTextureFromSurface(renderer, s);
@ -120,7 +119,7 @@ static void render_keyboard(SDL_Renderer *renderer) {
const int key_gap = key_unit_width / 14;
const int h_keyboard = key_unit_width * 6 + key_gap * 5 + key_unit_width / 2;
const int x_top_left = WINDOW_WIDTH / 2 + 1;
const int y_below_uart_rx = WINDOW_HEIGHT / 2 + 2 + 16;
const int y_below_uart_rx = WINDOW_HEIGHT / 2 + 2 + CH_HEIGHT;
const int y_top_left = y_below_uart_rx + (WINDOW_HEIGHT - y_below_uart_rx - h_keyboard) / 2;
const int key_gap_before_extend_keys = key_unit_width / 3;

View File

@ -1,4 +1,5 @@
#include <nvboard.h>
#include <render.h>
static std::string nvboard_home;
static SDL_Texture *tfpga_background;
@ -13,19 +14,44 @@ SDL_Texture* load_pic_texture(SDL_Renderer *renderer, std::string path) {
return load_texture(renderer, "/resources/pic/" + path);
}
SDL_Texture* new_texture(SDL_Renderer *renderer, int w, int h, int r, int g, int b) {
SDL_Surface *s = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0);
SDL_FillRect(s, NULL, SDL_MapRGB(s->format, r, g, b));
SDL_Texture* surface2texture(SDL_Renderer *renderer, SDL_Surface *s) {
assert(s != NULL);
SDL_Texture *t = SDL_CreateTextureFromSurface(renderer, s);
assert(t != NULL);
SDL_FreeSurface(s);
return t;
}
SDL_Texture* new_texture(SDL_Renderer *renderer, int w, int h, int r, int g, int b) {
SDL_Surface *s = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0);
SDL_FillRect(s, NULL, SDL_MapRGB(s->format, r, g, b));
return surface2texture(renderer, s);
}
void draw_thicker_line(SDL_Renderer *renderer, const SDL_Point *point, int n) {
SDL_RenderDrawLines(renderer, point, n);
SDL_Point *p = new SDL_Point[n];
for (int i = 0; i < n ; i ++) {
p[i] = point[i] + Point(-1, -1);
}
SDL_RenderDrawLines(renderer, &p[0], n);
delete [] p;
}
void init_render(SDL_Renderer *renderer) {
nvboard_home = getenv("NVBOARD_HOME");
tfpga_background = load_pic_texture(renderer, BG_PATH);
SDL_Rect rect_bg = {0, 0, WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2};
#if 0
tfpga_background = load_pic_texture(renderer, BG_PATH);
SDL_RenderCopy(renderer, tfpga_background, NULL, &rect_bg);
#else
uint8_t r, g, b, a;
SDL_GetRenderDrawColor(renderer, &r, &g, &b, &a);
SDL_SetRenderDrawColor(renderer,
(BOARD_BG_COLOR >> 16) & 0xff, (BOARD_BG_COLOR >> 8) & 0xff, BOARD_BG_COLOR & 0xff, 0);
SDL_RenderFillRect(renderer, &rect_bg);
SDL_SetRenderDrawColor(renderer, r, g, b, a);
#endif
}

View File

@ -1,4 +1,5 @@
#include <nvboard.h>
#include <render.h>
#define SEG_X 60
#define SEG_Y 225
@ -69,7 +70,7 @@ void SEGS7::update_state() {
}
}
static void load_texture(SDL_Renderer *renderer) {
static void init_render_local(SDL_Renderer *renderer) {
// vertical
tsegled_ver_on = new_texture(renderer, SEG_VER_WIDTH, SEG_VER_HEIGHT, 0xff, 0x00, 0x00);
tsegled_ver_off = new_texture(renderer, SEG_VER_WIDTH, SEG_VER_HEIGHT, 0x2b, 0x2b, 0x2b);
@ -84,7 +85,7 @@ static void load_texture(SDL_Renderer *renderer) {
#ifdef SEG_BKGND_ENA
SDL_Texture *tseg7_background;
#ifdef SEG_BKGND_CUSTOM
#if 0 //def SEG_BKGND_CUSTOM
tseg7_background = load_pic_texture(renderer, VSEGLED_BG_PATH);
#else
tseg7_background = new_texture(renderer, SEG_TOT_WIDTH, SEG_TOT_HEIGHT, 0x00, 0x00, 0x00);
@ -92,10 +93,51 @@ static void load_texture(SDL_Renderer *renderer) {
SDL_Rect rect_seg7 = {SEG_X, SEG_Y, SEG_TOT_WIDTH, SEG_TOT_HEIGHT};
SDL_RenderCopy(renderer, tseg7_background, NULL, &rect_seg7);
#endif
// draw surrounding lines
SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, 0);
const int gap = 14; // gap between surrounding lines and the 7-segments pad
SDL_Point top_left = Point(SEG_X, SEG_Y) + Point(-gap, -gap);
const int w = SEG_TOT_WIDTH + gap * 2;
const int h = SEG_TOT_HEIGHT + gap * 2;
const int ch_pad_h = 20;
const int ch_pad_w = 12;
const int d = 12;
SDL_Point p[32];
p[0] = top_left + Point(d, 0);
p[1] = p[0] + Point(w - 2 * d, 0);
p[2] = p[1] + Point(d, d);
p[3] = p[2] + Point(0, h - 2 * d);
p[4] = p[3] + Point(-d, d);
p[5] = p[4] - Point(w - 2 * d, 0);
p[6] = p[5] - Point(d, d);
p[7] = p[6] - Point(0, h - 2 * d);
p[8] = p[0];
draw_thicker_line(renderer, p, 9);
char buf[2] = "0";
SDL_Point p0 = Point(SEG_X, SEG_Y) + Point(SEG_TOT_WIDTH, SEG_TOT_HEIGHT) + Point(0, gap)
- Point(SEG_TOT_WIDTH / 8 / 2, 0) - Point(CH_WIDTH / 2, CH_HEIGHT / 2);
for (int i = 0; i < 8; i ++) {
SDL_Texture *t = str2texture(renderer, buf, 0xffffff, BOARD_BG_COLOR);
SDL_Rect r = Rect(p0, CH_WIDTH, CH_HEIGHT);
SDL_RenderCopy(renderer, t, NULL, &r);
SDL_DestroyTexture(t);
buf[0] ++;
p0 = p0 - Point(SEG_TOT_WIDTH / 8, 0);
}
char *str = "Seven Segment Display";
SDL_Texture *t = str2texture(renderer, "Seven Segment Display", 0xffffff, BOARD_BG_COLOR);
int w_texture = CH_WIDTH * strlen(str);
p0 = Point(SEG_X, SEG_Y) - Point(0, gap) - Point(0, CH_HEIGHT / 2)
+ Point(SEG_TOT_WIDTH / 2, 0) - Point(w_texture / 2, 0);
SDL_Rect r = Rect(p0, w_texture, CH_HEIGHT);
SDL_RenderCopy(renderer, t, NULL, &r);
SDL_DestroyTexture(t);
}
void init_segs7(SDL_Renderer *renderer) {
load_texture(renderer);
init_render_local(renderer);
for (int i = 0; i < 8; ++i) {
SDL_Rect mv = {SEG_X + SEG_SEP + (7 - i) * (SEG_HOR_WIDTH + SEG_DOT_WIDTH + SEG_VER_WIDTH * 2 + SEG_SEP * 2), SEG_Y + SEG_SEP, 0, 0};
bool is_len8 = (pin_array[GET_SEGA(i)].vector_len == 8);

View File

@ -1,15 +1,13 @@
#include <nvboard.h>
#include <term.h>
SDL_Texture* get_font_texture(uint8_t ch);
Term::Term(SDL_Renderer *r, int x, int y, int w, int h):
renderer(r), cursor_x(0), cursor_y(0), screen_y(0) {
region = { .x = x, .y = y, .w = w, .h = h };
w_in_char = region.w / 10;
h_in_char = region.h / 16;
w_in_char = region.w / CH_WIDTH;
h_in_char = region.h / CH_HEIGHT;
uint8_t *l = add_line();
cursor_texture = new_texture(r, 10, 16, 0x10, 0x10, 0x10);
cursor_texture = new_texture(r, CH_WIDTH, CH_HEIGHT, 0x10, 0x10, 0x10);
is_cursor_visible = true;
clear_screen();
dirty_line = new bool[h_in_char];
@ -117,10 +115,10 @@ void Term::draw_cursor() {
int y = cursor_y - screen_y;
int x = cursor_x;
SDL_Rect rect = region;
rect.w = 10, rect.h = 16;
rect.y += 16 * y;
rect.x += 10 * x;
SDL_Texture *t = is_cursor_visible ? cursor_texture : get_font_texture(' ');
rect.w = CH_WIDTH, rect.h = CH_HEIGHT;
rect.y += CH_HEIGHT * y;
rect.x += CH_WIDTH * x;
SDL_Texture *t = is_cursor_visible ? cursor_texture : ch2texture_term(' ');
SDL_RenderCopy(renderer, t, NULL, &rect);
set_redraw();
}
@ -130,7 +128,7 @@ void Term::update_gui() {
if (!dirty_screen) return;
SDL_Rect rect = region;
int x_start = rect.x;
rect.w = 10, rect.h = 16;
rect.w = CH_WIDTH, rect.h = CH_HEIGHT;
for (int y = 0; y < h_in_char; y ++) {
if (screen_y + y >= lines.size()) break;
if (!dirty_line[y]) continue;
@ -143,7 +141,7 @@ void Term::update_gui() {
uint8_t ch = l[x];
rect.x = region.x + rect.w * x;
SDL_Texture *t = get_font_texture(ch);
SDL_Texture *t = ch2texture_term(ch);
SDL_RenderCopy(renderer, t, NULL, &rect);
set_redraw();
}

View File

@ -13,10 +13,10 @@ UART::UART(SDL_Renderer *rend, int cnt, int init_val, int ct, int x, int y, int
Component(rend, cnt, init_val, ct),
tx_state(0), rx_state(0), divisor(16), tx_update_gui(false) {
tx_term = new Term(rend, x, y, w, h);
rx_term = new Term(rend, x, y + h + 1, w, 16);
rx_term = new Term(rend, x, y + h + 1, w, CH_HEIGHT);
SDL_Rect *rect_ptr = new SDL_Rect; // rx terminal
*rect_ptr = (SDL_Rect){x, y + h + 1, w, 16};
*rect_ptr = (SDL_Rect){x, y + h + 1, w, CH_HEIGHT};
set_rect(rect_ptr, 0);
uart_divisor_cnt = divisor - 1;
@ -31,7 +31,7 @@ UART::UART(SDL_Renderer *rend, int cnt, int init_val, int ct, int x, int y, int
SDL_SetRenderDrawColor(rend, 0x00, 0x00, 0x00, 0);
SDL_RenderDrawLine(rend, x, y + h, x + w, y + h);
SDL_RenderDrawLine(rend, x, y + h + 1 + 16, x + w, y + h + 1 + 16);
SDL_RenderDrawLine(rend, x, y + h + 1 + CH_HEIGHT, x + w, y + h + 1 + CH_HEIGHT);
SDL_SetRenderDrawColor(rend, 0xff, 0xff, 0xff, 0);
rx_update_gui = true;