diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b9fe08..e83f1c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,6 +132,7 @@ set(SOURCES_FX # Gray engine src/gray/engine.c src/gray/gclear.c + src/gray/ggetpixel.c src/gray/gint_gline.c src/gray/gpixel.c src/gray/grect.c @@ -144,6 +145,7 @@ set(SOURCES_FX src/render-fx/bopti-asm.s src/render-fx/bopti.c src/render-fx/dclear.c + src/render-fx/dgetpixel.c src/render-fx/dpixel.c src/render-fx/drect.c src/render-fx/dsubimage.c @@ -193,6 +195,7 @@ set(SOURCES_CG src/image/image_vflip_alloc.c # Rendering src/render-cg/dclear.c + src/render-cg/dgetpixel.c src/render-cg/dpixel.c src/render-cg/drect.c src/render-cg/dsubimage.c diff --git a/TODO b/TODO index 0d37de9..ddad120 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,6 @@ +Bugs to fix: +* render: figure out why fx-CG dclear() now takes 4.1 ms instead of 2.6 ms + Extensions on existing code: * clock: mono support * usb: add PC->calc reading, and interrupt pipes diff --git a/include/gint/display.h b/include/gint/display.h index 3a648bc..d5bb39e 100644 --- a/include/gint/display.h +++ b/include/gint/display.h @@ -151,6 +151,11 @@ void drect_border(int x1, int y1, int x2, int y2, *: When the gray engine is on, see dgray(). */ void dpixel(int x, int y, int color); +/* dgetpixel(): Get a pixel's color + Returns the current color of any pixel in the VRAM. This function ignores + the rendering window. Returns -1 if (x,y) is out of bounds. */ +int dgetpixel(int x, int y); + /* dline(): Render a straight line This function draws a line using a Bresenham-style algorithm. Please note diff --git a/src/gray/engine.c b/src/gray/engine.c index 08aa9bf..906887d 100644 --- a/src/gray/engine.c +++ b/src/gray/engine.c @@ -41,6 +41,7 @@ static struct rendering_mode const gray_mode = { .dclear = gclear, .drect = grect, .dpixel = gpixel, + .dgetpixel = ggetpixel, .gint_dhline = gint_ghline, .gint_dvline = gint_gvline, .dtext_opt = gtext_opt, @@ -51,6 +52,7 @@ static struct rendering_mode const gray_exit_mode = { .dclear = NULL, .drect = NULL, .dpixel = NULL, + .dgetpixel = NULL, .gint_dhline = NULL, .gint_dvline = NULL, .dtext_opt = NULL, diff --git a/src/gray/ggetpixel.c b/src/gray/ggetpixel.c new file mode 100644 index 0000000..c508d5c --- /dev/null +++ b/src/gray/ggetpixel.c @@ -0,0 +1,15 @@ +#include +#include + +int ggetpixel(int x, int y) +{ + uint32_t *light, *dark; + dgray_getvram(&light, &dark); + + int offset = (y << 2) + (x >> 5); + uint32_t mask = 1 << (~x & 31); + + bool l = (light[offset] & mask) != 0; + bool d = (dark [offset] & mask) != 0; + return (d << 1) | l; +} diff --git a/src/render-cg/dgetpixel.c b/src/render-cg/dgetpixel.c new file mode 100644 index 0000000..1068449 --- /dev/null +++ b/src/render-cg/dgetpixel.c @@ -0,0 +1,7 @@ +#include + +int dgetpixel(int x, int y) +{ + if((uint)x >= DWIDTH || (uint)y >= DHEIGHT) return -1; + return gint_vram[DWIDTH * y + x]; +} diff --git a/src/render-fx/dgetpixel.c b/src/render-fx/dgetpixel.c new file mode 100644 index 0000000..d394db6 --- /dev/null +++ b/src/render-fx/dgetpixel.c @@ -0,0 +1,15 @@ +#include +#include +#include "render-fx.h" + +int dgetpixel(int x, int y) +{ + if((uint)x >= DWIDTH || (uint)y >= DHEIGHT) return -1; + + DMODE_OVERRIDE(dgetpixel, x, y); + + int offset = (y << 2) + (x >> 5); + uint32_t mask = 1 << (~x & 31); + + return (gint_vram[offset] & mask) ? C_BLACK : C_WHITE; +} diff --git a/src/render-fx/render-fx.h b/src/render-fx/render-fx.h index 3146ef8..f21f3ed 100644 --- a/src/render-fx/render-fx.h +++ b/src/render-fx/render-fx.h @@ -69,6 +69,7 @@ struct rendering_mode void (*drect)(int x1, int y1, int x2, int y2, color_t color); /* Point rendering */ void (*dpixel)(int x, int y, color_t color); + int (*dgetpixel)(int x, int y); void (*gint_dhline)(int x1, int x2, int y, int color); void (*gint_dvline)(int y1, int y2, int x, int color); /* Text and image rendering */ @@ -87,6 +88,7 @@ int gupdate(void); void gclear(color_t color); void grect(int x1, int y1, int x2, int y2, color_t color); void gpixel(int x, int y, color_t color); +int ggetpixel(int x, int y); void gint_ghline(int x1, int x2, int y, int color); void gint_gvline(int y1, int y2, int x, int color); void gtext_opt(int x, int y, int fg, int bg, int halign, int valign, @@ -94,10 +96,9 @@ void gtext_opt(int x, int y, int fg, int bg, int halign, int valign, void gsubimage(bopti_image_t const *image, struct rbox *r, int flags); /* Short macro to call the alternate rendering function when available */ -#define DMODE_OVERRIDE(func, ...) \ - if(dmode && dmode->func) { \ - dmode->func(__VA_ARGS__); \ - return; \ +#define DMODE_OVERRIDE(func, ...) \ + if(dmode && dmode->func) { \ + return dmode->func(__VA_ARGS__); \ } #endif /* RENDER_FX */