topti: implement background color and text size

Also transition the bootlog from fxlib to topti.
This commit is contained in:
lephe 2019-02-22 15:08:51 +01:00
parent 3f7c0a04ad
commit 417340ce91
7 changed files with 111 additions and 41 deletions

View file

@ -16,6 +16,8 @@
#define DWIDTH 396
#define DHEIGHT 224
typedef void font_t;
#endif /* FXCG50 */
#endif /* GINT_DISPLAY_CG */

View file

@ -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 */

View file

@ -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
#

View file

@ -9,6 +9,12 @@
#include <gint/mpu/intc.h>
#include <core/mmu.h>
#include <gint/gint.h>
#include <gint/display.h>
#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();
}

View file

@ -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);

View file

@ -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

View file

@ -172,9 +172,10 @@ int topti_split(uint32_t const * glyph, int width, int height, int free,
@x @y Target position on VRAM
@str Text source
@f Font
@asm_text Assembler function for the rendering proper */
@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]);
}