From 417340ce91a11eaceb0b2def0cd972ec6e0f55eb Mon Sep 17 00:00:00 2001 From: lephe Date: Fri, 22 Feb 2019 15:08:51 +0100 Subject: [PATCH] topti: implement background color and text size Also transition the bootlog from fxlib to topti. --- include/gint/display-cg.h | 2 ++ include/gint/display-fx.h | 23 ++++++++++-- make/Makefile | 4 +-- src/core/bootlog.c | 39 +++++++++++---------- src/core/start.c | 4 +-- src/render-fx/topti-asm.s | 7 ++-- src/render-fx/topti.c | 73 ++++++++++++++++++++++++++++++++------- 7 files changed, 111 insertions(+), 41 deletions(-) diff --git a/include/gint/display-cg.h b/include/gint/display-cg.h index 36cdd33..2466800 100644 --- a/include/gint/display-cg.h +++ b/include/gint/display-cg.h @@ -16,6 +16,8 @@ #define DWIDTH 396 #define DHEIGHT 224 +typedef void font_t; + #endif /* FXCG50 */ #endif /* GINT_DISPLAY_CG */ diff --git a/include/gint/display-fx.h b/include/gint/display-fx.h index ae758d9..c6fcba6 100644 --- a/include/gint/display-fx.h +++ b/include/gint/display-fx.h @@ -184,6 +184,24 @@ typedef struct @font Font to use for subsequent text rendering calls */ void dfont(font_t const * font); +/* dsize() - get the width and height of rendered text + This function computes the size that the given string would take up if + rendered with a certain font. If you specify a NULL font, the currently + configured font will be used; this differs from dfont() which uses gint's + default font when NULL is passed. + + Note that the height of each glyph is not stored in the font, only the + maximum. Usually this is what you want because vertically-centered strings + must have the same baseline regardless of their contents. So the height + returned by dsize() is the same for all strings, only depends on the font. + + The height is computed in constant time, and the width in linear time. + + @str String whose size must be evaluated + @font Font to use; if NULL, defaults to the current font + @w @h Set to the width and height of the rendered text, may be NULL */ +void dsize(const char *str, font_t const * font, int *w, int *h); + /* dtext() - display a string of text Draws some text in the video RAM using the font set with dfont() (or gint's @@ -196,8 +214,9 @@ void dfont(font_t const * font); @x @y Coordinates of top-left corner of the rendered string @str String to display - @color Which color to use */ -void dtext(int x, int y, const char *str, color_t color); + @fg Text color + @bg Background color, pass [color_none] to disable */ +void dtext(int x, int y, const char *str, color_t fg, color_t bg); #endif /* FX9860G */ diff --git a/make/Makefile b/make/Makefile index 280c633..7a4c82b 100755 --- a/make/Makefile +++ b/make/Makefile @@ -77,7 +77,7 @@ conv = fxconv # # Version symbol is obtained by using the last commit hash on 7 nibbles -version_hash = 0x0$(shell git show --format='%h' HEAD | tr -d "\n") +version_hash = 0x0$(shell git rev-parse --short HEAD) # @@ -114,7 +114,7 @@ version.o: @ mkdir -p $(dir $@) @ echo "_GINT_VERSION = $(version_hash);" > $@.txt $(call cmd_b,ld,$@) $(ld) -r -R $@.txt -o $@ - +.PHONY: version.o # # Cleaning # diff --git a/src/core/bootlog.c b/src/core/bootlog.c index 9683b7d..65d4a0f 100644 --- a/src/core/bootlog.c +++ b/src/core/bootlog.c @@ -9,6 +9,12 @@ #include #include #include +#include + +#ifdef FXCG50 +#define dclear(c) Bdisp_AllClr_VRAM() +#define dupdate() Bdisp_PutDisp_DD() +#endif /* Linker script symbols - see core/start.c for details */ extern char @@ -20,24 +26,19 @@ extern char void bootlog_loaded(void) { /* Version string - the string constant resides in ROM */ - uint32_t v = GINT_VERSION; - const char *model = "gint #0.0-000"; + const char *base = "gint @"; + const char *hexa = "0123456789abcdef"; char str[14]; - for(int i = 0; i < 14; i++) str[i] = model[i]; + for(int i = 0; i < 6; i++) str[i] = base[i]; + str[13] = 0; - /* Quickly get the three digits of the build number */ - int x_q = (v & 0xffff) / 10; - int x_r = (v & 0xffff) - 10 * x_q; - int y_q = x_q / 10; - int y_r = x_q - 10 * y_q; - - str[5] = (v & 0xff000000) >> 24; - str[6] += (v & 0x00f00000) >> 20; - str[8] += (v & 0x000f0000) >> 16; - str[10] += y_q; - str[11] += y_r; - str[12] += x_r; + /* Retrieve the commit number */ + for(int i = 0; i < 7; i++) + { + int shift = 24 - (i << 2); + str[i + 6] = hexa[(GINT_VERSION >> shift) & 0xf]; + } /* Size of memory sections */ uint32_t rom_size = (uint32_t)&srom; @@ -49,7 +50,7 @@ void bootlog_loaded(void) const char *names = "SH7337\0 SH7305\0 SH7355\0 SH7724"; /* TODO: Use a solid API for boot-time printing */ - Bdisp_AllClr_VRAM(); + dclear(color_white); print(1, 1, str); print(15, 1, " Loaded"); @@ -64,7 +65,7 @@ void bootlog_loaded(void) print_dec(17, 3, &mtors - &btors, 2); print_dec(20, 3, &etors - &mtors, 2); - Bdisp_PutDisp_DD(); + dupdate(); } /* bootlog_mapped() - ROM mapping stage */ @@ -78,7 +79,7 @@ void bootlog_mapped(int rom, int ram) (rom < 0) ? print(9, 4, "???") : print_dec(9, 4, rom, 3); (ram < 0) ? print(18, 4, "???") : print_dec(18, 4, ram, 3); - Bdisp_PutDisp_DD(); + dupdate(); } /* bootlog_kernel() - gint loading stage */ @@ -113,5 +114,5 @@ void bootlog_kernel(void) print_hex(18, 6, SH7305_INTC._->IPRL.word, 4); } - Bdisp_PutDisp_DD(); + dupdate(); } diff --git a/src/core/start.c b/src/core/start.c index f445c17..a00ad85 100644 --- a/src/core/start.c +++ b/src/core/start.c @@ -142,9 +142,9 @@ int start(int isappli, int optnum) if(rom < (uint32_t)&srom) { Bdisp_AllClr_VRAM(); - print(1, 1, "Missing memory!"); + PrintXY(0, 0, "Missing memory!", 0); print_hex(1, 2, rom, 8); - print(1, 3, "<"); + PrintXY(0, 16, "<", 0); print_hex(1, 4, (uint32_t)&srom, 8); Bdisp_PutDisp_DD(); while(1); diff --git a/src/render-fx/topti-asm.s b/src/render-fx/topti-asm.s index 28695a8..a2fae15 100644 --- a/src/render-fx/topti-asm.s +++ b/src/render-fx/topti-asm.s @@ -29,10 +29,10 @@ _topti_asm_white: add #16, r4 mov.l @r4, r1 dt r7 - not r1, r1 - and r1, r0 + not r0, r0 + and r0, r1 bf.s 1b - mov.l r0, @r4 + mov.l r1, @r4 rts nop @@ -79,6 +79,7 @@ _topti_asm_black: 1: mov.l @r6+, r0 dt r7 mov.l @r4, r1 + /* (bubble) */ or r1, r0 mov.l r0, @r4 bf.s 1b diff --git a/src/render-fx/topti.c b/src/render-fx/topti.c index 6a9a3d1..724277c 100644 --- a/src/render-fx/topti.c +++ b/src/render-fx/topti.c @@ -169,12 +169,13 @@ int topti_split(uint32_t const * glyph, int width, int height, int free, Combines glyph data onto VRAM operands and blits them efficiently onto the VRAM. To write a single character, use a 2-byte string with a NUL. - @x @y Target position on VRAM - @str Text source - @f Font - @asm_text Assembler function for the rendering proper */ + @x @y Target position on VRAM + @str Text source + @f Font + @asm_fg Assembler function for text rendering + @asm_bg Assembler function for background rendering */ void topti_render(int x, int y, const char *str, font_t const *f, - asm_text_t *asm_text) + asm_text_t *asm_fg, asm_text_t *asm_bg) { /* Storage height and number of free bits in operators[] */ int height = f->data_height, free; @@ -191,9 +192,14 @@ void topti_render(int x, int y, const char *str, font_t const *f, int vdisp = 0; if(y < 0) vdisp = -y, y = 0; - /* Operator data */ + /* Operator data and background */ uint32_t operators[height]; - for(int i = 0; i < height; i++) operators[i] = 0; + uint32_t bg[height]; + for(int i = 0; i < height; i++) + { + operators[i] = 0; + bg[i] = 0xffffffff >> (x & 31); + } /* Put an initial offset to the operators to honor the x coordinate */ free = 32 - (x & 31); @@ -223,11 +229,19 @@ void topti_render(int x, int y, const char *str, font_t const *f, /* Once operators are full, update VRAM and start again */ - if(x >= 0) asm_text(v1, v2, operators + vdisp, height - vdisp); + if(x >= 0) + { + asm_bg(v1, v2, bg + vdisp, height - vdisp); + asm_fg(v1, v2, operators + vdisp, height - vdisp); + } v1++, v2++; if(++x >= 4) break; - for(int i = 0; i < height; i++) operators[i] = 0; + for(int i = 0; i < height; i++) + { + operators[i] = 0; + bg[i] = 0xffffffff; + } free += 32; /* If information was lost in the split, finish it */ @@ -241,12 +255,45 @@ void topti_render(int x, int y, const char *str, font_t const *f, /* Put the final longwords */ if(x >= 0 && x < 4 && free < 32) - asm_text(v1, v2, operators + vdisp, height - vdisp); + { + for(int i = 0; i < height; i++) bg[i] &= ~((1 << free) - 1); + asm_bg(v1, v2, bg + vdisp, height - vdisp); + asm_fg(v1, v2, operators + vdisp, height - vdisp); + } +} + +/* dsize() - get the width and height of rendered text */ +void dsize(const char *str, font_t const * f, int *w, int *h) +{ + if(!f) f = topti_font; + if(h) *h = f->line_height; + if(!w) return; + + /* Width for monospaced fonts is easy, unfortunately we still need to + compute the length of [str]. Critical applications might do the + product themselves to avoid this cost. */ + if(!f->prop) + { + int length = 0; + while(*str++) length++; + *w = (f->width + 1) * length - 1; + return; + } + + /* For proportional fonts, fetch the width of each individual glyphs */ + int width = 0; + while(*str) + { + int glyph = charset_decode(f->charset, *str++); + if(glyph > 0) width += f->sized_data[glyph] + 1; + } + *w = width - 1; } /* dtext() - display a string of text */ -void dtext(int x, int y, const char *str, color_t color) +void dtext(int x, int y, const char *str, color_t fg, color_t bg) { - if((uint)color >= 8) return; - topti_render(x, y, str, topti_font, topti_asm_text[color]); + if((uint)fg >= 8 || (uint)bg >= 8) return; + topti_render(x, y, str, topti_font, topti_asm_text[fg], + topti_asm_text[bg]); }