diff --git a/board/fxcg50/fxcg50.ld b/board/fxcg50/fxcg50.ld index 682f57a..5c768e4 100644 --- a/board/fxcg50/fxcg50.ld +++ b/board/fxcg50/fxcg50.ld @@ -13,6 +13,8 @@ MEMORY { /* virtual memory, read-write segment */ userram (WX) : o = 0x00000000, l = 1M + /* On-chip IL memory */ + ilram (rwx): o = 0xe5200000, l = 4k } SECTIONS @@ -153,6 +155,21 @@ SECTIONS } > userram + /* On-chip memory sections: IL and Y (X is reserved) */ + + . = ORIGIN(ilram); + .ilram ALIGN(4) : ALIGN(4) { + _lilram = LOADADDR(.ilram); + _rilram = . ; + + *(.vhex.ilram) + + . = ALIGN(16); + } > ilram AT> userram + _silram = SIZEOF(.ilram); + + + /* unwanted section */ /DISCARD/ : { *(.rela.debug*) diff --git a/board/fxcg50/initialize.c b/board/fxcg50/initialize.c index 473535e..dcb6e1c 100644 --- a/board/fxcg50/initialize.c +++ b/board/fxcg50/initialize.c @@ -16,6 +16,9 @@ extern void (*bctors)(void), (*ectors)(void); extern void (*bdtors)(void), (*edtors)(void); +/* on-chip RAM information */ +extern uint32_t lilram, silram, rilram; /* IL memory section */ + /* User-provided main() function */ extern int main(void); @@ -30,6 +33,22 @@ static void callarray(void (**f)(void), void (**l)(void)) while(f < l) (*(*f++))(); } +/* regcpy(): Copy a memory region using symbol information + @l Source pointer (load address) + @s Size of area (should be a multiple of 16) + @r Destination pointer (relocation address) */ +static void regcpy(uint32_t * __restrict l, int32_t s, uint32_t * __restrict r) +{ + while(s > 0) + { + *r++ = *l++; + *r++ = *l++; + *r++ = *l++; + *r++ = *l++; + s -= 16; + } +} + /* initialize() : Where it all starts We are currently in a RAM location at a non-constant address due to the @@ -93,6 +112,10 @@ void initialize(void) tell us if we are running in an emulator or on a real device. */ hw_detect(); + /* move special on-chip RAM section */ + regcpy(&lilram, (uintptr_t)&silram, &rilram); + + /* Install Vhex, switch VBR, initialize drivers and modules */ kinit(); diff --git a/include/vhex/display.h b/include/vhex/display.h index 7fddbd9..c6d8352 100644 --- a/include/vhex/display.h +++ b/include/vhex/display.h @@ -43,6 +43,6 @@ VINLINE size_t dheight(void) //--- /* dclear_render() : internal pipeline drawing */ -extern void dclear_render(struct dshader_surface *surface, uint32_t color); +extern void dclear_render(dsurface_t *surface, uint32_t color); #endif /*__VHEX_DISPLAY__*/ diff --git a/include/vhex/display/color.h b/include/vhex/display/color.h index 9fcc2fc..a5ba021 100644 --- a/include/vhex/display/color.h +++ b/include/vhex/display/color.h @@ -4,16 +4,16 @@ //FIXME: this is plateform-specific :/ enum { - C_WHITE = 0xffff, - C_LIGHT = 0xad55, - C_DARK = 0x528a, - C_BLACK = 0x0000, + C_WHITE = 0xffff, + C_LIGHT = 0xad55, + C_DARK = 0x528a, + C_BLACK = 0x0000, - C_RED = 0xf800, - C_GREEN = 0x07e0, - C_BLUE = 0x001f, + C_RED = 0xf800, + C_GREEN = 0x07e0, + C_BLUE = 0x001f, - C_NONE = -1, + C_NONE = -1, C_INVERT = -2, }; diff --git a/include/vhex/display/font.h b/include/vhex/display/font.h index 9ba8014..9cec5b6 100644 --- a/include/vhex/display/font.h +++ b/include/vhex/display/font.h @@ -1,91 +1,2 @@ -#ifndef __VHEX_DISPLAY_FONT__ -# define __VHEX_DISPLAY_FONT__ - -#include -#include -#include - -/* font_t: Font data encoded for dfont*() functions */ -typedef struct font { - /* Font name (NUL-terminated), NULL if no title */ - char const *name; - - /* Font shape flags */ - byte_union(shape, - uint8_t bold :1; - uint8_t italic :1; - uint8_t serif :1; - uint8_t mono :1; - uint8_t :3; - uint8_t prop :1; - ); - - /* Character spacing (usually 1) */ - uint8_t char_spacing; - - /* glyph information */ - struct { - uint8_t height; - uint8_t line_height; - uint32_t *data; - uint32_t count; - - union { - /* For monospaced fonts */ - struct { - uint8_t width; - uint16_t storage_size; - } mono; - /* For proportional fonts */ - struct __workaround { - uint8_t width; - uint16_t index; - uint8_t shift; - } *prop; - }; - } glyph; - - /* unicode blocks */ - struct { - struct { - /* Unicode point of first character in block */ - uint32_t start :20; - /* Length of block */ - uint32_t length :12; - } *blocks; - uint8_t block_count; - } unicode; - -} VPACKED(4) font_t; - -/* dfont_get() : get the current font */ -extern font_t *dfont_get(void); - -/* dfont_text_geometry() : get the char geometry */ -extern int dfont_text_geometry( - font_t *font, - char const * const str_char, - int *size, - size_t *w, - size_t *h -); - - -//--- -// Kernel-level API -//--- - -/* dfont_char_render() : character render */ -extern void dfont_char_render( - struct dshader_surface *surface, - int glyph_idx, - uint32_t *arg -); - -/* dfont_glyph_index(): Obtain the glyph index of a Unicode code point */ -extern int dfont_glyph_index(font_t const *f, uint32_t code_point); - -/* dfont_render() : draw caracter in surface */ -extern void dfont_text_render(struct dshader_surface *surface, uint32_t *arg); - -#endif /* __VHEX_DISPLAY_FONT__ */ +#include +#include diff --git a/include/vhex/display/font/information.h b/include/vhex/display/font/information.h new file mode 100644 index 0000000..40bb0a6 --- /dev/null +++ b/include/vhex/display/font/information.h @@ -0,0 +1,24 @@ +#ifndef __VHEX_DISPLAY_FONT_INFORMATION__ +# define __VHEX_DISPLAY_FONT_INFORMATION__ + +#include + +/* dfont_get() : get the current font */ +extern font_t *dfont_get(void); + +/* dfont_glyph_index(): Obtain the glyph index of a Unicode code point */ +extern int dfont_glyph_index(font_t const *f, uint32_t code_point); + +/* dfont_utf8_next(): Read the next UTF-8 code point of a string */ +extern uint32_t dfont_utf8_next(uint8_t const **str_pointer); + +/* dfont_text_geometry() : get the rendered text geometry with a given font */ +extern int dfont_text_geometry( + font_t *font, + char const * const str_char, + int *size, + size_t *w, + size_t *h +); + +#endif /* __VHEX_DISPLAY_FONT_INFORMATION__ */ diff --git a/include/vhex/display/font/render.h b/include/vhex/display/font/render.h new file mode 100644 index 0000000..fe5851a --- /dev/null +++ b/include/vhex/display/font/render.h @@ -0,0 +1,23 @@ +#ifndef __VHEX_DISPLAY_FONT_RENDER__ +# define __VHEX_DISPLAY_FONT_RENDER__ + +#include + +//--- +// User-level API +//--- + +/* dfont_cjar() : display one char */ +extern void dfont_char(uint32_t n, int x, int y, int fg, int bg); + +//--- +// kernel-level API +//--- + +extern void dfont_char_render( + dsurface_t *surface, + int glyph_idx, + uint32_t *arg +); + +#endif /* __VHEX_DISPLAY_FONT_RENDER__ */ diff --git a/include/vhex/display/font/types.h b/include/vhex/display/font/types.h new file mode 100644 index 0000000..314cc3c --- /dev/null +++ b/include/vhex/display/font/types.h @@ -0,0 +1,60 @@ +#ifndef __VHEX_DISPLAY_FONT_TYPES__ +# define __VHEX_DISPLAY_FONT_TYPES__ + +#include +#include + +/* font_t: Font data encoded for dfont*() functions */ +typedef struct font { + /* Font name (NUL-terminated), NULL if no title */ + char const *name; + + /* Font shape flags */ + byte_union(shape, + uint8_t bold :1; + uint8_t italic :1; + uint8_t serif :1; + uint8_t mono :1; + uint8_t :3; + uint8_t prop :1; + ); + + /* Character spacing (usually 1) */ + uint8_t char_spacing; + + /* glyph information */ + struct { + uint8_t height; + uint8_t line_height; + uint32_t *data; + uint32_t count; + + union { + /* For monospaced fonts */ + struct { + uint8_t width; + uint16_t storage_size; + } mono; + /* For proportional fonts */ + struct __workaround { + uint8_t width; + uint16_t index; + uint8_t shift; + } *prop; + }; + } glyph; + + /* unicode blocks */ + struct { + struct { + /* Unicode point of first character in block */ + uint32_t start :20; + /* Length of block */ + uint32_t length :12; + } *blocks; + uint8_t block_count; + } unicode; + +} VPACKED(4) font_t; + +#endif /* __VHEX_DISPLAY_FONT_TYPES__ */ diff --git a/include/vhex/display/interface.h b/include/vhex/display/interface.h new file mode 100644 index 0000000..bf029f9 --- /dev/null +++ b/include/vhex/display/interface.h @@ -0,0 +1,16 @@ +#ifndef __VHEX_DISPLAY_INTERFACE__ +# define __VHEX_DISPLAY_INTERFACE__ + +#include + +/* dstack_drv_interface - driver interface */ +struct dstack_drv_interface { + int (*frame_start)(dsurface_t *); + int (*frame_frag_next)(dsurface_t *); + int (*frame_frag_send)(dsurface_t *); + int (*frame_end)(dsurface_t *); + size_t display_width; + size_t display_height; +}; + +#endif /* __VHEX_DISPLAY_INTERFACE__ */ diff --git a/include/vhex/display/shader.h b/include/vhex/display/shader.h index fb7462e..612fb03 100644 --- a/include/vhex/display/shader.h +++ b/include/vhex/display/shader.h @@ -1,33 +1,18 @@ #ifndef __VHEX_DISPLAY_SHADER__ # define __VHEX_DISPLAY_SHADER__ -#include -#include - -/* dshader_surface - Describe the surface */ -struct dshader_surface { - void *draw; - void *frag; - size_t width; - size_t height; - int x1; - int y1; - int x2; - int y2; -}; -typedef struct dshader_surface dsurface_t; +#include /* dshader - display shader definition */ struct dshader_call { int (*routine)( - struct dshader_surface *surface, + dsurface_t *surface, uint32_t *draw_args, uint32_t *shader_args ); uint32_t args[8]; }; typedef struct dshader_call dshader_call_t; -typedef struct dshader_call dshader_t; /* DSHADER_LIST - helper to create a list of shader "on-the-fly" */ #define DSHADER_LIST(shader_list) (dshader_call_t*)&{ shader_list } diff --git a/include/vhex/display/stack.h b/include/vhex/display/stack.h index fce9cc6..9f979e8 100644 --- a/include/vhex/display/stack.h +++ b/include/vhex/display/stack.h @@ -4,12 +4,10 @@ #include #include + /* dstack_call - dstack indirect call (same as dshader) */ struct dstack_call { - void (*routine)( - struct dshader_surface *surface, - uint32_t *draw_args - ); + void (*routine)(dsurface_t *surface, uint32_t *draw_args); uint32_t args[12]; }; typedef struct dstack_call dstack_call_t; @@ -32,41 +30,12 @@ struct dstack_action { } -/* dstack_config - dstack configuration structure */ -struct dstack_config { - int default_icall_pool_slot; - int default_icall_args_nb; - int default_shader_per_action; -}; - -#ifndef DSTACK_DEFAULT_ICALL_SLOT -# define DSTACK_DEFAULT_ICALL_SLOT 32 -#endif - -#ifndef DSTACK_DEFAULT_ICALL_ARGS -# define DSTACK_DEFAULT_ICALL_ARGS 12 -#endif - -#ifndef DSTACK_DEFAULT_SHADER_PER_ACTION -# define DSTACK_DEFAULT_SHADER_PER_ACTION 4 -#endif - -/* dstack_drv_interface - driver interface */ -struct dstack_drv_interface { - int (*frame_start)(struct dshader_surface *); - int (*frame_frag_next)(struct dshader_surface *); - int (*frame_frag_send)(struct dshader_surface *); - int (*frame_end)(struct dshader_surface *); - size_t display_width; - size_t display_height; -}; - //--- // Display stack API //--- /* dstack_init() : Initialise the draw stack (should not be involved) */ -extern int dstack_init(struct dstack_config *config); +extern int dstack_init(void); /* dstack_add_action() : add a new action in the draw stack */ extern did_t dstack_add_action( diff --git a/include/vhex/display/text.h b/include/vhex/display/text.h index e03be0a..372818d 100644 --- a/include/vhex/display/text.h +++ b/include/vhex/display/text.h @@ -1,46 +1,2 @@ -#ifndef __VHEX_DISPLAY_TEXT__ -# define __VHEX_DISPLAY_TEXT__ - -#include -#include - -/* Alignment settings for dtext_opt() and dprint_opt(). Combining a vertical - and a horizontal alignment option specifies where a given point (x,y) should - be relative to the rendered string. */ -enum { - /* Horizontal settings: default in dtext() is DTEXT_LEFT */ - DTEXT_LEFT = 0, - DTEXT_CENTER = 1, - DTEXT_RIGHT = 2, - /* Vertical settings: default in dtext() is DTEXT_TOP */ - DTEXT_TOP = 0, - DTEXT_MIDDLE = 1, - DTEXT_BOTTOM = 2, -}; - -/* dtext_opt(): Display a string of text */ -extern did_t dtext_opt( - int x, int y, - int fg, int bg, - int halign, int valign, - char const * const str, int size -); - -/* dtext() : display raw text */ -extern did_t dtext(int x, int y, int fg, char const * const text); - -/* dprint_opt(): Display a formated string */ -extern did_t dprint_opt( - int x, int y, - int fg, int bg, - int halign, int valign, - char const * const str, ... -); - -/* dprint() : display formated text */ -extern did_t dprint(int x, int y, int fg, char const * const text, ...); - -/* dnsize(): Get the width and height of rendered text for the n first char */ -extern int dtext_geometry(char const * const str, int *n, size_t *w, size_t *h); - -#endif /* __VHEX_DISPLAY_TEXT__ */ +#include +#include diff --git a/include/vhex/display/text/information.h b/include/vhex/display/text/information.h new file mode 100644 index 0000000..8b99600 --- /dev/null +++ b/include/vhex/display/text/information.h @@ -0,0 +1,9 @@ +#ifndef __VHEX_DISPLAY_TEXT_INFORMATION__ +# define __VHEX_DISPLAY_TEXT_INFORMATION__ + +#include + +/* dtext_geometry() : get the rendered text geometry with the current font */ +extern int dtext_geometry(char const * const str, int *n, size_t *w, size_t *h); + +#endif /* __VHEX_DISPLAY_TEXT_INFORMATION__ */ diff --git a/include/vhex/display/text/render.h b/include/vhex/display/text/render.h new file mode 100644 index 0000000..255c2fe --- /dev/null +++ b/include/vhex/display/text/render.h @@ -0,0 +1,43 @@ +#ifndef __VHEX_DISPLAY_TEXT_RENDER__ +# define __VHEX_DISPLAY_TEXT_RENDER__ + +#include +#include + +/* Alignment settings for dtext_opt() and dprint_opt(). Combining a vertical + and a horizontal alignment option specifies where a given point (x,y) should + be relative to the rendered string. */ +enum { + /* Horizontal settings: default in dtext() is DTEXT_LEFT */ + DTEXT_LEFT = 0, + DTEXT_CENTER = 1, + DTEXT_RIGHT = 2, + /* Vertical settings: default in dtext() is DTEXT_TOP */ + DTEXT_TOP = 0, + DTEXT_MIDDLE = 1, + DTEXT_BOTTOM = 2, +}; + +/* dtext_opt(): Display a string of text */ +extern did_t dtext_opt( + int x, int y, + int fg, int bg, + int halign, int valign, + char const * const str, int size +); + +/* dtext() : display raw text */ +extern did_t dtext(int x, int y, int fg, char const * const text); + +/* dprint_opt(): Display a formated string */ +extern did_t dprint_opt( + int x, int y, + int fg, int bg, + int halign, int valign, + char const * const str, ... +); + +/* dprint() : display formated text */ +extern did_t dprint(int x, int y, int fg, char const * const text, ...); + +#endif /* __VHEX_DISPLAY_TEXT_RENDER__ */ diff --git a/include/vhex/display/types.h b/include/vhex/display/types.h index ef15607..43ab185 100644 --- a/include/vhex/display/types.h +++ b/include/vhex/display/types.h @@ -1,7 +1,21 @@ #ifndef __VHEX_DISPLAY_TYPES__ # define __VHEX_DISPLAY_TYPES__ +#include + /* draw ID */ typedef int did_t; +/* dsurface - Describe the surface */ +struct dsurface { + void *vram; + size_t width; + size_t height; + int x1; + int y1; + int x2; + int y2; +}; +typedef struct dsurface dsurface_t; + #endif /* __VHEX_DISPLAY_TYPES__ */ diff --git a/make/Makefile b/make/Makefile index 9e172f8..edd4472 100644 --- a/make/Makefile +++ b/make/Makefile @@ -156,6 +156,7 @@ t-$1-$2-gcc := $$(CONFIG.$1.TOOLCHAIN.PREFIX)gcc t-$1-$2-ldflags := $$(CONFIG.$1.TOOLCHAIN.LDFLAGS) t-$1-$2-cflags := $$(CONFIG.$1.TOOLCHAIN.CFLAGS) t-$1-$2-cflags += -fpic -ffreestanding -nostdlib -fstrict-volatile-bitfields -O1 +t-$1-$2-cflags += -Wa,--dsp # generate compiler information (used to find some library like libgcc.a) t-$1-$2-gcc-base := $$(shell $$(CONFIG.$1.TOOLCHAIN.PREFIX)gcc --print-search-dirs | grep install | sed 's/install: //') diff --git a/src/drivers/screen/R61524/frame.S b/src/drivers/screen/R61524/frame.S index 796d441..eeb7e91 100644 --- a/src/drivers/screen/R61524/frame.S +++ b/src/drivers/screen/R61524/frame.S @@ -3,11 +3,42 @@ .global _r61524_frame_frag_send -.align 4 +.balign 4 ! r61524_frame_frag_send() : send fragment in screen _r61524_frame_frag_send: + ! prepare loop information + mov #0xb4, r3 ! EX (1) + mov.l @(8, r4), r0 ! LS + shll8 r3 ! EX (2) + mov.l @(0, r4), r2 ! LS + shll16 r3 ! EX (3) + mov.w long_frag, r1 ! LS + cmp/eq #4, r0 ! EX (4) + bf 1f ! BR (?) + mov.w short_frag, r1 ! LS + nop ! MT + + ! prepare loop +1: ldrs 2f + ldre 3f + nop + ldrc r1 + +2: mov.w @r2+, r0 +3: mov.w r0, @r3 + + rts + nop + +long_frag: + .word 3960 +short_frag: + .word 1584 +#endif + +#if 0 ! check number of word to be send mov.l @(20, r4), r0 ! LS cmp/eq #220, r0 ! EX (1) diff --git a/src/drivers/screen/R61524/r61524.c b/src/drivers/screen/R61524/r61524.c index f7703eb..7d07e92 100644 --- a/src/drivers/screen/R61524/r61524.c +++ b/src/drivers/screen/R61524/r61524.c @@ -1,25 +1,14 @@ #include #include #include -#include +#include //--- // R61524 driver API //--- -/* r61524_clear_surface() - optimal way to clear the draw and render surface */ -VINLINE void r61524_clear_surface(struct dshader_surface *surface) -{ - uint32_t *xram = surface->draw; - int size = (surface->y1 == 220) ? 792 : 1980; - - for (int i = 0; i < size; ++i) { - xram[i] = 0x00010001; - } -} - /* r61524_frame_start() - prepar the screen and reset surfaces */ -int r61524_frame_start(struct dshader_surface *surface) +int r61524_frame_start(dsurface_t *surface) { /* Set the windows size */ r61524_select(horizontal_ram_start); @@ -41,21 +30,17 @@ int r61524_frame_start(struct dshader_surface *surface) r61524_select(write_data); /* initialize surface information */ - surface->draw = (void*)0xe5007000; - surface->frag = (void*)0xe5017000; + surface->vram = (void*)0xe5017000; surface->width = 396; surface->height = 10; surface->x1 = 0; surface->y1 = 0; surface->x2 = 395; surface->y2 = 9; - - /* reset the two surfaces */ - r61524_clear_surface(surface); return (0); } -int r61524_frame_frag_next(struct dshader_surface *surface) +int r61524_frame_frag_next(dsurface_t *surface) { surface->y1 += 10; if (surface->y1 >= 224) { @@ -69,9 +54,9 @@ int r61524_frame_frag_next(struct dshader_surface *surface) return (0); } -VWEAK int r61524_frame_frag_send(struct dshader_surface *surface) +VWEAK int r61524_frame_frag_send(dsurface_t *surface) { - uint16_t * restrict yram = surface->frag; + uint16_t * restrict yram = surface->vram; int size = (surface->y1 == 220) ? 1584 : 3960; for (int i = 0; i < size; ++i) { @@ -80,7 +65,7 @@ VWEAK int r61524_frame_frag_send(struct dshader_surface *surface) return (0); } -int r61524_frame_end(struct dshader_surface *surface) +int r61524_frame_end(dsurface_t *surface) { (void)surface; return (0); diff --git a/src/modules/display/dclear.c b/src/modules/display/dclear.c index 9fe1441..1c5bc87 100644 --- a/src/modules/display/dclear.c +++ b/src/modules/display/dclear.c @@ -7,12 +7,12 @@ //--- /* dclear_draw() : real drawing algorithm */ -void dclear_render(struct dshader_surface *surface, uint32_t color) +void dclear_render(dsurface_t *surface, uint32_t color) { uint32_t *vram; int size = (surface->y1 == 220) ? 792 : 1980; - vram = surface->frag; + vram = surface->vram; for (int i = 0; i < size; ++i) vram[i] = color; } @@ -22,7 +22,7 @@ void dclear_render(struct dshader_surface *surface, uint32_t color) //--- /* dclear_dstack() : dstack rwrapper primitive */ -void dclear_dstack(struct dshader_surface *surface, uint32_t *arg) +void dclear_dstack(dsurface_t *surface, uint32_t *arg) { dclear_render(surface, arg[0]); } diff --git a/src/modules/display/display.c b/src/modules/display/display.c index fc94a84..b1ad116 100644 --- a/src/modules/display/display.c +++ b/src/modules/display/display.c @@ -6,12 +6,7 @@ /* __display_init() : initialize the display */ static void __display_init(void) { - struct dstack_config conf = { - .default_icall_pool_slot = DSTACK_DEFAULT_ICALL_SLOT, - .default_icall_args_nb = DSTACK_DEFAULT_ICALL_ARGS, - .default_shader_per_action = DSTACK_DEFAULT_SHADER_PER_ACTION - }; - dstack_init(&conf); + dstack_init(); } /* __display_quit() : uninit the display */ diff --git a/src/modules/display/draw/dline.c b/src/modules/display/draw/dline.c index 836c6b2..950e3b3 100644 --- a/src/modules/display/draw/dline.c +++ b/src/modules/display/draw/dline.c @@ -76,7 +76,7 @@ void dhline_render(dsurface_t *surface, int y, int x1, int x2, int color) /* Use longwords to do the copy, but first paint the endpoints to heed for odd x1 and x2. Checking the parity may be a waste of time. */ - uint16_t *vram = surface->frag; + uint16_t *vram = surface->vram; if (color != C_INVERT) { vram[offset + x1] = color; vram[offset + x2] = color; @@ -117,7 +117,7 @@ void dvline_render(dsurface_t *surface, int x, int y1, int y2, int color) y1 -= surface->y1; y2 -= surface->y1; - uint16_t *vram = surface->frag; + uint16_t *vram = surface->vram; uint16_t *v = &vram[(surface->width * y1) + x]; int height = y2 - y1; diff --git a/src/modules/display/draw/dpixel.c b/src/modules/display/draw/dpixel.c index 1a1bbe9..4cc3076 100644 --- a/src/modules/display/draw/dpixel.c +++ b/src/modules/display/draw/dpixel.c @@ -26,17 +26,20 @@ void dpixel_render(dsurface_t *surface, int x, int y, int color) int draw_idx = real_y + real_x; /* handle special color */ - //uint16_t *draw = surface->draw; - uint16_t *frag = surface->frag; + uint16_t *vram = surface->vram; if (color == C_INVERT) - color = frag[draw_idx] ^ 0xffff; + color = vram[draw_idx] ^ 0xffff; /* set the pixel */ - frag[draw_idx] = color; + vram[draw_idx] = color; } +//--- +// Dstack-level API +//--- + /* dpixel_render_dstack() : dstack-API compatible render */ -void dpixel_dstack(struct dshader_surface *surface, uint32_t *arg) +void dpixel_dstack(dsurface_t *surface, uint32_t *arg) { dpixel_render(surface, arg[0], arg[1], arg[2]); } diff --git a/src/modules/display/dstack.c b/src/modules/display/dstack.c index 699b22d..adc1401 100644 --- a/src/modules/display/dstack.c +++ b/src/modules/display/dstack.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -33,21 +34,21 @@ static struct { //--- /* dstack_init() : Initialise the draw stack (should not be involved) */ -int dstack_init(struct dstack_config *config) +int dstack_init(void) { dstack_info.pool.action = calloc( - config->default_icall_pool_slot, + 16, sizeof(struct dstack_action) ); dstack_info.pool.idx = -1; - dstack_info.pool.slots = config->default_icall_pool_slot; + dstack_info.pool.slots = 16; + for (int i = 0; i < dstack_info.pool.slots; ++i) { dstack_info.pool.action[i].shader.table = calloc( - config->default_shader_per_action, + 4, sizeof(*dstack_info.pool.action[i].shader.table) ); - dstack_info.pool.action[i].shader.number = - config->default_shader_per_action; + dstack_info.pool.action[i].shader.number = 4; dstack_info.pool.action[i].shader.idx = -1; } @@ -138,7 +139,7 @@ did_t dstack_add_action( /* dstack_render(): render a frame */ void dstack_render(void) { - struct dshader_surface surface; + dsurface_t surface; struct dstack_action *action; action = dstack_info.pool.action; diff --git a/src/modules/display/text/dfont.c b/src/modules/display/font/information.c similarity index 52% rename from src/modules/display/text/dfont.c rename to src/modules/display/font/information.c index 13c7490..f3900a7 100644 --- a/src/modules/display/text/dfont.c +++ b/src/modules/display/font/information.c @@ -1,13 +1,7 @@ #include -#include -#include - -//--- -// Internal -//--- /* dfont_utf8_next(): Read the next UTF-8 code point of a string */ -static uint32_t dfont_utf8_next(uint8_t const **str_pointer) +uint32_t dfont_utf8_next(uint8_t const **str_pointer) { uint8_t const *str = *str_pointer; uint8_t lead = *str++; @@ -76,128 +70,6 @@ int dfont_glyph_index(font_t const *f, uint32_t code_point) return code_point; } -/* dfont_char_render() : */ -void dfont_char_render( - struct dshader_surface *surface, - int glyph_idx, - uint32_t *arg -) { - uint32_t glyph_bitmap; - uint32_t glyph_shift; - int glyph_width; - int glyph_size; - font_t *font; - int counter; - int sx; - int x; - int y; - - x = arg[0]; - y = arg[1]; - - /* generate font index / shift information */ - font = dfont_get(); - if (font->shape.prop == 1) { - glyph_width = font->glyph.prop[glyph_idx].width; - glyph_shift = font->glyph.prop[glyph_idx].shift; - glyph_idx = font->glyph.prop[glyph_idx].index; - glyph_size = glyph_width * font->glyph.height; - } else { - glyph_width = font->glyph.mono.width; - glyph_size = font->glyph.mono.storage_size; - glyph_shift = glyph_size * glyph_idx; - glyph_idx = glyph_shift >> 8; - glyph_shift = glyph_shift & 0xff; - } - - /* drawing algo */ - //TODO: cache surface data (limit read/write) - sx = x; - counter = 0; - glyph_shift = 0x80000000 >> glyph_shift; - glyph_bitmap = font->glyph.data[glyph_idx]; - for (int i = 0; i < glyph_size; ++i) - { - if (glyph_bitmap & glyph_shift) { - dpixel_render(surface, x, y, arg[4]); - } else { - dpixel_render(surface, x, y, arg[5]); - } - - /* update font bitmap index / shift */ - glyph_shift >>= 1; - if (glyph_shift == 0x00000000) { - glyph_shift = 0x80000000; - glyph_bitmap = font->glyph.data[++glyph_idx]; - } - - /* update bitmap position */ - x += 1; - counter += 1; - if (counter >= glyph_width) { - counter = 0; - x = sx; - y += 1; - } - } -} - -//--- -// Kernel-level API -//--- - -/* dfont_render() : draw caracter in surface */ -void dfont_text_render(struct dshader_surface *surface, uint32_t *arg) -{ - uint32_t code_point; - uint8_t const * str; - font_t *font; - int glyph_idx; - int glyph_width; - int counter; - int sx; - int sy; - - /* check culling */ - if (((int)arg[3] < surface->y1 && (int)arg[1] > surface->y2) - || ((int)arg[2] < surface->x1 && (int)arg[0] > surface->x2)) { - return; - } - - /* draw algo (update me) */ - sx = arg[0]; - sy = arg[1]; - counter = -1; - font = dfont_get(); - str = (void*)(uintptr_t)arg[6]; - while (++counter < (int)arg[7]) - { - code_point = dfont_utf8_next(&str); - if (code_point == '\n') { - arg[1] += font->glyph.height; - arg[0] = sx; - continue; - } - - glyph_idx = dfont_glyph_index(font, code_point); - glyph_width = font->glyph.mono.width; - if (font->shape.prop == 1) - glyph_width = font->glyph.prop[glyph_idx].width; - - dfont_char_render(surface, glyph_idx, arg); - - arg[0] += glyph_width + font->char_spacing; - - } - arg[1] = sy; - arg[0] = sx; -} - -//--- -// Public API -//--- - - /* dfont_get() : get the current font */ font_t *dfont_get(void) { @@ -205,7 +77,7 @@ font_t *dfont_get(void) return &font8x9; } -/* dfont_geometry() : get the char geometry */ +/* dfont_text_geometry() : get the rendered text geometry with a given font */ int dfont_text_geometry( font_t *font, char const * const str_char, diff --git a/src/modules/display/font/render.c b/src/modules/display/font/render.c new file mode 100644 index 0000000..52b76b1 --- /dev/null +++ b/src/modules/display/font/render.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include + +//--- +// Kernel-level render API +//--- + +/* dfont_char_render() : */ +void dfont_char_render( + dsurface_t *surface, + int glyph_idx, + uint32_t *arg +) { + uint32_t glyph_bitmap; + uint32_t glyph_shift; + int glyph_width; + int glyph_size; + font_t *font; + int counter; + int sx; + int x; + int y; + + x = arg[0]; + y = arg[1]; + + /* generate font index / shift information */ + font = dfont_get(); + if (font->shape.prop == 1) { + glyph_width = font->glyph.prop[glyph_idx].width; + glyph_shift = font->glyph.prop[glyph_idx].shift; + glyph_idx = font->glyph.prop[glyph_idx].index; + glyph_size = glyph_width * font->glyph.height; + } else { + glyph_width = font->glyph.mono.width; + glyph_size = font->glyph.mono.storage_size; + glyph_shift = glyph_size * glyph_idx; + glyph_idx = glyph_shift >> 8; + glyph_shift = glyph_shift & 0xff; + } + + /* drawing algo */ + //TODO: cache surface data (limit read/write) + sx = x; + counter = 0; + glyph_shift = 0x80000000 >> glyph_shift; + glyph_bitmap = font->glyph.data[glyph_idx]; + for (int i = 0; i < glyph_size; ++i) + { + if (glyph_bitmap & glyph_shift) { + dpixel_render(surface, x, y, arg[4]); + } else { + dpixel_render(surface, x, y, arg[5]); + } + + /* update font bitmap index / shift */ + glyph_shift >>= 1; + if (glyph_shift == 0x00000000) { + glyph_shift = 0x80000000; + glyph_bitmap = font->glyph.data[++glyph_idx]; + } + + /* update bitmap position */ + x += 1; + counter += 1; + if (counter >= glyph_width) { + counter = 0; + x = sx; + y += 1; + } + } +} + +//--- +// Dstack API +//--- + +/* dfont_char_dstack() : dstack wrapper */ +void dfont_char_dstack(dsurface_t *surface, uint32_t *arg) +{ + font_t *font = dfont_get(); + uint32_t buff[6] = { + arg[1], arg[2], 0, 0, arg[3], arg[4] + }; + + dfont_char_render(surface, dfont_glyph_index(font, arg[0]), buff); +} + +//--- +// User-level API +//--- + +/* dfont_char() : display one char */ +void dfont_char(uint32_t n, int x, int y, int fg, int bg) +{ + dstack_add_action( + &DSTACK_CALL( + &dfont_char_dstack, + n, + x, y, + fg, bg + ), + NULL, + NULL + ); +} diff --git a/src/modules/display/image/render.c b/src/modules/display/image/render.c index 330a1fe..f1d382d 100644 --- a/src/modules/display/image/render.c +++ b/src/modules/display/image/render.c @@ -134,7 +134,7 @@ void dsubimage_render( width = surface->width - vxs; if ((size_t)(vys + height) > surface->height) height = surface->height - vys; - vram = surface->frag; + vram = surface->vram; /* prepare box request */ diff --git a/src/modules/display/text/dascii.c b/src/modules/display/text/dascii.c deleted file mode 100644 index 5e40c47..0000000 --- a/src/modules/display/text/dascii.c +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include - -#include - -//--- -// Kernel-level API -//--- - -void dascii_dstack_render(struct dshader_surface *surface, uint32_t *arg) -{ - font_t *font = dfont_get(); - uint32_t buff[6] = { - arg[1], arg[2], 0, 0, arg[3], arg[4] - }; - - dfont_char_render(surface, dfont_glyph_index(font, arg[0]), buff); -} - -//--- -// User-level API -//--- - -/* dascii() : display one char */ -void dascii(char n, int x, int y, int fg, int bg) -{ - dstack_add_action( - &DSTACK_CALL( - &dascii_dstack_render, - n, - x, y, - fg, bg - ), - NULL, - NULL - ); -} diff --git a/src/modules/display/text/information.c b/src/modules/display/text/information.c new file mode 100644 index 0000000..98efddb --- /dev/null +++ b/src/modules/display/text/information.c @@ -0,0 +1,8 @@ +#include +#include + +/* dtext_geometry() : get the rendered text geometry with the current font */ +int dtext_geometry(char const * const str_char, int *s, size_t *w, size_t *h) +{ + return dfont_text_geometry(NULL, str_char, s, w, h); +} diff --git a/src/modules/display/text/dtext.c b/src/modules/display/text/render.c similarity index 76% rename from src/modules/display/text/dtext.c rename to src/modules/display/text/render.c index 727ac07..de283fc 100644 --- a/src/modules/display/text/dtext.c +++ b/src/modules/display/text/render.c @@ -1,9 +1,7 @@ -#include -#include -#include +#include #include -#include #include +#include #include #include @@ -97,9 +95,59 @@ static char *dtext_info_register(char const * const str) } //--- -// Public API +// Dstack API //--- +/* dfont_render() : draw caracter in surface */ +void dtext_dstack(dsurface_t *surface, uint32_t *arg) +{ + uint32_t code_point; + uint8_t const * str; + font_t *font; + int glyph_idx; + int glyph_width; + int counter; + int sx; + int sy; + + /* check culling */ + if (((int)arg[3] < surface->y1 && (int)arg[1] > surface->y2) + || ((int)arg[2] < surface->x1 && (int)arg[0] > surface->x2)) { + return; + } + + /* draw algo (update me) */ + sx = arg[0]; + sy = arg[1]; + counter = -1; + font = dfont_get(); + str = (void*)(uintptr_t)arg[6]; + while (++counter < (int)arg[7]) + { + code_point = dfont_utf8_next(&str); + if (code_point == '\n') { + arg[1] += font->glyph.height; + arg[0] = sx; + continue; + } + + glyph_idx = dfont_glyph_index(font, code_point); + glyph_width = font->glyph.mono.width; + if (font->shape.prop == 1) + glyph_width = font->glyph.prop[glyph_idx].width; + + dfont_char_render(surface, glyph_idx, arg); + + arg[0] += glyph_width + font->char_spacing; + + } + arg[1] = sy; + arg[0] = sx; +} + +//--- +// Public API +//--- /* dtext_opt(): Display a string of text */ did_t dtext_opt( @@ -113,7 +161,7 @@ did_t dtext_opt( void *real_str; /* get text geometry and handle obvious culling */ - if (dfont_text_geometry(NULL, str, &size, &width, &height) != 0) + if (dtext_geometry(str, &size, &width, &height) != 0) return (-1); if (x >= (int)dwidth() || y >= (int)dheight() @@ -134,7 +182,7 @@ did_t dtext_opt( /* request draw call */ return dstack_add_action( &DSTACK_CALL( - &dfont_text_render, + &dtext_dstack, x, y, x + width, y + height, fg, bg, (uint32_t)(uintptr_t)real_str, size,