VxKernel 0.6.0-11 : Update text/font architecture
@update <> board/fxcg50.ld | add on-chip IL memory information | add ".vhex.ilram" section <> board/initialize | relocalize IL memory code <> include/vhex/display && src/modules/display | update color information | use only "dsurface_t" type | isolate the dsurface_t types | isolate interface structure information | isolate shader structure information | remove dstack configuration structure | remove draw/frag information and use only one VRAM information <> include/vhex/display/font | isolate structure-oriented information in <vhex/display/font/types.h> | isolate render API information in <vhex/display/font/render.h> | isolate information API in <vhex/display/font/information.h> <> include/vhex/display/text | isolate render API information in <vhex/display/text/render.h> | isolate information API in <vhex/display/text/information.h> <> make/Makefile | enable DSP instructions <> src/drivers/screen/r61524 | try to use the DSP instruction for the sending loop, but seems to be a bit too slow instead of the "full-CPU" version generated by GCC
This commit is contained in:
parent
1ebab24090
commit
b2fc0db544
|
@ -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*)
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,91 +1,2 @@
|
|||
#ifndef __VHEX_DISPLAY_FONT__
|
||||
# define __VHEX_DISPLAY_FONT__
|
||||
|
||||
#include <vhex/defs/types.h>
|
||||
#include <vhex/defs/attributes.h>
|
||||
#include <vhex/display/shader.h>
|
||||
|
||||
/* 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 <vhex/display/font/information.h>
|
||||
#include <vhex/display/font/render.h>
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef __VHEX_DISPLAY_FONT_INFORMATION__
|
||||
# define __VHEX_DISPLAY_FONT_INFORMATION__
|
||||
|
||||
#include <vhex/display/font/types.h>
|
||||
|
||||
/* 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__ */
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef __VHEX_DISPLAY_FONT_RENDER__
|
||||
# define __VHEX_DISPLAY_FONT_RENDER__
|
||||
|
||||
#include <vhex/display/types.h>
|
||||
|
||||
//---
|
||||
// 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__ */
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef __VHEX_DISPLAY_FONT_TYPES__
|
||||
# define __VHEX_DISPLAY_FONT_TYPES__
|
||||
|
||||
#include <vhex/defs/types.h>
|
||||
#include <vhex/defs/attributes.h>
|
||||
|
||||
/* 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__ */
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef __VHEX_DISPLAY_INTERFACE__
|
||||
# define __VHEX_DISPLAY_INTERFACE__
|
||||
|
||||
#include <vhex/display/types.h>
|
||||
|
||||
/* 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__ */
|
|
@ -1,33 +1,18 @@
|
|||
#ifndef __VHEX_DISPLAY_SHADER__
|
||||
# define __VHEX_DISPLAY_SHADER__
|
||||
|
||||
#include <vhex/defs/attributes.h>
|
||||
#include <vhex/defs/types.h>
|
||||
|
||||
/* 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 <vhex/display/types.h>
|
||||
|
||||
/* 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 }
|
||||
|
|
|
@ -4,12 +4,10 @@
|
|||
#include <vhex/display/shader.h>
|
||||
#include <vhex/display/types.h>
|
||||
|
||||
|
||||
/* 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(
|
||||
|
|
|
@ -1,46 +1,2 @@
|
|||
#ifndef __VHEX_DISPLAY_TEXT__
|
||||
# define __VHEX_DISPLAY_TEXT__
|
||||
|
||||
#include <vhex/defs/types.h>
|
||||
#include <vhex/display/types.h>
|
||||
|
||||
/* 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 <vhex/display/text/information.h>
|
||||
#include <vhex/display/text/render.h>
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef __VHEX_DISPLAY_TEXT_INFORMATION__
|
||||
# define __VHEX_DISPLAY_TEXT_INFORMATION__
|
||||
|
||||
#include <vhex/defs/types.h>
|
||||
|
||||
/* 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__ */
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef __VHEX_DISPLAY_TEXT_RENDER__
|
||||
# define __VHEX_DISPLAY_TEXT_RENDER__
|
||||
|
||||
#include <vhex/defs/types.h>
|
||||
#include <vhex/display/types.h>
|
||||
|
||||
/* 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__ */
|
|
@ -1,7 +1,21 @@
|
|||
#ifndef __VHEX_DISPLAY_TYPES__
|
||||
# define __VHEX_DISPLAY_TYPES__
|
||||
|
||||
#include <vhex/defs/types.h>
|
||||
|
||||
/* 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__ */
|
||||
|
|
|
@ -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: //')
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,25 +1,14 @@
|
|||
#include <vhex/defs/types.h>
|
||||
#include <vhex/driver.h>
|
||||
#include <vhex/driver/screen/r61524.h>
|
||||
#include <vhex/display/stack.h>
|
||||
#include <vhex/display/interface.h>
|
||||
|
||||
//---
|
||||
// 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);
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <vhex/display/stack.h>
|
||||
#include <vhex/display/shader.h>
|
||||
#include <vhex/display/interface.h>
|
||||
#include <vhex/driver.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -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;
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
#include <vhex/display/font.h>
|
||||
#include <vhex/display/draw/pixel.h>
|
||||
#include <vhex/display/color.h>
|
||||
|
||||
//---
|
||||
// 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,
|
|
@ -0,0 +1,108 @@
|
|||
#include <vhex/display/font.h>
|
||||
#include <vhex/display/draw/pixel.h>
|
||||
#include <vhex/display/color.h>
|
||||
#include <vhex/display/stack.h>
|
||||
|
||||
//---
|
||||
// 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
|
||||
);
|
||||
}
|
|
@ -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 */
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
#include <vhex/display.h>
|
||||
#include <vhex/defs/types.h>
|
||||
|
||||
#include <vhex/display/font.h>
|
||||
|
||||
//---
|
||||
// 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
|
||||
);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#include <vhex/display/types.h>
|
||||
#include <vhex/display/font/information.h>
|
||||
|
||||
/* 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);
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
#include <vhex/defs/types.h>
|
||||
#include <vhex/display/text.h>
|
||||
#include <vhex/display/shader.h>
|
||||
#include <vhex/display/types.h>
|
||||
#include <vhex/display/stack.h>
|
||||
#include <vhex/display/color.h>
|
||||
#include <vhex/display/font.h>
|
||||
#include <vhex/display/text.h>
|
||||
#include <vhex/display.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
@ -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,
|
Loading…
Reference in New Issue