From 973e34089e33f06cfd9ed560db968870e22c2b8a Mon Sep 17 00:00:00 2001 From: inmarket Date: Tue, 24 Sep 2013 16:10:15 +1000 Subject: [PATCH] GDISP streaming bug fixes Win32 bitmap support Win32 Rotation is back to front. Need to check touch and other drivers. --- drivers/multiple/Win32/gdisp_lld.c | 192 ++++++++++------------ drivers/multiple/Win32/gdisp_lld_config.h | 2 +- gfxconf.example.h | 31 ++-- include/gdisp/gdisp.h | 52 ++++++ include/gdisp/lld/gdisp_lld.h | 26 +-- include/gmisc/gmisc.h | 17 ++ include/gmisc/options.h | 14 +- src/gdisp/gdisp.c | 37 ++--- 8 files changed, 209 insertions(+), 162 deletions(-) diff --git a/drivers/multiple/Win32/gdisp_lld.c b/drivers/multiple/Win32/gdisp_lld.c index d6c6b2fb..0f1a0b03 100644 --- a/drivers/multiple/Win32/gdisp_lld.c +++ b/drivers/multiple/Win32/gdisp_lld.c @@ -340,16 +340,16 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) { y = g->p.y; break; case GDISP_ROTATE_90: - x = g->g.Height - 1 - g->p.y; - y = g->p.x; + x = g->p.y; + y = g->g.Width - 1 - g->p.x; break; case GDISP_ROTATE_180: x = g->g.Width - 1 - g->p.x; y = g->g.Height - 1 - g->p.y; break; case GDISP_ROTATE_270: - x = g->p.y; - y = g->g.Width - 1 - g->p.x; + x = g->g.Height - 1 - g->p.y; + y = g->p.x; break; } #else @@ -384,10 +384,10 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) { rect.right = rect.left + g->p.cx; break; case GDISP_ROTATE_90: - rect.top = g->p.x; - rect.bottom = rect.top + g->p.cx; - rect.right = g->g.Height - g->p.y; - rect.left = rect.right - g->p.cy; + rect.bottom = g->g.Width - g->p.x; + rect.top = rect.bottom - g->p.cx; + rect.left = g->p.y; + rect.right = rect.left + g->p.cy; break; case GDISP_ROTATE_180: rect.bottom = g->g.Height - g->p.y; @@ -396,10 +396,10 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) { rect.left = rect.right - g->p.cx; break; case GDISP_ROTATE_270: - rect.bottom = g->g.Width - g->p.x; - rect.top = rect.bottom - g->p.cx; - rect.left = g->p.y; - rect.right = rect.left + g->p.cy; + rect.top = g->p.x; + rect.bottom = rect.top + g->p.cx; + rect.right = g->g.Height - g->p.y; + rect.left = rect.right - g->p.cy; break; } #else @@ -420,8 +420,8 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) { } #endif -#if 0 && (GDISP_HARDWARE_BITFILLS && GDISP_NEED_CONTROL) - static pixel_t *rotateimg(coord_t cx, coord_t cy, coord_t srcx, coord_t srccx, const pixel_t *buffer) { +#if GDISP_HARDWARE_BITFILLS && GDISP_NEED_CONTROL + static pixel_t *rotateimg(GDISPDriver *g, const pixel_t *buffer) { pixel_t *dstbuf; pixel_t *dst; const pixel_t *src; @@ -429,37 +429,37 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) { coord_t i, j; // Shortcut. - if (GC->g.Orientation == GDISP_ROTATE_0 && srcx == 0 && cx == srccx) + if (g->g.Orientation == GDISP_ROTATE_0 && g->p.x1 == 0 && g->p.cx == g->p.x2) return (pixel_t *)buffer; // Allocate the destination buffer - sz = (size_t)cx * (size_t)cy; + sz = (size_t)g->p.cx * (size_t)g->p.cy; if (!(dstbuf = (pixel_t *)malloc(sz * sizeof(pixel_t)))) return 0; // Copy the bits we need - switch(GC->g.Orientation) { + switch(g->g.Orientation) { case GDISP_ROTATE_0: - for(dst = dstbuf, src = buffer+srcx, j = 0; j < cy; j++) - for(i = 0; i < cx; i++, src += srccx - cx) + for(dst = dstbuf, src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx) + for(i = 0; i < g->p.cx; i++) *dst++ = *src++; break; case GDISP_ROTATE_90: - for(src = buffer+srcx, j = 0; j < cy; j++) { - dst = dstbuf+cy-j-1; - for(i = 0; i < cx; i++, src += srccx - cx, dst += cy) + for(src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx) { + dst = dstbuf+sz-g->p.cy+j; + for(i = 0; i < g->p.cx; i++, dst -= g->p.cy) *dst = *src++; } break; case GDISP_ROTATE_180: - for(dst = dstbuf+sz, src = buffer+srcx, j = 0; j < cy; j++) - for(i = 0; i < cx; i++, src += srccx - cx) + for(dst = dstbuf+sz, src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx) + for(i = 0; i < g->p.cx; i++) *--dst = *src++; break; case GDISP_ROTATE_270: - for(src = buffer+srcx, j = 0; j < cy; j++) { - dst = dstbuf+sz-cy+j; - for(i = 0; i < cx; i++, src += srccx - cx, dst -= cy) + for(src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx) { + dst = dstbuf+g->p.cy-j-1; + for(i = 0; i < g->p.cx; i++, dst += g->p.cy) *dst = *src++; } break; @@ -468,34 +468,24 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) { } #endif -#if 0 && GDISP_HARDWARE_BITFILLS - /** - * @brief Fill an area with a bitmap. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x, y The start filled area - * @param[in] cx, cy The width and height to be filled - * @param[in] srcx, srcy The bitmap position to start the fill from - * @param[in] srccx The width of a line in the bitmap. - * @param[in] buffer The pixels to use to fill the area. - * - * @notapi - */ - void gdisp_lld_blit_area(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) { +#if GDISP_HARDWARE_BITFILLS + void gdisp_lld_blit_area(GDISPDriver *g) { BITMAPV4HEADER bmpInfo; - RECT rect; + HDC dcScreen; + pixel_t * buffer; #if GDISP_NEED_CONTROL - pixel_t *srcimg; + RECT rect; + pixel_t * srcimg; #endif // Make everything relative to the start of the line - buffer += srccx*srcy; - srcy = 0; + buffer = g->p.ptr; + buffer += g->p.x2*g->p.y1; memset(&bmpInfo, 0, sizeof(bmpInfo)); bmpInfo.bV4Size = sizeof(bmpInfo); bmpInfo.bV4Planes = 1; - bmpInfo.bV4BitCount = 32; + bmpInfo.bV4BitCount = sizeof(pixel_t)*8; bmpInfo.bV4AlphaMask = 0; bmpInfo.bV4RedMask = RGB2COLOR(255,0,0); bmpInfo.bV4GreenMask = RGB2COLOR(0,255,0); @@ -508,62 +498,60 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) { bmpInfo.bV4CSType = 0; //LCS_sRGB; #if GDISP_NEED_CONTROL - bmpInfo.bV4SizeImage = (cy*cx) * sizeof(pixel_t); - srcimg = rotateimg(cx, cy, srcx, srccx, buffer); + bmpInfo.bV4SizeImage = (g->p.cy*g->p.cx) * sizeof(pixel_t); + srcimg = rotateimg(g, buffer); if (!srcimg) return; - switch(GC->g.Orientation) { + switch(g->g.Orientation) { case GDISP_ROTATE_0: - bmpInfo.bV4Width = cx; - bmpInfo.bV4Height = -cy; /* top-down image */ - rect.top = y; - rect.bottom = rect.top+cy; - rect.left = x; - rect.right = rect.left+cx; + bmpInfo.bV4Width = g->p.cx; + bmpInfo.bV4Height = -g->p.cy; /* top-down image */ + rect.top = g->p.y; + rect.bottom = rect.top+g->p.cy; + rect.left = g->p.x; + rect.right = rect.left+g->p.cx; break; case GDISP_ROTATE_90: - bmpInfo.bV4Width = cy; - bmpInfo.bV4Height = -cx; /* top-down image */ - rect.top = x; - rect.bottom = rect.top+cx; - rect.right = GC->g.Height - y; - rect.left = rect.right-cy; + bmpInfo.bV4Width = g->p.cy; + bmpInfo.bV4Height = -g->p.cx; /* top-down image */ + rect.bottom = g->g.Width - g->p.x; + rect.top = rect.bottom-g->p.cx; + rect.left = g->p.y; + rect.right = rect.left+g->p.cy; break; case GDISP_ROTATE_180: - bmpInfo.bV4Width = cx; - bmpInfo.bV4Height = -cy; /* top-down image */ - rect.bottom = GC->g.Height - y; - rect.top = rect.bottom-cy; - rect.right = GC->g.Width - x; - rect.left = rect.right-cx; + bmpInfo.bV4Width = g->p.cx; + bmpInfo.bV4Height = -g->p.cy; /* top-down image */ + rect.bottom = g->g.Height-1 - g->p.y; + rect.top = rect.bottom-g->p.cy; + rect.right = g->g.Width - g->p.x; + rect.left = rect.right-g->p.cx; break; case GDISP_ROTATE_270: - bmpInfo.bV4Width = cy; - bmpInfo.bV4Height = -cx; /* top-down image */ - rect.bottom = GC->g.Width - x; - rect.top = rect.bottom-cx; - rect.left = y; - rect.right = rect.left+cy; + bmpInfo.bV4Width = g->p.cy; + bmpInfo.bV4Height = -g->p.cx; /* top-down image */ + rect.top = g->p.x; + rect.bottom = rect.top+g->p.cx; + rect.right = g->g.Height - g->p.y; + rect.left = rect.right-g->p.cy; break; } + dcScreen = GetDC(winRootWindow); SetDIBitsToDevice(dcBuffer, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, srcimg, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS); - if (srcimg != (pixel_t *)buffer) + SetDIBitsToDevice(dcScreen, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, srcimg, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS); + ReleaseDC(winRootWindow, dcScreen); + if (srcimg != buffer) free(srcimg); #else - bmpInfo.bV4Width = srccx; - bmpInfo.bV4Height = -cy; /* top-down image */ - bmpInfo.bV4SizeImage = (cy*srccx) * sizeof(pixel_t); - rect.top = y; - rect.bottom = rect.top+cy; - rect.left = x; - rect.right = rect.left+cx; - SetDIBitsToDevice(dcBuffer, x, y, cx, cy, srcx, 0, 0, cy, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS); + bmpInfo.bV4Width = g->p.x2; + bmpInfo.bV4Height = -g->p.cy; /* top-down image */ + bmpInfo.bV4SizeImage = (g->p.cy*g->p.x2) * sizeof(pixel_t); + dcScreen = GetDC(winRootWindow); + SetDIBitsToDevice(dcBuffer, g->p.x, g->p.y, g->p.cx, g->p.cy, g->p.x1, 0, 0, g->p.cy, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS); + SetDIBitsToDevice(dcScreen, g->p.x, g->p.y, g->p.cx, g->p.cy, g->p.x1, 0, 0, g->p.cy, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS); + ReleaseDC(winRootWindow, dcScreen); #endif - - // Invalidate the region to get it on the screen. - InvalidateRect(winRootWindow, &rect, FALSE); - UpdateWindow(winRootWindow); } #endif @@ -577,13 +565,13 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) { color = GetPixel(dcBuffer, g->p.x, g->p.y); break; case GDISP_ROTATE_90: - color = GetPixel(dcBuffer, g->g.Height - 1 - g->p.y, g->p.x); + color = GetPixel(dcBuffer, g->p.y, g->g.Width - 1 - g->p.x); break; case GDISP_ROTATE_180: color = GetPixel(dcBuffer, g->g.Width - 1 - g->p.x, g->g.Height - 1 - g->p.y); break; case GDISP_ROTATE_270: - color = GetPixel(dcBuffer, g->p.y, g->g.Width - 1 - g->p.x); + color = GetPixel(dcBuffer, g->g.Height - 1 - g->p.y, g->p.x); break; } #else @@ -610,11 +598,11 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) { lines = -g->p.y1; goto vertical_scroll; case GDISP_ROTATE_90: - rect.top = g->p.x; - rect.bottom = rect.top+g->p.cx; - rect.right = g->g.Height - g->p.y; - rect.left = rect.right-g->p.cy; - lines = g->p.y1; + rect.bottom = g->g.Width - g->p.x; + rect.top = rect.bottom-g->p.cx; + rect.left = g->p.y; + rect.right = rect.left+g->p.cy; + lines = -g->p.y1; goto horizontal_scroll; case GDISP_ROTATE_180: rect.bottom = g->g.Height - g->p.y; @@ -636,11 +624,11 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) { } break; case GDISP_ROTATE_270: - rect.bottom = g->g.Width - g->p.x; - rect.top = rect.bottom-g->p.cx; - rect.left = g->p.y; - rect.right = rect.left+g->p.cy; - lines = -g->p.y1; + rect.top = g->p.x; + rect.bottom = rect.top+g->p.cx; + rect.right = g->g.Height - g->p.y; + rect.left = rect.right-g->p.cy; + lines = g->p.y1; horizontal_scroll: if (lines > 0) { rect.right -= lines; @@ -684,17 +672,11 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) { return; switch((orientation_t)g->p.ptr) { case GDISP_ROTATE_0: - g->g.Width = wWidth; - g->g.Height = wHeight; - break; - case GDISP_ROTATE_90: - g->g.Height = wWidth; - g->g.Width = wHeight; - break; case GDISP_ROTATE_180: g->g.Width = wWidth; g->g.Height = wHeight; break; + case GDISP_ROTATE_90: case GDISP_ROTATE_270: g->g.Height = wWidth; g->g.Width = wHeight; diff --git a/drivers/multiple/Win32/gdisp_lld_config.h b/drivers/multiple/Win32/gdisp_lld_config.h index 4a526f07..b8a030ef 100644 --- a/drivers/multiple/Win32/gdisp_lld_config.h +++ b/drivers/multiple/Win32/gdisp_lld_config.h @@ -29,7 +29,7 @@ #define GDISP_HARDWARE_FILLS TRUE #define GDISP_HARDWARE_PIXELREAD TRUE #define GDISP_HARDWARE_CONTROL TRUE -//#define GDISP_HARDWARE_BITFILLS TRUE +#define GDISP_HARDWARE_BITFILLS TRUE #define GDISP_HARDWARE_SCROLL TRUE #define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB888 diff --git a/gfxconf.example.h b/gfxconf.example.h index 65bc97f0..1f7d9c2e 100644 --- a/gfxconf.example.h +++ b/gfxconf.example.h @@ -14,11 +14,11 @@ #ifndef _GFXCONF_H #define _GFXCONF_H -/* The operating system to use - one of these must be defined */ -#define GFX_USE_OS_CHIBIOS FALSE -#define GFX_USE_OS_WIN32 FALSE -#define GFX_USE_OS_LINUX FALSE -#define GFX_USE_OS_OSX FALSE +/* The operating system to use - one of these must be defined - preferably via your makefile */ +//#define GFX_USE_OS_CHIBIOS FALSE +//#define GFX_USE_OS_WIN32 FALSE +//#define GFX_USE_OS_LINUX FALSE +//#define GFX_USE_OS_OSX FALSE /* GFX subsystems to turn on */ #define GFX_USE_GDISP FALSE @@ -37,8 +37,8 @@ #define GDISP_NEED_VALIDATION TRUE #define GDISP_NEED_CLIP TRUE #define GDISP_NEED_TEXT TRUE -#define GDISP_NEED_CIRCLE TRUE -#define GDISP_NEED_ELLIPSE TRUE +#define GDISP_NEED_CIRCLE FALSE +#define GDISP_NEED_ELLIPSE FALSE #define GDISP_NEED_ARC FALSE #define GDISP_NEED_CONVEX_POLYGON FALSE #define GDISP_NEED_SCROLL FALSE @@ -47,13 +47,17 @@ #define GDISP_NEED_QUERY FALSE #define GDISP_NEED_IMAGE FALSE #define GDISP_NEED_MULTITHREAD FALSE -#define GDISP_NEED_ASYNC FALSE -#define GDISP_NEED_MSGAPI FALSE +#define GDISP_NEED_STREAMING FALSE + +/* GDISP - text features */ #define GDISP_NEED_ANTIALIAS FALSE #define GDISP_NEED_UTF8 FALSE #define GDISP_NEED_TEXT_KERNING FALSE /* GDISP - fonts to include */ +#define GDISP_INCLUDE_FONT_UI1 FALSE +#define GDISP_INCLUDE_FONT_UI2 FALSE +#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE #define GDISP_INCLUDE_FONT_DEJAVUSANS10 FALSE #define GDISP_INCLUDE_FONT_DEJAVUSANS12 FALSE #define GDISP_INCLUDE_FONT_DEJAVUSANS16 FALSE @@ -68,10 +72,6 @@ #define GDISP_INCLUDE_FONT_DEJAVUSANS24_AA FALSE #define GDISP_INCLUDE_FONT_DEJAVUSANS32_AA FALSE #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA FALSE - -#define GDISP_INCLUDE_FONT_UI1 FALSE -#define GDISP_INCLUDE_FONT_UI2 FALSE -#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE #define GDISP_INCLUDE_USER_FONTS FALSE /* GDISP image decoders */ @@ -139,12 +139,11 @@ #define GMISC_NEED_ARRAYOPS FALSE #define GMISC_NEED_FASTTRIG FALSE #define GMISC_NEED_FIXEDTRIG FALSE +#define GMISC_NEED_INVSQRT FALSE /* Optional Parameters for various subsystems */ /* - #define GDISP_NEED_UTF8 FALSE - #define GDISP_NEED_TEXT_KERNING FALSE - #define GDISP_NEED_ANTIALIAS FALSE + #define GDISP_LINEBUF_SIZE 128 #define GEVENT_MAXIMUM_SIZE 32 #define GEVENT_MAX_SOURCE_LISTENERS 32 #define GTIMER_THREAD_WORKAREA_SIZE 512 diff --git a/include/gdisp/gdisp.h b/include/gdisp/gdisp.h index cb98b46d..6b2f5b47 100644 --- a/include/gdisp/gdisp.h +++ b/include/gdisp/gdisp.h @@ -430,6 +430,58 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, */ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color); +/* Streaming Functions */ + +#if GDISP_NEED_STREAMING || defined(__DOXYGEN__) + /** + * @brief Start a streaming operation. + * @details Stream data to a window on the display sequentially and very fast. + * @note While streaming is in operation - no other calls to GDISP functions + * can be made (with the exception of @p gdispBlendColor() and streaming + * functions). If a call is made (eg in a multi-threaded application) the other + * call is blocked waiting for the streaming operation to finish. + * @note @p gdispStreamStop() must be called to finish the streaming operation. + * @note If more data is written than the defined area then the results are unspecified. + * Some drivers may wrap back to the beginning of the area, others may just + * ignore subsequent data. + * @note Unlike most operations that clip the defined area to the display to generate + * a smaller active area, this call will just silently fail if any of the stream + * region lies outside the current clipping area. + * @note A streaming operation may be terminated early (without writing to every location + * in the stream area) by calling @p gdispStreamStop(). + * + * @param[in] x,y The start position + * @param[in] cx,cy The size of the streamable area + * + * @api + */ + void gdispStreamStart(coord_t x, coord_t y, coord_t cx, coord_t cy); + + /** + * @brief Send pixel data to the stream. + * @details Write a pixel to the next position in the streamed area and increment the position + * @pre @p gdispStreamStart() has been called. + * @note If the gdispStreamStart() has not been called (or failed due to clipping), the + * data provided here is simply thrown away. + * + * @param[in] color The color of the pixel to write + * + * @api + */ + void gdispStreamColor(color_t color); + + /** + * @brief Finish the current streaming operation. + * @details Completes the current streaming operation and allows other GDISP calls to operate again. + * @pre @p gdispStreamStart() has been called. + * @note If the gdispStreamStart() has not been called (or failed due to clipping), this + * call is simply ignored. + * + * @api + */ + void gdispStreamStop(void); +#endif + /* Clipping Functions */ #if GDISP_NEED_CLIP || defined(__DOXYGEN__) diff --git a/include/gdisp/lld/gdisp_lld.h b/include/gdisp/lld/gdisp_lld.h index 38c0ccc0..3698efb0 100644 --- a/include/gdisp/lld/gdisp_lld.h +++ b/include/gdisp/lld/gdisp_lld.h @@ -184,7 +184,7 @@ typedef struct GDISPDriver { } GDISPDriver; -#if !GDISP_MULTIPLE_DRIVERS || defined(GDISP_LLD_DECLARATIONS) +#if !GDISP_MULTIPLE_DRIVERS || defined(GDISP_LLD_DECLARATIONS) || defined(__DOXYGEN__) #if GDISP_MULTIPLE_DRIVERS #define LLDSPEC static #else @@ -203,7 +203,7 @@ typedef struct GDISPDriver { */ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g); - #if GDISP_HARDWARE_STREAM + #if GDISP_HARDWARE_STREAM || defined(__DOXYGEN__) /** * @brief Start a streamed operation * @pre GDISP_HARDWARE_STREAM is TRUE @@ -228,7 +228,7 @@ typedef struct GDISPDriver { */ LLDSPEC void gdisp_lld_stream_color(GDISPDriver *g); - #if GDISP_HARDWARE_STREAM_READ + #if GDISP_HARDWARE_STREAM_READ || defined(__DOXYGEN__) /** * @brief Read a pixel from the current streaming position and then increment that position * @return The color at the current position @@ -241,7 +241,7 @@ typedef struct GDISPDriver { LLDSPEC color_t gdisp_lld_stream_read(GDISPDriver *g); #endif - #if GDISP_HARDWARE_STREAM_END + #if GDISP_HARDWARE_STREAM_END || defined(__DOXYGEN__) /** * @brief End the current streaming operation * @pre GDISP_HARDWARE_STREAM and GDISP_HARDWARE_STREAM_END is TRUE @@ -254,7 +254,7 @@ typedef struct GDISPDriver { #endif #endif - #if GDISP_HARDWARE_DRAWPIXEL + #if GDISP_HARDWARE_DRAWPIXEL || defined(__DOXYGEN__) /** * @brief Draw a pixel * @pre GDISP_HARDWARE_DRAWPIXEL is TRUE @@ -268,7 +268,7 @@ typedef struct GDISPDriver { LLDSPEC void gdisp_lld_draw_pixel(GDISPDriver *g); #endif - #if GDISP_HARDWARE_CLEARS + #if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__) /** * @brief Clear the screen using the defined color * @pre GDISP_HARDWARE_CLEARS is TRUE @@ -281,7 +281,7 @@ typedef struct GDISPDriver { LLDSPEC void gdisp_lld_clear(GDISPDriver *g); #endif - #if GDISP_HARDWARE_FILLS + #if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__) /** * @brief Fill an area with a single color * @pre GDISP_HARDWARE_FILLS is TRUE @@ -296,7 +296,7 @@ typedef struct GDISPDriver { LLDSPEC void gdisp_lld_fill_area(GDISPDriver *g); #endif - #if GDISP_HARDWARE_BITFILLS + #if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__) /** * @brief Fill an area using a bitmap * @pre GDISP_HARDWARE_BITFILLS is TRUE @@ -313,7 +313,7 @@ typedef struct GDISPDriver { LLDSPEC void gdisp_lld_blit_area(GDISPDriver *g); #endif - #if GDISP_HARDWARE_PIXELREAD + #if GDISP_HARDWARE_PIXELREAD || defined(__DOXYGEN__) /** * @brief Read a pixel from the display * @return The color at the defined position @@ -327,7 +327,7 @@ typedef struct GDISPDriver { LLDSPEC color_t gdisp_lld_get_pixel_color(GDISPDriver *g); #endif - #if GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL + #if (GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL) || defined(__DOXYGEN__) /** * @brief Scroll an area of the screen * @pre GDISP_HARDWARE_SCROLL is TRUE (and the application needs it) @@ -346,7 +346,7 @@ typedef struct GDISPDriver { LLDSPEC void gdisp_lld_vertical_scroll(GDISPDriver *g); #endif - #if GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL + #if (GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL) || defined(__DOXYGEN__) /** * @brief Control some feature of the hardware * @pre GDISP_HARDWARE_CONTROL is TRUE (and the application needs it) @@ -360,7 +360,7 @@ typedef struct GDISPDriver { LLDSPEC void gdisp_lld_control(GDISPDriver *g); #endif - #if GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY + #if (GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY) || defined(__DOXYGEN__) /** * @brief Query some feature of the hardware * @return The information requested (typecast as void *) @@ -374,7 +374,7 @@ typedef struct GDISPDriver { LLDSPEC void *gdisp_lld_query(GDISPDriver *g); // Uses p.x (=what); #endif - #if GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION) + #if (GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)) || defined(__DOXYGEN__) /** * @brief Set the hardware clipping area * @pre GDISP_HARDWARE_CLIP is TRUE (and the application needs it) diff --git a/include/gmisc/gmisc.h b/include/gmisc/gmisc.h index 5943e642..ff3d0c76 100644 --- a/include/gmisc/gmisc.h +++ b/include/gmisc/gmisc.h @@ -184,6 +184,23 @@ extern "C" { /** @} */ #endif +#if GMISC_NEED_INVSQRT + /** + * @brief Fast inverse square root function (x^-1/2) + * @return The approximate inverse square root + * + * @param[in] n The number to find the inverse square root of + * + * @note This function generates an approximate result. Higher accuracy (at the expense + * of speed) can be obtained by modifying the source code (the necessary line + * is already there - just commented out). + * @note This function relies on the internal machine format of a float and a long. + * If your machine architecture is very unusual this function may not work. + * + * @api + */ + float invsqrt(float n); +#endif #ifdef __cplusplus } #endif diff --git a/include/gmisc/options.h b/include/gmisc/options.h index d5cf5898..73b41800 100644 --- a/include/gmisc/options.h +++ b/include/gmisc/options.h @@ -27,13 +27,6 @@ #ifndef GMISC_NEED_ARRAYOPS #define GMISC_NEED_ARRAYOPS FALSE #endif - /** - * @brief Include fast array based trig functions (sin, cos) - * @details Defaults to FALSE - */ - #ifndef GMISC_NEED_FASTTRIG - #define GMISC_NEED_FASTTRIG FALSE - #endif /** * @brief Include fast fixed point trig functions (sin, cos) * @details Defaults to FALSE @@ -41,6 +34,13 @@ #ifndef GMISC_NEED_FIXEDTRIG #define GMISC_NEED_FIXEDTRIG FALSE #endif + /** + * @brief Include fast inverse square root (x^-1/2) + * @details Defaults to FALSE + */ + #ifndef GMISC_NEED_INVSQRT + #define GMISC_NEED_INVSQRT FALSE + #endif /** * @} * diff --git a/src/gdisp/gdisp.c b/src/gdisp/gdisp.c index 25c2621d..8ec2c998 100644 --- a/src/gdisp/gdisp.c +++ b/src/gdisp/gdisp.c @@ -367,7 +367,7 @@ void _gdispInit(void) { #if NEED_CLIPPING // Test if the area is valid - if not then exit - if (x < GC->clipx0 || x+cx >= GC->clipx1 || y < GC->clipy0 || y+cy >= GC->clipy1) { + if (x < GC->clipx0 || x+cx > GC->clipx1 || y < GC->clipy0 || y+cy > GC->clipy1) { MUTEX_EXIT(); return; } @@ -398,7 +398,7 @@ void _gdispInit(void) { void gdispStreamColor(color_t color) { #if !GDISP_HARDWARE_STREAM && GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS - coord_t pos, sx1, sy1, sx2; + coord_t sx1, sy1, sx2; #endif // Don't touch the mutex as we should already own it @@ -413,48 +413,45 @@ void _gdispInit(void) { gdisp_lld_stream_color(GC); #elif GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS GC->linebuf[GC->p.cx++] = color; + GC->p.x++; if (GC->p.cx >= GDISP_LINEBUF_SIZE) { - pos = GC->p.cx; sx1 = GC->p.x1; sy1 = GC->p.y1; - sx2 = GC->p.x2; - GC->p.x -= pos; - GC->p.cx = pos; + //sx2 = GC->p.x2; + GC->p.x -= GC->p.cx; GC->p.cy = 1; GC->p.x1 = 0; GC->p.y1 = 0; - GC->p.x2 = pos; + //GC->p.x2 = GC->p.cx; GC->p.ptr = (void *)GC->linebuf; gdisp_lld_blit_area(GC); GC->p.x1 = sx1; GC->p.y1 = sy1; - GC->p.x2 = sx2; - GC->p.x += pos; + //GC->p.x2 = sx2; + GC->p.x += GC->p.cx; GC->p.cx = 0; } // Just wrap at end-of-line and end-of-buffer - if (++GC->p.x >= GC->p.x2) { + if (GC->p.x >= GC->p.x2) { if (GC->p.cx) { - pos = GC->p.cx; sx1 = GC->p.x1; sy1 = GC->p.y1; - sx2 = GC->p.x2; - GC->p.x -= pos; - GC->p.cx = pos; + //sx2 = GC->p.x2; + GC->p.x -= GC->p.cx; GC->p.cy = 1; GC->p.x1 = 0; GC->p.y1 = 0; - GC->p.x2 = pos; + //GC->p.x2 = GC->p.cx; GC->p.ptr = (void *)GC->linebuf; gdisp_lld_blit_area(GC); GC->p.x1 = sx1; GC->p.y1 = sy1; - GC->p.x2 = sx2; + //GC->p.x2 = sx2; GC->p.cx = 0; } GC->p.x = GC->p.x1; - if (++GC->p.y >= GC->p.x2) + if (++GC->p.y >= GC->p.y2) GC->p.y = GC->p.y1; } #else @@ -465,13 +462,13 @@ void _gdispInit(void) { // Just wrap at end-of-line and end-of-buffer if (++GC->p.x >= GC->p.x2) { GC->p.x = GC->p.x1; - if (++GC->p.y >= GC->p.x2) + if (++GC->p.y >= GC->p.y2) GC->p.y = GC->p.y1; } #endif } - void gdispStreamEnd(void) { + void gdispStreamStop(void) { // Only release the mutex and end the stream if we are actually streaming. if (!(GC->flags & GDISP_FLG_INSTREAM)) return; @@ -486,7 +483,7 @@ void _gdispInit(void) { GC->p.cy = 1; GC->p.x1 = 0; GC->p.y1 = 0; - GC->p.x2 = GC->p.cx; + //GC->p.x2 = GC->p.cx; GC->p.ptr = (void *)GC->linebuf; gdisp_lld_blit_area(GC); }