From d70d3b4e4a7fb93ab928981bf4e10dc41d3fc3ce Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Tue, 1 Sep 2015 11:37:12 +0200 Subject: [PATCH] Kandinsky now uses KDSetPixel for framebuffer access --- kandinsky/Makefile | 6 ++- kandinsky/include/kandinsky.h | 2 +- kandinsky/include/kandinsky/color.h | 14 +++---- kandinsky/include/kandinsky/line.h | 3 +- .../kandinsky/{referential.h => pixel.h} | 0 kandinsky/src/line.c | 6 +-- kandinsky/src/pixel.c | 42 +++++++++++++++++++ kandinsky/src/rect.c | 12 ++++-- kandinsky/src/referential.c | 20 --------- kandinsky/src/text.c | 4 +- 10 files changed, 70 insertions(+), 39 deletions(-) rename kandinsky/include/kandinsky/{referential.h => pixel.h} (100%) create mode 100644 kandinsky/src/pixel.c delete mode 100644 kandinsky/src/referential.c diff --git a/kandinsky/Makefile b/kandinsky/Makefile index 3b729095a..520a07b6b 100644 --- a/kandinsky/Makefile +++ b/kandinsky/Makefile @@ -1,5 +1,6 @@ -SFLAGS += -Ikandinsky/include -Iplatform/stm32f429 -objs += $(addprefix kandinsky/src/, line.o text.o font.o rect.o referential.o) +SFLAGS += -Ikandinsky/include +objs += $(addprefix kandinsky/src/, font.o line.o pixel.o rect.o text.o) +tests += $(addprefix kandinsky/test/, set_pixel.o) FREETYPE_PATH := /usr/local/Cellar/freetype/2.5.5 LIBPNG_PATH := /usr/local/Cellar/libpng/1.6.17 @@ -21,3 +22,4 @@ kandinsky/fonts/rasterizer: kandinsky/fonts/rasterizer.c @clang -I$(FREETYPE_PATH)/include/freetype2 -L$(FREETYPE_PATH)/lib -lfreetype $< -o $@ products += $(font_files) kandinsky/fonts/rasterizer + diff --git a/kandinsky/include/kandinsky.h b/kandinsky/include/kandinsky.h index 51134600e..7f34c1825 100644 --- a/kandinsky/include/kandinsky.h +++ b/kandinsky/include/kandinsky.h @@ -3,8 +3,8 @@ #include #include +#include #include -#include #include #include diff --git a/kandinsky/include/kandinsky/color.h b/kandinsky/include/kandinsky/color.h index a014f1f7c..36514ee94 100644 --- a/kandinsky/include/kandinsky/color.h +++ b/kandinsky/include/kandinsky/color.h @@ -4,18 +4,18 @@ #include #include +#if (KD_BITS_PER_PIXEL & (KD_BITS_PER_PIXEL - 1)) +#error KD_BITS_PER_PIXEL should be a power of two! +// PoT implies that all pixels are byte-aligned +#endif #if KD_BITS_PER_PIXEL <= 8 -#warning KD_BITS_PER_PIXEL -#warning 8 bpp typedef uint8_t KDColor; -/* -#elif KD_BITS_PER_PIXEL <= 16 +#elif KD_BITS_PER_PIXEL == 16 typedef uint16_t KDColor; -#elif KD_BITS_PER_PIXEL <= 32 +#elif KD_BITS_PER_PIXEL == 32 typedef uint32_t KDColor; -#elif KD_BITS_PER_PIXEL <= 64 +#elif KD_BITS_PER_PIXEL == 64 typedef uint64_t KDColor; -*/ #else #error KD_BITS_PER_PIXEL is too large! #endif diff --git a/kandinsky/include/kandinsky/line.h b/kandinsky/include/kandinsky/line.h index 02ec9a706..9243465a0 100644 --- a/kandinsky/include/kandinsky/line.h +++ b/kandinsky/include/kandinsky/line.h @@ -1,8 +1,9 @@ #ifndef KANDINSKY_LINE_H #define KANDINSKY_LINE_H +#include #include -void KDDrawLine(KDPoint p1, KDPoint p2); +void KDDrawLine(KDPoint p1, KDPoint p2);//, KDColor c); #endif diff --git a/kandinsky/include/kandinsky/referential.h b/kandinsky/include/kandinsky/pixel.h similarity index 100% rename from kandinsky/include/kandinsky/referential.h rename to kandinsky/include/kandinsky/pixel.h diff --git a/kandinsky/src/line.c b/kandinsky/src/line.c index 2d64f0c73..5f3a9399a 100644 --- a/kandinsky/src/line.c +++ b/kandinsky/src/line.c @@ -1,8 +1,8 @@ #include -#include +#include -void KDDrawLine(KDPoint p1, KDPoint p2) { +void KDDrawLine(KDPoint p1, KDPoint p2) { //, KDColor c) { for (KDCoordinate x = p1.x; x +#include +#include + +static KDPoint sOrigin = {.x = 0, .y = 0}; + +#define BIT_MASK(high, low) ((((uint32_t)1<<((high)-(low)+1))-1)<<(low)) +#define BIT_VALUE(value, high, low) (((value)<<(low))&BIT_MASK(high, low)) + +static inline void set_color(KDColor * address, int8_t high_bit, int8_t low_bit, KDColor value) { + assert(high_bit-low_bit+1 <= 8*sizeof(KDColor)); // Interval too large + assert(low_bit >= 0); // Interval starts too early + assert(low_bit < 8*sizeof(KDColor)); // Interval ends too late + KDColor mask = ((((KDColor)1<<(high_bit-low_bit+1))-1)<= KD_FRAMEBUFFER_ADDRESS); + assert(address < (KD_FRAMEBUFFER_ADDRESS+(KD_FRAMEBUFFER_WIDTH*KD_FRAMEBUFFER_HEIGHT*KD_BITS_PER_PIXEL)/8)); + *address = (*address & ~mask) | (value & mask); +} + +void KDSetOrigin(KDPoint origin) { + sOrigin = origin; +} + +KDPoint KDGetOrigin() { + return sOrigin; +} + +void KDSetPixel(KDPoint p, KDColor c) { + assert(p.x >= 0); + assert(p.x < KD_FRAMEBUFFER_WIDTH); + assert(p.y >= 0); + assert(p.y < KD_FRAMEBUFFER_HEIGHT); + int pixels_offset = p.y*(KD_FRAMEBUFFER_WIDTH) + p.x; + int bits_offset = (KD_BITS_PER_PIXEL)*pixels_offset; + const uint8_t color_bitsize = 8*sizeof(KDColor); + // Notice: the "const" here is rather important. Indeed, it hints the compiler + // for the following "modulo", which helps us avoid idivmod. + int color_offset = bits_offset/color_bitsize; + int8_t low_bit = bits_offset % color_bitsize; + int8_t high_bit = low_bit + KD_BITS_PER_PIXEL - 1; + set_color((KDColor *)(KD_FRAMEBUFFER_ADDRESS+color_offset), high_bit, low_bit, c); +} diff --git a/kandinsky/src/rect.c b/kandinsky/src/rect.c index e9226a920..9435a0c26 100644 --- a/kandinsky/src/rect.c +++ b/kandinsky/src/rect.c @@ -1,9 +1,15 @@ #include -#include +#include #include void KDFillRect(KDRect rect, KDColor color) { - for (KDCoordinate y = rect.y ; y < (rect.y + rect.height); y++) { - memset(KDPixelAddress((KDPoint){.x=rect.x, .y=y}), color, rect.width); + //for (KDCoordinate y = rect.y ; y < (rect.y + rect.height); y++) { + //memset(KDPixelAddress((KDPoint){.x=rect.x, .y=y}), color, rect.width); + //} + KDPoint p; + for (p.x = rect.x; p.x<(rect.x+rect.width-1); p.x++) { + for (p.y = rect.y; p.y<(rect.y+rect.height-1); p.y++) { + KDSetPixel(p, color); + } } } diff --git a/kandinsky/src/referential.c b/kandinsky/src/referential.c deleted file mode 100644 index bf8131767..000000000 --- a/kandinsky/src/referential.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -static KDPoint sOrigin = {.x = 0, .y = 0}; - -void KDSetOrigin(KDPoint origin) { - sOrigin = origin; -} - -KDPoint KDGetOrigin() { - return sOrigin; -} - -KDColor * KDPixelAddress(KDPoint p) { - KDPoint origin = KDGetOrigin(); - return (KDColor *)(KD_FRAMEBUFFER_ADDRESS - + KD_FRAMEBUFFER_WIDTH*(p.y + origin.y) - + (p.x + origin.x)); -} - diff --git a/kandinsky/src/text.c b/kandinsky/src/text.c index 6181639c2..4d4f4de16 100644 --- a/kandinsky/src/text.c +++ b/kandinsky/src/text.c @@ -1,12 +1,12 @@ #include -#include +#include #include #include "font.h" void KDDrawChar(char character, KDPoint p) { for (int j=0; j