aboutsummaryrefslogtreecommitdiffstats
path: root/src/gdisp/gdisp_gdisp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gdisp/gdisp_gdisp.c')
-rw-r--r--src/gdisp/gdisp_gdisp.c111
1 files changed, 43 insertions, 68 deletions
diff --git a/src/gdisp/gdisp_gdisp.c b/src/gdisp/gdisp_gdisp.c
index a34788b2..0e5cacb5 100644
--- a/src/gdisp/gdisp_gdisp.c
+++ b/src/gdisp/gdisp_gdisp.c
@@ -566,45 +566,24 @@ static void line_clip(GDisplay *g) {
void _gdispInit(void)
{
- // Both GDISP_CONTROLLER_LIST and GDISP_CONTROLLER_DISPLAYS are defined - create the required numbers of each controller
- #if defined(GDISP_CONTROLLER_LIST) && defined(GDISP_CONTROLLER_DISPLAYS)
- {
- int i, cnt;
-
- extern GDriverVMTList GDISP_CONTROLLER_LIST;
- static const struct GDriverVMT const * dclist[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_LIST};
- static const unsigned dnlist[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_DISPLAYS};
-
- for(i = 0; i < GDISP_TOTAL_CONTROLLERS; i++) {
- for(cnt = dnlist[i]; cnt; cnt--)
- gdriverRegister(dclist[i]);
- }
- }
-
- // Only GDISP_CONTROLLER_LIST is defined - create one of each controller
- #elif defined(GDISP_CONTROLLER_LIST)
+ // GDISP_DRIVER_LIST is defined - create each driver instance
+ #if defined(GDISP_DRIVER_LIST)
{
int i;
- extern GDriverVMTList GDISP_CONTROLLER_LIST;
- static const struct GDriverVMT const * dclist[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_LIST};
+ extern GDriverVMTList GDISP_DRIVER_LIST;
+ static const struct GDriverVMT const * dclist[] = {GDISP_DRIVER_LIST};
- for(i = 0; i < GDISP_TOTAL_CONTROLLERS; i++)
+ for(i = 0; i < sizeof(dclist)/sizeof(dclist[0]); i++)
gdriverRegister(dclist[i]);
}
-
- // Only GDISP_TOTAL_DISPLAYS is defined - create the required number of the one controller
#elif GDISP_TOTAL_DISPLAYS > 1
{
- int cnt;
-
- extern GDriverVMTList GDISPVMT_OnlyOne;
+ int i;
- for(cnt = 0; cnt < GDISP_TOTAL_DISPLAYS; cnt++)
+ for(i = 0; i < GDISP_TOTAL_DISPLAYS; i++)
gdriverRegister(GDISPVMT_OnlyOne);
}
-
- // One and only one display
#else
{
extern GDriverVMTList GDISPVMT_OnlyOne;
@@ -715,10 +694,6 @@ void _gdispDeInitDriver(GDriver *g) {
#undef gd
}
-GDisplay *gdispGetDisplay(unsigned display) {
- return (GDisplay *)gdriverGetInstance(GDRIVER_TYPE_DISPLAY, display);
-}
-
void gdispSetDisplay(GDisplay *g) {
if (g) GDISP = g;
}
@@ -1001,7 +976,7 @@ void gdispGDrawPixel(GDisplay *g, coord_t x, coord_t y, color_t color) {
autoflush(g);
MUTEX_EXIT(g);
}
-
+
void gdispGDrawLine(GDisplay *g, coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color) {
MUTEX_ENTER(g);
g->p.x = x0;
@@ -1110,7 +1085,7 @@ void gdispGFillArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, c
autoflush_stopdone(g);
MUTEX_EXIT(g);
}
-
+
void gdispGBlitArea(GDisplay *g, 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) {
MUTEX_ENTER(g);
@@ -1246,7 +1221,7 @@ void gdispGBlitArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, c
}
#endif
}
-
+
#if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
void gdispGSetClip(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy) {
MUTEX_ENTER(g);
@@ -1400,7 +1375,7 @@ void gdispGBlitArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, c
MUTEX_EXIT(g);
}
#endif
-
+
#if GDISP_NEED_ELLIPSE
void gdispGFillEllipse(GDisplay *g, coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
coord_t dx, dy;
@@ -2662,7 +2637,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
}
}
}
-
+
static int32_t rounding_div(const int32_t n, const int32_t d)
{
if ((n < 0) != (d < 0))
@@ -2670,23 +2645,23 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
else
return (n + d/2) / d;
}
-
+
/* Find a vector (nx, ny) that is perpendicular to (dx, dy) and has length
* equal to 'norm'. */
static void get_normal_vector(coord_t dx, coord_t dy, coord_t norm, coord_t *nx, coord_t *ny)
{
int32_t dx2, dy2, len_sq, norm_sq, norm_sq2;
int div, step, best, delta, abs_delta;
-
+
dx2 = dx; dy2 = dy;
norm_sq = (int32_t)norm * norm;
norm_sq2 = norm_sq * 512;
-
+
/* Scale dx2 and dy2 so that
* len_sq / 2 <= norm_sq * 512 <= len_sq * 2.
* The scaling by 512 is to yield higher accuracy in division later. */
len_sq = dx2 * dx2 + dy2 * dy2;
-
+
if (len_sq < norm_sq2)
{
while (len_sq && len_sq < norm_sq2)
@@ -2701,69 +2676,69 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
len_sq >>= 2; dx2 >>= 1; dy2 >>= 1;
}
}
-
+
/* Now find the divider div so that
* len_sq / div^2 == norm_sq i.e. div = sqrt(len_sq / norm_sq)
*
* This is done using bisection search to avoid the need for floating
* point sqrt.
- *
+ *
* Based on previous scaling, we know that
* len_sq / 2 <= norm_sq * 512 <=> div <= sqrt(1024) = 32
* len_sq * 2 >= norm_sq * 512 <=> div >= sqrt(256) = 16
*/
div = 24; step = 8;
best = 256;
-
+
for (;;)
{
dx = dx2 / div;
dy = dy2 / div;
len_sq = dx*dx + dy*dy;
-
+
delta = len_sq - norm_sq;
-
+
abs_delta = (delta >= 0) ? delta : -delta;
-
+
if (abs_delta < best)
{
*nx = dy;
*ny = -dx;
best = abs_delta;
}
-
+
if (delta > 0)
div += step;
else if (delta < 0)
div -= step;
else if (delta == 0)
break;
-
+
if (step == 0)
break;
else
step >>= 1; /* Do one round with step = 0 to calculate final result. */
}
}
-
+
void gdispGDrawThickLine(GDisplay *g, coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color, coord_t width, bool_t round) {
coord_t dx, dy, nx = 0, ny = 0;
-
+
/* Compute the direction vector for the line */
dx = x1 - x0;
dy = y1 - y0;
-
+
/* Draw a small dot if the line length is zero. */
if (dx == 0 && dy == 0)
dx += 1;
-
+
/* Compute a normal vector with length 'width'. */
get_normal_vector(dx, dy, width, &nx, &ny);
-
+
/* Handle 1px wide lines gracefully */
if (nx == 0 && ny == 0)
nx = 1;
-
+
/* Offset the x0,y0 by half the width of the line. This way we
* can keep the width of the line accurate even if it is not evenly
* divisible by 2.
@@ -2772,11 +2747,11 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
x0 -= rounding_div(nx, 2);
y0 -= rounding_div(ny, 2);
}
-
+
/* Fill in the point array */
if (!round) {
/* We use 4 points for the basic line shape:
- *
+ *
* pt1 pt2
* (+n) ------------------------------------ (d+n)
* | |
@@ -2784,7 +2759,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
* pt0 pt3
*/
point pntarray[4];
-
+
pntarray[0].x = 0;
pntarray[0].y = 0;
pntarray[1].x = nx;
@@ -2793,7 +2768,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
pntarray[2].y = dy + ny;
pntarray[3].x = dx;
pntarray[3].y = dy;
-
+
gdispGFillConvexPoly(g, x0, y0, pntarray, 4, color);
} else {
/* We use 4 points for basic shape, plus 4 extra points for ends:
@@ -2808,26 +2783,26 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
*/
point pntarray[8];
coord_t nx2, ny2;
-
+
/* Magic numbers:
* 75/256 = sin(45) / (1 + sqrt(2)) diagonal octagon segments
* 106/256 = 1 / (1 + sqrt(2)) octagon side
* 53/256 = 0.5 / (1 + sqrt(2)) half of octagon side
* 150/256 = 1 - 1 / (1 + sqrt(2)) octagon height minus one side
*/
-
+
/* Rotate the normal vector 45 deg counter-clockwise and reduce
* to 1 / (1 + sqrt(2)) length, for forming octagonal ends. */
nx2 = rounding_div((nx * 75 + ny * 75), 256);
ny2 = rounding_div((-nx * 75 + ny * 75), 256);
-
+
/* Offset and extend the line so that the center of the octagon
* is at the specified points. */
x0 += ny * 53 / 256;
y0 -= nx * 53 / 256;
dx -= ny * 106 / 256;
dy += nx * 106 / 256;
-
+
/* Now fill in the points by summing the calculated vectors. */
pntarray[0].x = 0;
pntarray[0].y = 0;
@@ -2845,7 +2820,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
pntarray[6].y = dy + ny * 150/256 - ny2;
pntarray[7].x = dx;
pntarray[7].y = dy;
-
+
gdispGFillConvexPoly(g, x0, y0, pntarray, 8, color);
}
}
@@ -3099,19 +3074,19 @@ color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha)
uint16_t fg_ratio = alpha + 1;
uint16_t bg_ratio = 256 - alpha;
uint16_t r, g, b;
-
+
r = RED_OF(fg) * fg_ratio;
g = GREEN_OF(fg) * fg_ratio;
b = BLUE_OF(fg) * fg_ratio;
-
+
r += RED_OF(bg) * bg_ratio;
g += GREEN_OF(bg) * bg_ratio;
b += BLUE_OF(bg) * bg_ratio;
-
+
r >>= 8;
g >>= 8;
b >>= 8;
-
+
return RGB2COLOR(r, g, b);
}