From 81baa4c26a7784a2bbb6807d07e61abe4cfbf23e Mon Sep 17 00:00:00 2001 From: lephe Date: Sat, 4 May 2019 21:00:40 +0200 Subject: [PATCH] bopti: expose bopti functions and implement dimage() and dimage_opt() --- include/display/fx.h | 20 +++++++++++++++ include/gint/display-fx.h | 27 ++++++++++++++++++++ src/render-fx/bopti.c | 2 +- src/render-fx/dimage.c | 25 +++++++++++++++++++ src/render-fx/drect.c | 52 ++++++++++++++------------------------- 5 files changed, 92 insertions(+), 34 deletions(-) create mode 100644 src/render-fx/dimage.c diff --git a/include/display/fx.h b/include/display/fx.h index 876b930..289b964 100644 --- a/include/display/fx.h +++ b/include/display/fx.h @@ -27,4 +27,24 @@ 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] + @left @top @w @h Bounding box to render */ +void bopti_render_clip(int x, int y, image_t const *img, int left, int top, + int w, int h); + +/* bopti_render_noclip() - render a bopti image without clipping + This function is only ever slightly faster than bopti_render_clip(), + eliminating two types of coordinate checks: + 1. The bounding box does not overflow from the image + 2. The final rendering does not overflow from the screen + + @x @y Location of the top-left corner + @img Image encoded by [fxconv] + @left @top @w @h Bounding box to render */ +void bopti_render_noclip(int x, int y, image_t const *img, int left, int top, + int w, int h); + + #endif /* DISPLAY_FX */ diff --git a/include/gint/display-fx.h b/include/gint/display-fx.h index d052191..e7e0426 100644 --- a/include/gint/display-fx.h +++ b/include/gint/display-fx.h @@ -134,6 +134,33 @@ typedef struct } GPACKED(4) image_t; +/* dimage() - render a full image + This function blits an image on the VRAM using gint's special format. It is + a special case of dimage_opt() where the full image is drawn with clipping. + + @x @y Coordinates of the top-left corner of the image + @image Pointer to image encoded with [fxconv] */ +void dimage(int x, int y, image_t const *image); + +/* Option values for dimage_opt() */ +enum { + /* Disable clipping, ie. adjustments to the specified subrectangle and + screen location such that any part that overflows from the image or + the screen is ignored. Slightly faster. */ + DIMAGE_NOCLIP = 0x01, +}; + +/* dimage_opt() - render a section of an image + This function blits a subrectangle [left, top, width, height] of an image on + the VRAM. It is more general than dimage() and also provides a few options. + + @x @y Coordinates on screen of the rendered subrectangle + @image Pointer to image encoded with [fxconv] + @left @top Top-left coordinates of the subrectangle within [image] + @width @height Subrectangle dimensions */ +void dimage_opt(int x, int y, image_t const *image, int left, int top, + int width, int height, int flags); + //--- // Text rendering (topti) //--- diff --git a/src/render-fx/bopti.c b/src/render-fx/bopti.c index 3bbc225..d19a5d8 100644 --- a/src/render-fx/bopti.c +++ b/src/render-fx/bopti.c @@ -52,7 +52,7 @@ struct command /* Ignored elements between two rendered grid rows */ int vram_stride; - /* Ignored elements between two columns rendered grid columns */ + /* Ignored elements between two rendered grid columns */ int data_stride; /* Assembly function, prototype depends on image type */ diff --git a/src/render-fx/dimage.c b/src/render-fx/dimage.c new file mode 100644 index 0000000..59fd24f --- /dev/null +++ b/src/render-fx/dimage.c @@ -0,0 +1,25 @@ +#include +#include + +/* dimage() - render a full image */ +void dimage(int x, int y, image_t const *img) +{ + if(img->gray) return; + bopti_render_clip(x, y, img, 0, 0, img->width, img->height); +} + +/* dimage_opt() - render a section of an image */ +void dimage_opt(int x, int y, image_t const *img, int left, int top, + int width, int height, int flags) +{ + if(img->gray) return; + + if(flags & DIMAGE_NOCLIP) + { + bopti_render_noclip(x, y, img, left, top, width, height); + } + else + { + bopti_render_clip(x, y, img, left, top, width, height); + } +} diff --git a/src/render-fx/drect.c b/src/render-fx/drect.c index 927cf98..6d4ce82 100644 --- a/src/render-fx/drect.c +++ b/src/render-fx/drect.c @@ -23,39 +23,25 @@ void drect(int x1, int y1, int x2, int y2, color_t color) uint32_t *base = vram + (y1 << 2); uint32_t *lword = vram + (y2 << 2) + 4; - switch(color) + if(color == color_white) while(lword > base) { - case color_white: - while(lword > base) - { - *--lword &= ~m[3]; - *--lword &= ~m[2]; - *--lword &= ~m[1]; - *--lword &= ~m[0]; - } - break; - - case color_black: - while(lword > base) - { - *--lword |= m[3]; - *--lword |= m[2]; - *--lword |= m[1]; - *--lword |= m[0]; - } - break; - - case color_reverse: - while(lword > base) - { - *--lword ^= m[3]; - *--lword ^= m[2]; - *--lword ^= m[1]; - *--lword ^= m[0]; - } - break; - - /* Other colors are unsupported */ - default: return; + *--lword &= ~m[3]; + *--lword &= ~m[2]; + *--lword &= ~m[1]; + *--lword &= ~m[0]; + } + else if(color == color_black) while(lword > base) + { + *--lword |= m[3]; + *--lword |= m[2]; + *--lword |= m[1]; + *--lword |= m[0]; + } + else if(color == color_reverse) while(lword > base) + { + *--lword ^= m[3]; + *--lword ^= m[2]; + *--lword ^= m[1]; + *--lword ^= m[0]; } }