mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-29 13:03:36 +01:00
render: refactor to share functions, and basic text on fxcg50
This commit is contained in:
parent
81baa4c26a
commit
0055199359
21 changed files with 759 additions and 522 deletions
60
include/display/common.h
Normal file
60
include/display/common.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
//---
|
||||
// display:common - Internal definitions for common display functions
|
||||
//---
|
||||
|
||||
#ifndef DISPLAY_COMMON
|
||||
#define DISPLAY_COMMON
|
||||
|
||||
#include <gint/display.h>
|
||||
|
||||
/* dhline() - optimized drawing of a horizontal line
|
||||
@x1 @x2 @y Coordinates of endpoints of line (both included)
|
||||
@color Any color suitable for dline() */
|
||||
void dhline(int x1, int x2, int y, color_t color);
|
||||
|
||||
/* dvline() - optimized drawing of a vertical line
|
||||
@y1 @y2 @x Coordinates of endpoints of line (both included)
|
||||
@color Any color suitable for dline() */
|
||||
void dvline(int y1, int y2, int x, color_t color);
|
||||
|
||||
//---
|
||||
// Font rendering (topti)
|
||||
//---
|
||||
|
||||
/* Current font */
|
||||
extern font_t const * topti_font;
|
||||
/* Default font */
|
||||
extern font_t const * gint_default_font;
|
||||
|
||||
/* enum topti_charset: Available character set decoders
|
||||
Each charset is associated with a reduced character table. */
|
||||
enum topti_charset
|
||||
{
|
||||
charset_numeric = 0, /* 10 elements: 0..9 */
|
||||
charset_upper = 1, /* 26 elements: A..Z */
|
||||
charset_alpha = 2, /* 52 elements: A..Z, a..z */
|
||||
charset_alnum = 3, /* 62 elements: A..Z, a..z, 0..9 */
|
||||
charset_print = 4, /* 95 elements: 0x20..0x7e */
|
||||
charset_ascii = 5, /* 128 elements: 0x00..0x7f */
|
||||
};
|
||||
|
||||
/* charset_size(): Number of elements in each character set
|
||||
@set Character set ID
|
||||
Returns the expected number of glyphs, -1 if charset ID is invalid. */
|
||||
int charset_size(enum topti_charset set);
|
||||
|
||||
/* charset_decode(): Translate ASCII into reduced character sets
|
||||
Returns the position of [c] in the character table of the given charset, or
|
||||
-1 if [c] is not part of that set.
|
||||
@set Any character set
|
||||
@c Character to decode */
|
||||
int charset_decode(enum topti_charset set, uint c);
|
||||
|
||||
/* topti_offset(): Use a font index to find the location of a glyph
|
||||
@f Font object
|
||||
@glyph Glyph number obtained by charset_decode(), must be nonnegative.
|
||||
Returns the offset the this glyph's data in the font's data array. When
|
||||
using a proportional font, the size array is not heeded for. */
|
||||
int topti_offset(font_t const *f, uint glyph);
|
||||
|
||||
#endif /* DISPLAY_COMMON */
|
|
@ -24,9 +24,6 @@
|
|||
@masks Stores the result of the function (four uint32_t values) */
|
||||
void masks(int x1, int x2, uint32_t *masks);
|
||||
|
||||
/* Font currently configured for text rendering */
|
||||
extern font_t const * topti_font;
|
||||
|
||||
/* bopti_render_clip() - render a bopti image with clipping
|
||||
@x @y Location of the top-left corner
|
||||
@img Image encoded by [fxconv]
|
||||
|
|
|
@ -22,11 +22,19 @@
|
|||
|
||||
In this module, colors are in the 16-bit R5G6B5 format, as it is the format
|
||||
used by the display controller. */
|
||||
|
||||
#ifdef GINT_NEED_VRAM
|
||||
extern uint16_t *vram;
|
||||
#endif
|
||||
|
||||
/* Provide a platform-agnostic definition of color_t.
|
||||
Some functions also support transparency, in which case they take an [int]
|
||||
as argument and recognize negative values as transparent. */
|
||||
typedef uint16_t color_t;
|
||||
|
||||
enum {
|
||||
color_none = -1,
|
||||
};
|
||||
|
||||
//---
|
||||
// Video RAM management
|
||||
//---
|
||||
|
@ -62,73 +70,6 @@ extern uint16_t *vram;
|
|||
@secondary Additional VRAM area, enables triple buffering if non-NULL */
|
||||
void dvram(uint16_t *main, uint16_t *secondary);
|
||||
|
||||
/* dupdate() - push the video RAM to the display driver
|
||||
This function makes the contents of the VRAM visible on the screen. It is
|
||||
the direct equivalent of Bdisp_PutDisp_DD().
|
||||
|
||||
If triple buffering is enabled (this is the default, and disabled only if
|
||||
dvram() is used to setup double buffering instead), it also swaps buffers.
|
||||
Also waits for the previous dupdate() call to finish before executing. */
|
||||
void dupdate(void);
|
||||
|
||||
//---
|
||||
// Area rendering functions
|
||||
//---
|
||||
|
||||
/* dclear() - fill the screen with a single color
|
||||
This function clears the screen by painting all the pixels in a single,
|
||||
opaque color.
|
||||
|
||||
@color Any R5G6B5 color */
|
||||
void dclear(uint16_t color);
|
||||
|
||||
/* drect() - fill a rectangle of the screen
|
||||
This functions paints a rectangle in an opaque color. The endpoints (x1 y1)
|
||||
and (x2 y2) are included in the rectangle.
|
||||
|
||||
@x1 @y1 @x2 @y2 Bounding rectangle (drawn area).
|
||||
@color Any R5G6B5 color */
|
||||
void drect(int x1, int y1, int x2, int y2, uint16_t color);
|
||||
|
||||
//---
|
||||
// Point drawing functions
|
||||
//---
|
||||
|
||||
/* dpixel() - change a pixel's color
|
||||
Paints the selected pixel with an opaque color. Setting pixels individually
|
||||
is a slow method for rendering. Other functions that draw lines, rectangles,
|
||||
images or text will take advantage of possible optimizations to make the
|
||||
rendering faster: check them out first.
|
||||
|
||||
@x @y Coordinates of the pixel to repaint
|
||||
@color Any R5G6B5 color */
|
||||
void dpixel(int x, int y, uint16_t color);
|
||||
|
||||
/* dline() - render a straight line
|
||||
This function draws a line using a Bresenham-style algorithm. Please note
|
||||
that the affected pixels may not be exactly the same when using dline() and
|
||||
Bdisp algorithms.
|
||||
|
||||
dline() has optimization facilities for horizontal and vertical lines. The
|
||||
first kind is about twice as fast, while the second avoids some computation
|
||||
(the optimization gain is not as significant as on fx9860g). dline() is not
|
||||
able to clip the line without calculating all the pixels, so drawing a line
|
||||
from (-1e6,0) to (1e6,395) will work, but will be veeery slow.
|
||||
|
||||
@x1 @y1 @x2 @y2 End points of the line (both included).
|
||||
@color Any R5G6B5 color */
|
||||
void dline(int x1, int y1, int x2, int y2, uint16_t color);
|
||||
|
||||
//---
|
||||
// Image rendering (bopti)
|
||||
//---
|
||||
|
||||
//---
|
||||
// Text rendering (topti)
|
||||
//---
|
||||
|
||||
typedef void font_t;
|
||||
|
||||
#endif /* FXCG50 */
|
||||
|
||||
#endif /* GINT_DISPLAY_CG */
|
||||
|
|
|
@ -31,7 +31,7 @@ extern uint32_t *vram;
|
|||
|
||||
OPERATORS (combine with existing pixels)
|
||||
none - leaves unchanged
|
||||
reverse - inverts white <-> black, light <-> dark
|
||||
invert - inverts white <-> black, light <-> dark
|
||||
lighten - shifts black -> dark -> light -> white -> white
|
||||
darken - shifts white -> light -> dark -> black -> black
|
||||
|
||||
|
@ -47,7 +47,7 @@ typedef enum
|
|||
|
||||
/* Monochrome operators */
|
||||
color_none = 4,
|
||||
color_reverse = 5,
|
||||
color_invert = 5,
|
||||
|
||||
/* Gray operators */
|
||||
color_lighten = 6,
|
||||
|
@ -55,59 +55,6 @@ typedef enum
|
|||
|
||||
} color_t;
|
||||
|
||||
//---
|
||||
// Area drawing functions
|
||||
//---
|
||||
|
||||
/* dupdate() - push the video RAM to the display driver
|
||||
This function makes the contents of the VRAM visible on the screen. It is
|
||||
the direct equivalent of Bdisp_PutDisp_DD(). */
|
||||
void dupdate(void);
|
||||
|
||||
/* dclear() - fill the screen with a single color
|
||||
This function clears the screen by replacing all the pixels with a single
|
||||
color. This function is optimized for opaque drawing. If you wish to apply
|
||||
operators, use drect().
|
||||
|
||||
@color Allowed colors: white, black */
|
||||
void dclear(color_t color);
|
||||
|
||||
/* drect() - fill a rectangle of the screen
|
||||
This functions applies a color or an operator to a rectangle defined by two
|
||||
points (x1 y1) and (x2 y2). Both are included in the rectangle.
|
||||
|
||||
@x1 @y1 @x2 @y2 Bounding rectangle (drawn area).
|
||||
@color Allowed colors: white, black, none, reverse */
|
||||
void drect(int x1, int y1, int x2, int y2, color_t color);
|
||||
|
||||
//---
|
||||
// Point drawing functions
|
||||
//---
|
||||
|
||||
/* dpixel() - change a pixel's color
|
||||
If the requested color is an operator, the result will depend on the current
|
||||
color of the pixel. Setting single pixels is the slowest method to produce a
|
||||
graphical result: all other functions for rendering lines, rectangles,
|
||||
images or text use highly-optimized methods, so check them out first if you
|
||||
care about performance.
|
||||
|
||||
@x @y Coordinates of the pixel to repaint
|
||||
@color Allowed colors: white, black, none, reverse */
|
||||
void dpixel(int x, int y, color_t color);
|
||||
|
||||
/* dline() - render a straight line
|
||||
This function draws a line using a Bresenham-style algorithm. Please note
|
||||
that the affected pixels may not be exactly the same when using dline() and
|
||||
Bdisp_DrawLineVRAM().
|
||||
|
||||
dline() has optimization facilities for horizontal and vertical lines, but
|
||||
it does not detect if your line doesn't fit in the screen. So drawing from
|
||||
(-1e6,0) to (1e6,63) will work, but will be veeery slow.
|
||||
|
||||
@x1 @y1 @x2 @y2 End points of the line (both included).
|
||||
@color Allowed colors: white, black, none, reverse */
|
||||
void dline(int x1, int y1, int x2, int y2, color_t color);
|
||||
|
||||
//---
|
||||
// Image rendering (bopti)
|
||||
//---
|
||||
|
@ -161,99 +108,6 @@ enum {
|
|||
void dimage_opt(int x, int y, image_t const *image, int left, int top,
|
||||
int width, int height, int flags);
|
||||
|
||||
//---
|
||||
// Text rendering (topti)
|
||||
//---
|
||||
|
||||
/* font_t - font data encoded for topti */
|
||||
typedef struct
|
||||
{
|
||||
/* Length of font name (not NUL-terminated) */
|
||||
uint title :5;
|
||||
/* Font shape flags */
|
||||
uint bold :1;
|
||||
uint italic :1;
|
||||
uint serif :1;
|
||||
uint mono :1;
|
||||
/* Whether data is variable-length (proportional font) */
|
||||
uint prop :1;
|
||||
/* Reserved for future use */
|
||||
uint :2;
|
||||
/* Implemented charcter set */
|
||||
uint charset :4;
|
||||
/* Line height */
|
||||
uint8_t line_height;
|
||||
/* Storage height */
|
||||
uint8_t data_height;
|
||||
|
||||
/* The rest of the data depends on whether the font is proportional */
|
||||
union {
|
||||
/* For monospaced fonts */
|
||||
struct {
|
||||
/* Width of glyphs */
|
||||
uint16_t width;
|
||||
/* Storage size, in longwords, of each glyph */
|
||||
uint16_t storage_size;
|
||||
/* Raw glyph data */
|
||||
uint32_t data[];
|
||||
};
|
||||
/* For proportional fonts */
|
||||
struct {
|
||||
/* Storage index to find glyphs quickly */
|
||||
uint16_t index[16];
|
||||
/* Size array (padded to 4 bytes), 1 byte per entry,
|
||||
followed by glyph data */
|
||||
uint8_t sized_data[];
|
||||
};
|
||||
};
|
||||
|
||||
/* The font name is stored after the data. The size is the length set
|
||||
in the [title] field, padded to 4 bytes with NULs. There might not
|
||||
be a NUL at the end. */
|
||||
|
||||
} GPACKED(4) font_t;
|
||||
|
||||
/* dfont() - set the default font for text rendering
|
||||
This font will be used by dtext() and sister functions. If font=NULL, gint's
|
||||
default 5*6 font is used.
|
||||
|
||||
@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
|
||||
default if no such font was set).
|
||||
|
||||
Due to the particular design of topti, this function takes advantage of the
|
||||
line structure of the VRAM to rendeer several characters at once. This is
|
||||
not a printf()-family function so [str] cannot contain formats like "%d"
|
||||
(they will be rendered directly) and cannot receive additional arguments.
|
||||
|
||||
@x @y Coordinates of top-left corner of the rendered string
|
||||
@str String to display
|
||||
@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 */
|
||||
|
||||
#endif /* GINT_DISPLAY_FX */
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
//---
|
||||
// gint:display - Drawing functions
|
||||
//
|
||||
// This module covers the drawing functions that are common to fx9860g and
|
||||
// fxcg50. Platform-specific definitions are found in <gint/display-fx.h>
|
||||
// and <gint/display-cg.h>.
|
||||
//---
|
||||
|
||||
#ifndef GINT_DISPLAY
|
||||
|
@ -7,8 +11,8 @@
|
|||
|
||||
#include <gint/defs/types.h>
|
||||
|
||||
/* As you would expect, display on fx9860g and display on fxcg50 are completely
|
||||
different worlds. As a consequence, so are the rendering functions ^^ */
|
||||
/* Platform-specific functions include VRAM management and the definition of
|
||||
the color_t type. */
|
||||
|
||||
#ifdef FX9860G
|
||||
#include <gint/display-fx.h>
|
||||
|
@ -18,26 +22,180 @@
|
|||
#include <gint/display-cg.h>
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* dinfo_t - summary of information provided by this module */
|
||||
/* TODO: dinfo() or similar */
|
||||
|
||||
//---
|
||||
// Video RAM management
|
||||
//---
|
||||
|
||||
/* dupdate() - push the video RAM to the display driver
|
||||
This function makes the contents of the VRAM visible on the screen. It is
|
||||
the direct equivalent of Bdisp_PutDisp_DD().
|
||||
|
||||
On fxcg50, if triple buffering is enabled (which is the default and disabled
|
||||
only by calling dvram()), it also swaps buffers. Due to the DMA being used,
|
||||
always waits for the previous call to dupdate() call() to finish. */
|
||||
void dupdate(void);
|
||||
|
||||
//---
|
||||
// Area rendering functions
|
||||
//---
|
||||
|
||||
/* dclear() - fill the screen with a single color
|
||||
This function clears the screen by painting all the pixels in a single
|
||||
color. It is optimized for opaque colors.
|
||||
|
||||
On fx9860g, use drect() if you need complex operators such as invert.
|
||||
|
||||
@color fx9860g: white, black
|
||||
fxcg50: Any R5G6B5 color */
|
||||
void dclear(color_t color);
|
||||
|
||||
/* drect() - fill a rectangle of the screen
|
||||
This functions applies a color or an operator to a rectangle defined by two
|
||||
points (x1 y1) and (x2 y2). Both are included in the rectangle.
|
||||
|
||||
@x1 @y1 @x2 @y2 Bounding rectangle (drawn area).
|
||||
@color fx9860g: white, black, none, invert
|
||||
fxcg50: Any R5G6B5 color */
|
||||
void drect(int x1, int y1, int x2, int y2, color_t color);
|
||||
|
||||
//---
|
||||
// Point drawing functions
|
||||
//---
|
||||
|
||||
/* dpixel() - change a pixel's color
|
||||
Paints the selected pixel with an opaque color. Setting pixels individually
|
||||
is a slow method for rendering. Other functions that draw lines, rectangles,
|
||||
images or text will take advantage of possible optimizations to make the
|
||||
rendering faster: check them out first.
|
||||
|
||||
On fx9860g, if an operator such as invert is used, the result will depend
|
||||
on the current color of the pixel.
|
||||
|
||||
@x @y Coordinates of the pixel to repaint
|
||||
@color fx9860g: white, black, none, invert
|
||||
fxcg50: Any R5G6B5 color */
|
||||
void dpixel(int x, int y, color_t color);
|
||||
|
||||
/* dline() - render a straight line
|
||||
This function draws a line using a Bresenham-style algorithm. Please note
|
||||
that dline() may not render lines exactly like Bdisp_DrawLineVRAM().
|
||||
|
||||
dline() has optimization facilities for horizontal and vertical lines. The
|
||||
speedup for horizontal lines is about x2 on fxcg50 and probably about x30
|
||||
on fx9860g. Vertical lines have a smaller speedup.
|
||||
|
||||
dline() is currently not able to clip arbitrary lines without calculating
|
||||
all the pixels, so drawing a line from (-1e6,0) to (1e6,395) will work but
|
||||
will be veeery slow.
|
||||
|
||||
@x1 @y1 @x2 @y2 End points of the line (both included).
|
||||
@color fx9860g: white, black, none, invert
|
||||
fxcg50: Any R5G6B5 color */
|
||||
void dline(int x1, int y1, int x2, int y2, color_t color);
|
||||
|
||||
//---
|
||||
// Text rendering (topti)
|
||||
//---
|
||||
|
||||
/* font_t - font data encoded for topti */
|
||||
typedef struct
|
||||
{
|
||||
/* Screen width, in pixels */
|
||||
int width;
|
||||
/* Screen height, in pixels */
|
||||
int height;
|
||||
/* Color depth (is 1 on fx9860g regardless of the gray engine) */
|
||||
int bpp;
|
||||
/* Current rendering font */
|
||||
font_t const * font;
|
||||
/* Length of font name (not necessarily NUL-terminated!) */
|
||||
uint title :5;
|
||||
/* Font shape flags */
|
||||
uint bold :1;
|
||||
uint italic :1;
|
||||
uint serif :1;
|
||||
uint mono :1;
|
||||
/* Whether data is variable-length (proportional font) */
|
||||
uint prop :1;
|
||||
/* Reserved for future use */
|
||||
uint :2;
|
||||
/* Implemented charcter set */
|
||||
uint charset :4;
|
||||
/* Line height */
|
||||
uint8_t line_height;
|
||||
/* Storage height */
|
||||
uint8_t data_height;
|
||||
|
||||
} dinfo_t;
|
||||
/* The rest of the data depends on whether the font is proportional */
|
||||
union {
|
||||
/* For monospaced fonts */
|
||||
struct {
|
||||
/* Width of glyphs */
|
||||
uint16_t width;
|
||||
/* Storage size, in longwords, of each glyph */
|
||||
uint16_t storage_size;
|
||||
/* Raw glyph data */
|
||||
uint32_t data[];
|
||||
};
|
||||
/* For proportional fonts */
|
||||
struct {
|
||||
/* Storage index to find glyphs quickly */
|
||||
uint16_t index[16];
|
||||
/* Size array (padded to 4 bytes), 1 byte per entry,
|
||||
followed by glyph data */
|
||||
uint8_t sized_data[];
|
||||
};
|
||||
};
|
||||
|
||||
/* dinfo() - retrieve information from the display module
|
||||
This function returns the value of most parameters of the display module.
|
||||
/* The font name is stored after the data. The size is the length set
|
||||
in the [title] field, padded to 4 bytes with NULs. There might not
|
||||
be a NUL at the end. */
|
||||
|
||||
@info Pointer to allocated dinfo_t structure, will be filled. */
|
||||
void dinfo(dinfo_t *info);
|
||||
#endif
|
||||
} GPACKED(4) font_t;
|
||||
|
||||
/* dfont() - set the default font for text rendering
|
||||
This font will be used by dtext() and sister functions. If [font = NULL],
|
||||
gint's default font is used.
|
||||
|
||||
On fx9860g, the default font is a 5x7 font very close to the system's.
|
||||
On fxcg50, the default font is an original 10x12 font.
|
||||
|
||||
@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 is different 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. If
|
||||
[w = NULL], this function returns in constant 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
|
||||
default if no such font was set).
|
||||
|
||||
On fx9860g, due to the particular design of topti, this function performs
|
||||
drastic rendering optimizations using the line structure of the VRAM and is
|
||||
able to render several characters at once.
|
||||
|
||||
This is not a printf()-family function so [str] cannot contain formats like
|
||||
"%d" and you cannot pass aditional arguments.
|
||||
|
||||
@x @y Coordinates of top-left corner of the rendered string
|
||||
@str String to display
|
||||
@fg Text color
|
||||
fx9860g: white, black, none, invert
|
||||
fxcg50: Any R5G6B6 color, or [color_none]
|
||||
@bg Background color
|
||||
fx9860g: white, black, none, invert
|
||||
fxcg50: Any R5G6B5 color, or [color_none] */
|
||||
void dtext(int x, int y, const char *str, int fg, int bg);
|
||||
|
||||
#endif /* GINT_DISPLAY */
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
//---
|
||||
// gint:core:syscalls - calls to CASIOWIN
|
||||
// gint:syscalls - calls to CASIOWIN
|
||||
//---
|
||||
|
||||
#ifndef GINT_CORE_SYSCALLS
|
||||
#define GINT_CORE_SYSCALLS
|
||||
#ifndef GINT_SYSCALLS
|
||||
#define GINT_SYSCALLS
|
||||
|
||||
/* __os_version(): Get OS version on the form MM.mm.iiii (10 bytes) */
|
||||
void __os_version(char *version);
|
||||
|
||||
#endif /* GINT_CORE_SYSCALLS */
|
||||
#endif /* GINT_SYSCALLS */
|
||||
|
|
|
@ -53,8 +53,9 @@ src := $(shell find ../src \
|
|||
src_obj := $(foreach s,$(src),$(call src2obj,$s))
|
||||
|
||||
# Files with special handling
|
||||
spe := ../src/font5x7.png
|
||||
spe_obj := version.o $(foreach s,$(spe),$(call src2obj,$s))
|
||||
spe-fx := ../src/font5x7.png
|
||||
spe-cg := ../src/font10x12.png
|
||||
spe_obj := version.o $(foreach s,$(spe-$(CONFIG.TARGET)),$(call src2obj,$s))
|
||||
|
||||
# All object files
|
||||
obj := $(src_obj) $(spe_obj)
|
||||
|
@ -107,14 +108,18 @@ $(call src2obj,../src/font5x7.png): ../src/font5x7.png
|
|||
@ mkdir -p $(dir $@)
|
||||
$(call cmd_m,fxconv,font5x7.png)$(conv) -f $< -o $@ name:gint_font5x7 \
|
||||
charset:ascii grid.size:5x7 grid.padding:1 grid.border:0
|
||||
$(call src2obj,../src/font10x12.png): ../src/font10x12.png
|
||||
@ mkdir -p $(dir $@)
|
||||
$(call cmd_m,fxconv,font10x12.png)$(conv) -f $< -o $@ name:gint_font10x12 \
|
||||
charset:print grid.size:10x12 grid.padding:0 grid.border:3
|
||||
|
||||
# Version symbol. ld generates a .stack section for unknown reasons; I remove
|
||||
# it in the linker script.
|
||||
version.o:
|
||||
version.o: ../.git/HEAD
|
||||
@ mkdir -p $(dir $@)
|
||||
@ echo "_GINT_VERSION = $(version_hash);" > $@.txt
|
||||
$(call cmd_b,ld,$@) $(ld) -r -R $@.txt -o $@
|
||||
.PHONY: version.o
|
||||
|
||||
#
|
||||
# Cleaning
|
||||
#
|
||||
|
|
BIN
src/font10x12.png
Normal file
BIN
src/font10x12.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
BIN
src/font5x7.png
BIN
src/font5x7.png
Binary file not shown.
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
@ -1,11 +1,9 @@
|
|||
#define GINT_NEED_VRAM
|
||||
#include <gint/defs/util.h>
|
||||
#include <gint/display.h>
|
||||
#include <gint/defs/util.h>
|
||||
|
||||
/* dhline() - optimized drawing of a horizontal line
|
||||
@x1 @x2 @y Coordinates of endpoints of line (both included)
|
||||
@color Any R5G6B5 color */
|
||||
static void dhline(int x1, int x2, int y, uint16_t color)
|
||||
/* dhline() - optimized drawing of a horizontal line */
|
||||
void dhline(int x1, int x2, int y, uint16_t color)
|
||||
{
|
||||
/* Order and bounds */
|
||||
if((uint)y >= 224) return;
|
||||
|
@ -32,10 +30,8 @@ static void dhline(int x1, int x2, int y, uint16_t color)
|
|||
while(end > start) *--end = op;
|
||||
}
|
||||
|
||||
/* dvline() - optimized drawing of a vertical line
|
||||
@y1 @y2 @x Coordinates of endpoints of line (both included)
|
||||
@color Any R5G6B5 color */
|
||||
static void dvline(int y1, int y2, int x, uint16_t color)
|
||||
/* dvline() - optimized drawing of a vertical line */
|
||||
void dvline(int y1, int y2, int x, uint16_t color)
|
||||
{
|
||||
/* Order and bounds */
|
||||
if((uint)x >= 395) return;
|
||||
|
@ -49,59 +45,3 @@ static void dvline(int y1, int y2, int x, uint16_t color)
|
|||
while(height--) *v = color, v += 396;
|
||||
}
|
||||
|
||||
/* dline() - Bresenham line drawing algorithm
|
||||
Remotely adapted from MonochromeLib code by Pierre "PerriotLL" Le Gall.
|
||||
Relies on dhline() and dvline() for optimized situations.
|
||||
@x1 @y1 @x2 @y2 Coordinates of endpoints of line (included)
|
||||
@color Any R5G6B5 color */
|
||||
void dline(int x1, int y1, int x2, int y2, uint16_t color)
|
||||
{
|
||||
/* Possible optimizations */
|
||||
if(y1 == y2)
|
||||
{
|
||||
dhline(x1, x2, y1, color);
|
||||
return;
|
||||
}
|
||||
if(x1 == x2)
|
||||
{
|
||||
dvline(y1, y2, x1, color);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Brensenham line drawing algorithm */
|
||||
|
||||
int i, x = x1, y = y1, cumul;
|
||||
int dx = x2 - x1, dy = y2 - y1;
|
||||
int sx = sgn(dx), sy = sgn(dy);
|
||||
|
||||
dx = abs(dx), dy = abs(dy);
|
||||
|
||||
dpixel(x1, y1, color);
|
||||
|
||||
if(dx >= dy)
|
||||
{
|
||||
/* Start with a non-zero cumul to even the overdue between the
|
||||
two ends of the line (for more regularity) */
|
||||
cumul = dx >> 1;
|
||||
for(i = 1; i < dx; i++)
|
||||
{
|
||||
x += sx;
|
||||
cumul += dy;
|
||||
if(cumul > dx) cumul -= dx, y += sy;
|
||||
dpixel(x, y, color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cumul = dy >> 1;
|
||||
for(i = 1; i < dy; i++)
|
||||
{
|
||||
y += sy;
|
||||
cumul += dx;
|
||||
if(cumul > dy) cumul -= dy, x += sx;
|
||||
dpixel(x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
dpixel(x2, y2, color);
|
||||
}
|
||||
|
|
|
@ -21,39 +21,21 @@ void drect(int x1, int y1, int x2, int y2, uint16_t color)
|
|||
uint16_t *base = vram + 396 * y1;
|
||||
int height = y2 - y1 + 1;
|
||||
|
||||
/* Do borders first if there are at an odd position */
|
||||
|
||||
if(x1 & 1)
|
||||
{
|
||||
uint16_t *v = base;
|
||||
for(int h = height; h; h--)
|
||||
{
|
||||
v[x1] = color;
|
||||
v += 396;
|
||||
}
|
||||
x1++;
|
||||
}
|
||||
|
||||
if(x2 & 1) x2++;
|
||||
else
|
||||
{
|
||||
uint16_t *v = base;
|
||||
for(int h = height; h; h--)
|
||||
{
|
||||
v[x2] = color;
|
||||
v += 396;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now copy everything that's left as longwords */
|
||||
|
||||
uint32_t *v = (void *)(base + x1);
|
||||
int ax1 = x1 + (x1 & 1);
|
||||
int ax2 = (x2 + 1) & ~1;
|
||||
|
||||
uint32_t *v = (void *)(base + ax1);
|
||||
uint32_t op = (color << 16) | color;
|
||||
int width = (x2 - x1) >> 1;
|
||||
int width = (ax2 - ax1) >> 1;
|
||||
|
||||
for(int h = height; h; h--)
|
||||
{
|
||||
base[x1] = color;
|
||||
base[x2] = color;
|
||||
for(int w = 0; w < width; w++) v[w] = op;
|
||||
v += 198;
|
||||
base += 396;
|
||||
}
|
||||
}
|
||||
|
|
29
src/render-cg/topti-asm.h
Normal file
29
src/render-cg/topti-asm.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
//---
|
||||
// gint:render-cg:topti-asm - Assembler drawing routines for topti
|
||||
//---
|
||||
|
||||
#ifndef GINT_RENDERCG_TOPTIASM
|
||||
#define GINT_RENDERCG_TOPTIASM
|
||||
|
||||
/* Text rendering functions
|
||||
|
||||
@vram Pointer to VRAM, offset for subglyph position
|
||||
@data Glyph data, offset for subglyph position
|
||||
@color topti_glyph_fg: Foreground color
|
||||
topti_glyph_bg: Background color
|
||||
topti_glyph_fg_bg: (fg << 16) | bg
|
||||
@height Subglyph height
|
||||
@width Sublgyph width
|
||||
@stride Storage width of subglyph - width
|
||||
@index Starting index in data, ie. top * storage width + left */
|
||||
typedef void asm_text_t(uint16_t *vram, uint32_t const * data, uint32_t color,
|
||||
int height, int width, int stride, int index);
|
||||
|
||||
/* Opaque foreground, transparent background */
|
||||
extern asm_text_t topti_glyph_fg;
|
||||
/* Transparent foreground, opaque background */
|
||||
extern asm_text_t topti_glyph_bg;
|
||||
/* Opaque foreground, opaque background */
|
||||
extern asm_text_t topti_glyph_fg_bg;
|
||||
|
||||
#endif /* GINT_RENDERFX_TOPTIASM */
|
202
src/render-cg/topti-asm.s
Normal file
202
src/render-cg/topti-asm.s
Normal file
|
@ -0,0 +1,202 @@
|
|||
.global _topti_glyph_fg_bg
|
||||
.global _topti_glyph_fg
|
||||
.global _topti_glyph_bg
|
||||
.section .pretext
|
||||
|
||||
# Glyph rendering functions.
|
||||
# These are pretty naive, using only word accesses to index the VRAM and
|
||||
# absolute positions to index the glyph data, instead of shiting a single
|
||||
# longword to real all bits in order. This is because we only render a subglyph
|
||||
# (for clipping) so there'a non-zero stride in glyph data.
|
||||
|
||||
# Parameters:
|
||||
# r4: vram
|
||||
# r5: data
|
||||
# r6: color (either fg, bg, or (fg << 16) | bg)
|
||||
# r7: height
|
||||
# @(4,r15): width
|
||||
# @(8,r15): dataw - width (stride)
|
||||
# @(12,r15): starting index in data
|
||||
# Stack:
|
||||
# @(0,r15): r8 save
|
||||
|
||||
# Register allocation:
|
||||
# r0: (temporary)
|
||||
# r1: (temporary)
|
||||
# r2: x counter
|
||||
# r3: glyph data index
|
||||
# r4: vram pointer
|
||||
# r5: glyph pointer
|
||||
# r6: color
|
||||
# r7: y counter
|
||||
# Callee-saved registers:
|
||||
# r8: vram stride
|
||||
|
||||
# Opaque foreground, opaque background
|
||||
|
||||
_topti_glyph_fg_bg:
|
||||
|
||||
# Compute VRAM stride 2 * (396-width)
|
||||
mov.l r8, @-r15
|
||||
mov.l 1f, r8
|
||||
mov.l @(4, r15), r3
|
||||
shll r3
|
||||
sub r3, r8
|
||||
|
||||
# Load the starting index
|
||||
mov.l @(12, r15), r3
|
||||
|
||||
.fg_bg_y:
|
||||
# Initialize width counter
|
||||
mov.l @(4, r15), r2
|
||||
|
||||
.fg_bg_x:
|
||||
# Load one bit of data in T
|
||||
mov r3, r0
|
||||
mov #-5, r1
|
||||
shld r1, r0
|
||||
shll2 r0
|
||||
mov.l @(r0, r5), r1
|
||||
|
||||
mov r3, r0
|
||||
and #31, r0
|
||||
|
||||
shld r0, r1
|
||||
shll r1
|
||||
|
||||
# Select the correct 16 bits or r6
|
||||
bf/s .fg_bg_zero
|
||||
mov r6, r1
|
||||
swap.w r6, r1
|
||||
|
||||
.fg_bg_zero:
|
||||
# Write color to VRAM
|
||||
mov.w r1, @r4
|
||||
add #2, r4
|
||||
|
||||
# Leave the x-loop if x counter reaches 0
|
||||
dt r2
|
||||
bf/s .fg_bg_x
|
||||
add #1, r3
|
||||
|
||||
# Move to next row, leave the y-loop if height reaches 0
|
||||
dt r7
|
||||
mov.l @(8, r15), r0
|
||||
add r0, r3
|
||||
bf/s .fg_bg_y
|
||||
add r8, r4
|
||||
|
||||
rts
|
||||
mov.l @r15+, r8
|
||||
|
||||
# Opaque foreground, transparent background
|
||||
|
||||
_topti_glyph_fg:
|
||||
|
||||
# Compute VRAM stride 2 * (396-width)
|
||||
mov.l r8, @-r15
|
||||
mov.l 1f, r8
|
||||
mov.l @(4, r15), r3
|
||||
shll r3
|
||||
sub r3, r8
|
||||
|
||||
# Load the starting index
|
||||
mov.l @(12, r15), r3
|
||||
|
||||
.fg_y:
|
||||
# Initialize width counter
|
||||
mov.l @(4, r15), r2
|
||||
|
||||
.fg_x:
|
||||
# Load one bit of data in T
|
||||
mov r3, r0
|
||||
mov #-5, r1
|
||||
shld r1, r0
|
||||
shll2 r0
|
||||
mov.l @(r0, r5), r1
|
||||
|
||||
mov r3, r0
|
||||
and #31, r0
|
||||
|
||||
shld r0, r1
|
||||
shll r1
|
||||
|
||||
# Write color to VRAM only if it's a 1 bit
|
||||
bf .fg_next
|
||||
mov.w r6, @r4
|
||||
|
||||
.fg_next:
|
||||
# Leave the x-loop if x counter reaches 0
|
||||
add #2, r4
|
||||
dt r2
|
||||
bf/s .fg_x
|
||||
add #1, r3
|
||||
|
||||
# Move to next row, leave the y-loop if height reaches 0
|
||||
dt r7
|
||||
mov.l @(8, r15), r0
|
||||
add r0, r3
|
||||
bf/s .fg_y
|
||||
add r8, r4
|
||||
|
||||
rts
|
||||
mov.l @r15+, r8
|
||||
|
||||
# Transparent foreground, opaque background
|
||||
|
||||
_topti_glyph_bg:
|
||||
|
||||
# Compute VRAM stride 2 * (396-width)
|
||||
mov.l r8, @-r15
|
||||
mov.l 1f, r8
|
||||
mov.l @(4, r15), r3
|
||||
shll r3
|
||||
sub r3, r8
|
||||
|
||||
# Load the starting index
|
||||
mov.l @(12, r15), r3
|
||||
|
||||
.bg_y:
|
||||
# Initialize width counter
|
||||
mov.l @(4, r15), r2
|
||||
|
||||
.bg_x:
|
||||
# Load one bit of data in T
|
||||
mov r3, r0
|
||||
mov #-5, r1
|
||||
shld r1, r0
|
||||
shll2 r0
|
||||
mov.l @(r0, r5), r1
|
||||
|
||||
mov r3, r0
|
||||
and #31, r0
|
||||
|
||||
shld r0, r1
|
||||
shll r1
|
||||
|
||||
# Write color to VRAM only if it's a 0 bit
|
||||
bt .bg_next
|
||||
mov.w r6, @r4
|
||||
|
||||
.bg_next:
|
||||
# Leave the x-loop if x counter reaches 0
|
||||
add #2, r4
|
||||
dt r2
|
||||
bf/s .bg_x
|
||||
add #1, r3
|
||||
|
||||
# Move to next row, leave the y-loop if height reaches 0
|
||||
dt r7
|
||||
mov.l @(8, r15), r0
|
||||
add r0, r3
|
||||
bf/s .bg_y
|
||||
add r8, r4
|
||||
|
||||
rts
|
||||
mov.l @r15+, r8
|
||||
|
||||
# Data
|
||||
|
||||
.align 4
|
||||
|
||||
1: .long 396*2
|
96
src/render-cg/topti.c
Normal file
96
src/render-cg/topti.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
#define GINT_NEED_VRAM
|
||||
#include <gint/defs/types.h>
|
||||
#include <gint/defs/attributes.h>
|
||||
#include <gint/display.h>
|
||||
#include <display/common.h>
|
||||
#include "topti-asm.h"
|
||||
|
||||
/* Default font */
|
||||
extern font_t gint_font10x12;
|
||||
font_t const * gint_default_font = &gint_font10x12;
|
||||
font_t const * topti_font = &gint_font10x12;
|
||||
|
||||
/* topti_glyph(): Render a glyph on the VRAM
|
||||
Prints a glyph naively using word accesses, because for most fonts with a
|
||||
small size (including gint's 10x12 font) this will be more efficient than
|
||||
the complex logic for longword accesses.
|
||||
|
||||
This function assumes that at least one of [fg] and [bg] is not transparent.
|
||||
|
||||
@vram Target position on VRAM, adjusted to [top], not adjusted to [left]
|
||||
@data Glyph data
|
||||
@left Left-position of subglyph
|
||||
@top Top-Position of subglyph
|
||||
@width Subglyph width
|
||||
@height Subglyph height
|
||||
@dataw Glyph width
|
||||
@fg @bg Foreground and background colors */
|
||||
GSECTION(".pretext")
|
||||
void topti_glyph(uint16_t *vram, uint32_t const * data, int left, int top,
|
||||
int width, int height, int dataw, int fg, int bg)
|
||||
{
|
||||
int index = top * dataw + left;
|
||||
|
||||
/* Most common situation: opaque text on transparent background */
|
||||
if(bg < 0) topti_glyph_fg(vram + left, data, fg, height, width,
|
||||
dataw - width, index);
|
||||
/* Full text on opaque background */
|
||||
else if(fg >= 0) topti_glyph_fg_bg(vram + left, data, (fg << 16) | bg,
|
||||
height, width, dataw - width, index);
|
||||
/* Draw background but not text */
|
||||
else topti_glyph_bg(vram + left, data, bg, height, width,
|
||||
dataw - width, index);
|
||||
}
|
||||
|
||||
GSECTION(".pretext")
|
||||
void topti_render(int x, int y, const char *str, size_t size, font_t const *f,
|
||||
int fg, int bg)
|
||||
{
|
||||
/* Raw glyph data */
|
||||
uint32_t const * data = f->prop
|
||||
? (void *)(f->sized_data + charset_size(f->charset))
|
||||
: f->data;
|
||||
|
||||
/* Storage height, top position within glyph */
|
||||
int height = f->data_height, top = 0;
|
||||
|
||||
/* Vertical clipping */
|
||||
if(x > 395 || y > 223 || y + height <= 0) return;
|
||||
if(y + height > 224) height = 224 - y;
|
||||
if(y < 0) top = -y, height += y, y = 0;
|
||||
|
||||
/* Move to top row */
|
||||
uint16_t *target = vram + 396 * y;
|
||||
|
||||
/* Character spacing */
|
||||
int space = 2;
|
||||
|
||||
/* Read each character from the input string */
|
||||
while(size--)
|
||||
{
|
||||
int glyph = charset_decode(f->charset, *str++);
|
||||
if(glyph < 0) continue;
|
||||
|
||||
int index = topti_offset(f, glyph);
|
||||
|
||||
/* Compute horizontal intersection between glyph and screen */
|
||||
|
||||
int dataw = f->prop ? f->sized_data[glyph] : f->width;
|
||||
int width = dataw, left = 0;
|
||||
|
||||
if(x + dataw <= 0)
|
||||
{
|
||||
x += dataw + space;
|
||||
continue;
|
||||
}
|
||||
if(x < 0) left = -x, width += x;
|
||||
if(x + width > 396) width = 396 - x;
|
||||
|
||||
/* Render glyph */
|
||||
|
||||
topti_glyph(target + x, data + index, left, top, width, height,
|
||||
dataw, fg, bg);
|
||||
|
||||
x += dataw + space;
|
||||
}
|
||||
}
|
|
@ -1,11 +1,9 @@
|
|||
#define GINT_NEED_VRAM
|
||||
#include <gint/defs/util.h>
|
||||
#include <gint/display.h>
|
||||
#include <gint/defs/util.h>
|
||||
#include <display/fx.h>
|
||||
|
||||
/* dhline() - optimized drawing of a horizontal line using a rectangle mask
|
||||
@x1 @x2 @y Coordinates of endpoints of line (both included)
|
||||
@color Allowed colors: white, black, none, reverse */
|
||||
/* dhline() - optimized drawing of a horizontal line using a rectangle mask */
|
||||
void dhline(int x1, int x2, int y, color_t color)
|
||||
{
|
||||
if((uint)y >= 64) return;
|
||||
|
@ -31,7 +29,7 @@ void dhline(int x1, int x2, int y, color_t color)
|
|||
data[2] |= m[2];
|
||||
data[3] |= m[3];
|
||||
}
|
||||
else if(color == color_reverse)
|
||||
else if(color == color_invert)
|
||||
{
|
||||
data[0] ^= m[0];
|
||||
data[1] ^= m[1];
|
||||
|
@ -40,92 +38,26 @@ void dhline(int x1, int x2, int y, color_t color)
|
|||
}
|
||||
}
|
||||
|
||||
/* dvline() - optimized drawing of a vertical line
|
||||
This variant is less powerful than dhline() because the line-based structure
|
||||
of the vram cannot be used here.
|
||||
@y1 @y2 @x Coordinates of endpoints of line (both included)
|
||||
@color Allowed colors: black, white, none, reverse */
|
||||
void dvline(int y1, int y2, int x, color_t operator)
|
||||
/* dvline() - optimized drawing of a vertical line */
|
||||
void dvline(int y1, int y2, int x, color_t color)
|
||||
{
|
||||
if((uint)x >= 128) return;
|
||||
if(y1 > y2) swap(y1, y2);
|
||||
|
||||
uint32_t *base = vram + (y1 << 2) + (x >> 5);
|
||||
uint32_t *lword = base + ((y2 - y1 + 1) << 4);
|
||||
uint32_t *lword = base + ((y2 - y1 + 1) << 2);
|
||||
uint32_t mask = 1 << (~x & 31);
|
||||
|
||||
switch(operator)
|
||||
if(color == color_white)
|
||||
{
|
||||
case color_white:
|
||||
while(lword > base) lword -= 4, *lword &= ~mask;
|
||||
break;
|
||||
|
||||
case color_black:
|
||||
}
|
||||
else if(color == color_black)
|
||||
{
|
||||
while(lword > base) lword -= 4, *lword |= mask;
|
||||
break;
|
||||
|
||||
case color_reverse:
|
||||
}
|
||||
else if(color == color_invert)
|
||||
{
|
||||
while(lword > base) lword -= 4, *lword ^= mask;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* dline() - Bresenham line drawing algorithm
|
||||
Remotely adapted from MonochromeLib code by Pierre "PerriotLL" Le Gall.
|
||||
Relies on dhline() and dvline() for optimized situations.
|
||||
@x1 @y1 @x2 @y2 Coordinates of endpoints of line (included)
|
||||
@color Allowed colors: black, white, none, reverse */
|
||||
void dline(int x1, int y1, int x2, int y2, color_t color)
|
||||
{
|
||||
/* Possible optimizations */
|
||||
if(y1 == y2)
|
||||
{
|
||||
dhline(x1, x2, y1, color);
|
||||
return;
|
||||
}
|
||||
if(x1 == x2)
|
||||
{
|
||||
dvline(y1, y2, x1, color);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Brensenham line drawing algorithm */
|
||||
|
||||
int i, x = x1, y = y1, cumul;
|
||||
int dx = x2 - x1, dy = y2 - y1;
|
||||
int sx = sgn(dx), sy = sgn(dy);
|
||||
|
||||
dx = abs(dx), dy = abs(dy);
|
||||
|
||||
dpixel(x1, y1, color);
|
||||
|
||||
if(dx >= dy)
|
||||
{
|
||||
/* Start with a non-zero cumul to even the overdue between the
|
||||
two ends of the line (for more regularity) */
|
||||
cumul = dx >> 1;
|
||||
for(i = 1; i < dx; i++)
|
||||
{
|
||||
x += sx;
|
||||
cumul += dy;
|
||||
if(cumul > dx) cumul -= dx, y += sy;
|
||||
dpixel(x, y, color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cumul = dy >> 1;
|
||||
for(i = 1; i < dy; i++)
|
||||
{
|
||||
y += sy;
|
||||
cumul += dx;
|
||||
if(cumul > dy) cumul -= dy, x += sx;
|
||||
dpixel(x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
dpixel(x2, y2, color);
|
||||
}
|
||||
|
|
|
@ -11,18 +11,16 @@ void dpixel(int x, int y, color_t color)
|
|||
uint32_t *lword = vram + (y << 2) + (x >> 5);
|
||||
uint32_t mask = 1 << (~x & 31);
|
||||
|
||||
switch(color)
|
||||
if(color == color_white)
|
||||
{
|
||||
case color_white:
|
||||
*lword &= ~mask;
|
||||
break;
|
||||
case color_black:
|
||||
}
|
||||
else if(color == color_black)
|
||||
{
|
||||
*lword |= mask;
|
||||
break;
|
||||
case color_reverse:
|
||||
}
|
||||
else if(color == color_invert)
|
||||
{
|
||||
*lword ^= mask;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ void drect(int x1, int y1, int x2, int y2, color_t color)
|
|||
*--lword |= m[1];
|
||||
*--lword |= m[0];
|
||||
}
|
||||
else if(color == color_reverse) while(lword > base)
|
||||
else if(color == color_invert) while(lword > base)
|
||||
{
|
||||
*--lword ^= m[3];
|
||||
*--lword ^= m[2];
|
||||
|
|
|
@ -94,7 +94,7 @@ _topti_asm_none:
|
|||
nop
|
||||
|
||||
.align 4
|
||||
_topti_asm_reverse:
|
||||
_topti_asm_invert:
|
||||
1: mov.l @r6+, r0
|
||||
dt r7
|
||||
mov.l @r4, r1
|
||||
|
@ -165,7 +165,7 @@ _topti_asm_text:
|
|||
.long _topti_asm_dark
|
||||
.long _topti_asm_black
|
||||
.long _topti_asm_none
|
||||
.long _topti_asm_reverse
|
||||
.long _topti_asm_invert
|
||||
.long _topti_asm_lighten
|
||||
.long _topti_asm_darken
|
||||
|
||||
|
|
|
@ -2,104 +2,14 @@
|
|||
#include <gint/defs/types.h>
|
||||
#include <gint/defs/attributes.h>
|
||||
#include <gint/display.h>
|
||||
#include <display/common.h>
|
||||
#include "topti-asm.h"
|
||||
|
||||
/* Default font */
|
||||
extern font_t gint_font5x7;
|
||||
font_t const * gint_default_font = &gint_font5x7;
|
||||
font_t const * topti_font = &gint_font5x7;
|
||||
|
||||
/* dfont() - set the default font for text rendering */
|
||||
GSECTION(".pretext")
|
||||
void dfont(font_t const * font)
|
||||
{
|
||||
topti_font = font ? font : &gint_font5x7;
|
||||
}
|
||||
|
||||
/* enum charset: Available character set decoders
|
||||
Each charset is associated with a reduced character table. */
|
||||
enum charset
|
||||
{
|
||||
charset_numeric = 0, /* 10 elements: 0..9 */
|
||||
charset_upper = 1, /* 26 elements: A..Z */
|
||||
charset_alpha = 2, /* 52 elements: A..Z, a..z */
|
||||
charset_alnum = 3, /* 62 elements: A..Z, a..z, 0..9 */
|
||||
charset_print = 4, /* 95 elements: 0x20..0x7e */
|
||||
charset_ascii = 5, /* 128 elements: 0x00..0x7f */
|
||||
};
|
||||
|
||||
/* charset_size(): Number of elements in each character set
|
||||
@set Character set ID
|
||||
Returns the expected number of glyphs, -1 if charset ID is invalid. */
|
||||
GSECTION(".pretext")
|
||||
int charset_size(enum charset set)
|
||||
{
|
||||
int size[] = { 10, 26, 52, 62, 95, 128 };
|
||||
return (uint)set < 6 ? size[set] : -1;
|
||||
}
|
||||
|
||||
/* charset_decode(): Translate ASCII into reduced character sets
|
||||
Returns the position of [c] in the character table of the given charset, or
|
||||
-1 if [c] is not part of that set.
|
||||
@set Any character set
|
||||
@c Character to decode */
|
||||
GSECTION(".pretext")
|
||||
int charset_decode(enum charset set, uint c)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
switch(set)
|
||||
{
|
||||
case charset_numeric:
|
||||
x = c - '0';
|
||||
return (x < 10) ? x : -1;
|
||||
case charset_upper:
|
||||
x = (c - 'A') & ~0x20;
|
||||
return (x < 26) ? x : -1;
|
||||
case charset_alnum:
|
||||
x = c - '0';
|
||||
if(x < 10) return x;
|
||||
/* Intentional fallthrough */
|
||||
case charset_alpha:
|
||||
y = c & 0x20;
|
||||
x = (c ^ y) - 'A';
|
||||
/* Turn 32 into 26 and leave 0 as 0 */
|
||||
y = y - (y >> 3) - (y >> 4);
|
||||
return (x < 26) ? (x + y) : -1;
|
||||
case charset_print:
|
||||
x = c - 0x20;
|
||||
return (x < 0x5f) ? x : -1;
|
||||
case charset_ascii:
|
||||
return c;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* topti_offset(): Use a font index to find the location of a glyph
|
||||
@f Font object
|
||||
@glyph Glyph number obtained by charset_decode(), must be nonnegative.
|
||||
Returns the offset the this glyph's data in the font's data array. When
|
||||
using a proportional font, the size array is not heeded for. */
|
||||
GSECTION(".pretext")
|
||||
int topti_offset(font_t const *f, uint glyph)
|
||||
{
|
||||
/* Non-proportional fonts don't need an index */
|
||||
if(!f->prop) return glyph * f->storage_size;
|
||||
|
||||
uint8_t const *width = f->sized_data;
|
||||
|
||||
/* The index gives us the position of all glyphs whose IDs are mutiples
|
||||
of 8. Start with a close one and iterate from there. */
|
||||
uint g = glyph & ~0x7;
|
||||
int offset = f->index[g >> 3];
|
||||
|
||||
/* Traverse the width array (which is in bits) while converting to
|
||||
longword size */
|
||||
while(g < glyph) offset += (width[g++] * f->data_height + 31) >> 5;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* topti_split(): Split glyph data into lines
|
||||
This function splits the data from [glyph] inyo lines and writes a bit of
|
||||
each line in [operators]. This operation is meant to be used multiple times
|
||||
|
@ -299,7 +209,7 @@ void dsize(const char *str, font_t const * f, int *w, int *h)
|
|||
|
||||
/* dtext() - display a string of text */
|
||||
GSECTION(".pretext")
|
||||
void dtext(int x, int y, const char *str, color_t fg, color_t bg)
|
||||
void dtext(int x, int y, const char *str, int fg, int bg)
|
||||
{
|
||||
if((uint)fg >= 8 || (uint)bg >= 8) return;
|
||||
topti_render(x, y, str, topti_font, topti_asm_text[fg],
|
||||
|
|
60
src/render/dline.c
Normal file
60
src/render/dline.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include <gint/display.h>
|
||||
#include <gint/defs/util.h>
|
||||
#include <display/common.h>
|
||||
|
||||
/* dline() - Bresenham line drawing algorithm
|
||||
Remotely adapted from MonochromeLib code by Pierre "PerriotLL" Le Gall.
|
||||
Relies on platform-dependent dhline() and dvline() for optimized situations.
|
||||
@x1 @y1 @x2 @y2 Coordinates of endpoints of line (included)
|
||||
@color Any R5G6B5 color */
|
||||
void dline(int x1, int y1, int x2, int y2, color_t color)
|
||||
{
|
||||
/* Possible optimizations */
|
||||
if(y1 == y2)
|
||||
{
|
||||
dhline(x1, x2, y1, color);
|
||||
return;
|
||||
}
|
||||
if(x1 == x2)
|
||||
{
|
||||
dvline(y1, y2, x1, color);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Brensenham line drawing algorithm */
|
||||
|
||||
int i, x = x1, y = y1, cumul;
|
||||
int dx = x2 - x1, dy = y2 - y1;
|
||||
int sx = sgn(dx), sy = sgn(dy);
|
||||
|
||||
dx = abs(dx), dy = abs(dy);
|
||||
|
||||
dpixel(x1, y1, color);
|
||||
|
||||
if(dx >= dy)
|
||||
{
|
||||
/* Start with a non-zero cumul to even the overdue between the
|
||||
two ends of the line (for more regularity) */
|
||||
cumul = dx >> 1;
|
||||
for(i = 1; i < dx; i++)
|
||||
{
|
||||
x += sx;
|
||||
cumul += dy;
|
||||
if(cumul > dx) cumul -= dx, y += sy;
|
||||
dpixel(x, y, color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cumul = dy >> 1;
|
||||
for(i = 1; i < dy; i++)
|
||||
{
|
||||
y += sy;
|
||||
cumul += dx;
|
||||
if(cumul > dy) cumul -= dy, x += sx;
|
||||
dpixel(x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
dpixel(x2, y2, color);
|
||||
}
|
73
src/render/topti.c
Normal file
73
src/render/topti.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
#include <gint/defs/types.h>
|
||||
#include <gint/display.h>
|
||||
#include <display/common.h>
|
||||
|
||||
/* dfont(): Set the default font for text rendering */
|
||||
GSECTION(".pretext")
|
||||
void dfont(font_t const * font)
|
||||
{
|
||||
topti_font = font ? font : gint_default_font;
|
||||
}
|
||||
|
||||
/* charset_size(): Number of elements in each character set */
|
||||
GSECTION(".pretext")
|
||||
int charset_size(enum topti_charset set)
|
||||
{
|
||||
int size[] = { 10, 26, 52, 62, 95, 128 };
|
||||
return (uint)set < 6 ? size[set] : -1;
|
||||
}
|
||||
|
||||
/* charset_decode(): Translate ASCII into reduced character sets */
|
||||
GSECTION(".pretext")
|
||||
int charset_decode(enum topti_charset set, uint c)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
switch(set)
|
||||
{
|
||||
case charset_numeric:
|
||||
x = c - '0';
|
||||
return (x < 10) ? x : -1;
|
||||
case charset_upper:
|
||||
x = (c - 'A') & ~0x20;
|
||||
return (x < 26) ? x : -1;
|
||||
case charset_alnum:
|
||||
x = c - '0';
|
||||
if(x < 10) return x;
|
||||
/* Intentional fallthrough */
|
||||
case charset_alpha:
|
||||
y = c & 0x20;
|
||||
x = (c ^ y) - 'A';
|
||||
/* Turn 32 into 26 and leave 0 as 0 */
|
||||
y = y - (y >> 3) - (y >> 4);
|
||||
return (x < 26) ? (x + y) : -1;
|
||||
case charset_print:
|
||||
x = c - 0x20;
|
||||
return (x < 0x5f) ? x : -1;
|
||||
case charset_ascii:
|
||||
return c;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* topti_offset(): Use a font index to find the location of a glyph */
|
||||
GSECTION(".pretext")
|
||||
int topti_offset(font_t const *f, uint glyph)
|
||||
{
|
||||
/* Non-proportional fonts don't need an index */
|
||||
if(!f->prop) return glyph * f->storage_size;
|
||||
|
||||
uint8_t const *width = f->sized_data;
|
||||
|
||||
/* The index gives us the position of all glyphs whose IDs are mutiples
|
||||
of 8. Start with a close one and iterate from there. */
|
||||
uint g = glyph & ~0x7;
|
||||
int offset = f->index[g >> 3];
|
||||
|
||||
/* Traverse the width array (which is in bits) while converting to
|
||||
longword size */
|
||||
while(g < glyph) offset += (width[g++] * f->data_height + 31) >> 5;
|
||||
|
||||
return offset;
|
||||
}
|
Loading…
Reference in a new issue