summaryrefslogtreecommitdiff
path: root/src/sdl2gfx/SDL_gfxPrimitives.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sdl2gfx/SDL_gfxPrimitives.c')
-rw-r--r--src/sdl2gfx/SDL_gfxPrimitives.c4295
1 files changed, 0 insertions, 4295 deletions
diff --git a/src/sdl2gfx/SDL_gfxPrimitives.c b/src/sdl2gfx/SDL_gfxPrimitives.c
deleted file mode 100644
index f2115ce99..000000000
--- a/src/sdl2gfx/SDL_gfxPrimitives.c
+++ /dev/null
@@ -1,4295 +0,0 @@
-/*
-
-SDL2_gfxPrimitives.c: graphics primitives for SDL2 renderers
-
-Copyright (C) 2012 Andreas Schiffler
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of this software.
-
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must not
-claim that you wrote the original software. If you use this software
-in a product, an acknowledgment in the product documentation would be
-appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and must not be
-misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source
-distribution.
-
-Andreas Schiffler -- aschiffler at ferzkopp dot net
-
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-
-#include "SDL_gfxPrimitives.h"
-#include "SDL_rotozoom.h"
-#include "SDL_gfxPrimitives_font.h"
-
-/* ---- Structures */
-
-/*!
-\brief The structure passed to the internal Bresenham iterator.
-*/
-typedef struct {
- Sint16 x, y;
- int dx, dy, s1, s2, swapdir, error;
- Uint32 count;
-} SDL2_gfxBresenhamIterator;
-
-/*!
-\brief The structure passed to the internal Murphy iterator.
-*/
-typedef struct {
- SDL_Renderer *renderer;
- int u, v; /* delta x , delta y */
- int ku, kt, kv, kd; /* loop constants */
- int oct2;
- int quad4;
- Sint16 last1x, last1y, last2x, last2y, first1x, first1y, first2x, first2y, tempx, tempy;
-} SDL2_gfxMurphyIterator;
-
-/* ---- Pixel */
-
-/*!
-\brief Draw pixel in currently set color.
-
-\param renderer The renderer to draw on.
-\param x X (horizontal) coordinate of the pixel.
-\param y Y (vertical) coordinate of the pixel.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int pixel(SDL_Renderer *renderer, Sint16 x, Sint16 y)
-{
- return SDL_RenderDrawPoint(renderer, x, y);
-}
-
-/*!
-\brief Draw pixel with blending enabled if a<255.
-
-\param renderer The renderer to draw on.
-\param x X (horizontal) coordinate of the pixel.
-\param y Y (vertical) coordinate of the pixel.
-\param color The color value of the pixel to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int pixelColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return pixelRGBA(renderer, x, y, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw pixel with blending enabled if a<255.
-
-\param renderer The renderer to draw on.
-\param x X (horizontal) coordinate of the pixel.
-\param y Y (vertical) coordinate of the pixel.
-\param r The red color value of the pixel to draw.
-\param g The green color value of the pixel to draw.
-\param b The blue color value of the pixel to draw.
-\param a The alpha value of the pixel to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int pixelRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result = 0;
- result |= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND);
- result |= SDL_SetRenderDrawColor(renderer, r, g, b, a);
- result |= SDL_RenderDrawPoint(renderer, x, y);
- return result;
-}
-
-/*!
-\brief Draw pixel with blending enabled and using alpha weight on color.
-
-\param renderer The renderer to draw on.
-\param x The horizontal coordinate of the pixel.
-\param y The vertical position of the pixel.
-\param r The red color value of the pixel to draw.
-\param g The green color value of the pixel to draw.
-\param b The blue color value of the pixel to draw.
-\param a The alpha value of the pixel to draw.
-\param weight The weight multiplied into the alpha value of the pixel.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int pixelRGBAWeight(SDL_Renderer * renderer, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Uint32 weight)
-{
- /*
- * Modify Alpha by weight
- */
- Uint32 ax = a;
- ax = ((ax * weight) >> 8);
- if (ax > 255) {
- a = 255;
- } else {
- a = (Uint8)(ax & 0x000000ff);
- }
-
- return pixelRGBA(renderer, x, y, r, g, b, a);
-}
-
-/* ---- Hline */
-
-/*!
-\brief Draw horizontal line in currently set color
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point (i.e. left) of the line.
-\param x2 X coordinate of the second point (i.e. right) of the line.
-\param y Y coordinate of the points of the line.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int hline(SDL_Renderer * renderer, Sint16 x1, Sint16 x2, Sint16 y)
-{
- return SDL_RenderDrawLine(renderer, x1, y, x2, y);;
-}
-
-
-/*!
-\brief Draw horizontal line with blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point (i.e. left) of the line.
-\param x2 X coordinate of the second point (i.e. right) of the line.
-\param y Y coordinate of the points of the line.
-\param color The color value of the line to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int hlineColor(SDL_Renderer * renderer, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return hlineRGBA(renderer, x1, x2, y, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw horizontal line with blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point (i.e. left) of the line.
-\param x2 X coordinate of the second point (i.e. right) of the line.
-\param y Y coordinate of the points of the line.
-\param r The red value of the line to draw.
-\param g The green value of the line to draw.
-\param b The blue value of the line to draw.
-\param a The alpha value of the line to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int hlineRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result = 0;
- result |= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND);
- result |= SDL_SetRenderDrawColor(renderer, r, g, b, a);
- result |= SDL_RenderDrawLine(renderer, x1, y, x2, y);
- return result;
-}
-
-/* ---- Vline */
-
-/*!
-\brief Draw vertical line with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the points of the line.
-\param y1 Y coordinate of the first point (i.e. top) of the line.
-\param y2 Y coordinate of the second point (i.e. bottom) of the line.
-\param color The color value of the line to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int vlineColor(SDL_Renderer * renderer, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return vlineRGBA(renderer, x, y1, y2, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw vertical line with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the points of the line.
-\param y1 Y coordinate of the first point (i.e. top) of the line.
-\param y2 Y coordinate of the second point (i.e. bottom) of the line.
-\param r The red value of the line to draw.
-\param g The green value of the line to draw.
-\param b The blue value of the line to draw.
-\param a The alpha value of the line to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int vlineRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y1, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result = 0;
- result |= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND);
- result |= SDL_SetRenderDrawColor(renderer, r, g, b, a);
- result |= SDL_RenderDrawLine(renderer, x, y1, x, y2);
- return result;
-}
-
-/* ---- Rectangle */
-
-/*!
-\brief Draw rectangle with blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point (i.e. top right) of the rectangle.
-\param y1 Y coordinate of the first point (i.e. top right) of the rectangle.
-\param x2 X coordinate of the second point (i.e. bottom left) of the rectangle.
-\param y2 Y coordinate of the second point (i.e. bottom left) of the rectangle.
-\param color The color value of the rectangle to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int rectangleColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return rectangleRGBA(renderer, x1, y1, x2, y2, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw rectangle with blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point (i.e. top right) of the rectangle.
-\param y1 Y coordinate of the first point (i.e. top right) of the rectangle.
-\param x2 X coordinate of the second point (i.e. bottom left) of the rectangle.
-\param y2 Y coordinate of the second point (i.e. bottom left) of the rectangle.
-\param r The red value of the rectangle to draw.
-\param g The green value of the rectangle to draw.
-\param b The blue value of the rectangle to draw.
-\param a The alpha value of the rectangle to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int rectangleRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result;
- Sint16 tmp;
- SDL_Rect rect;
-
- /*
- * Test for special cases of straight lines or single point
- */
- if (x1 == x2) {
- if (y1 == y2) {
- return (pixelRGBA(renderer, x1, y1, r, g, b, a));
- } else {
- return (vlineRGBA(renderer, x1, y1, y2, r, g, b, a));
- }
- } else {
- if (y1 == y2) {
- return (hlineRGBA(renderer, x1, x2, y1, r, g, b, a));
- }
- }
-
- /*
- * Swap x1, x2 if required
- */
- if (x1 > x2) {
- tmp = x1;
- x1 = x2;
- x2 = tmp;
- }
-
- /*
- * Swap y1, y2 if required
- */
- if (y1 > y2) {
- tmp = y1;
- y1 = y2;
- y2 = tmp;
- }
-
- /*
- * Create destination rect
- */
- rect.x = x1;
- rect.y = y1;
- rect.w = x2 - x1;
- rect.h = y2 - y1;
-
- /*
- * Draw
- */
- result = 0;
- result |= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND);
- result |= SDL_SetRenderDrawColor(renderer, r, g, b, a);
- result |= SDL_RenderDrawRect(renderer, &rect);
- return result;
-}
-
-/* ---- Rounded Rectangle */
-
-/*!
-\brief Draw rounded-corner rectangle with blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point (i.e. top right) of the rectangle.
-\param y1 Y coordinate of the first point (i.e. top right) of the rectangle.
-\param x2 X coordinate of the second point (i.e. bottom left) of the rectangle.
-\param y2 Y coordinate of the second point (i.e. bottom left) of the rectangle.
-\param rad The radius of the corner arc.
-\param color The color value of the rectangle to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int roundedRectangleColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 rad, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return roundedRectangleRGBA(renderer, x1, y1, x2, y2, rad, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw rounded-corner rectangle with blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point (i.e. top right) of the rectangle.
-\param y1 Y coordinate of the first point (i.e. top right) of the rectangle.
-\param x2 X coordinate of the second point (i.e. bottom left) of the rectangle.
-\param y2 Y coordinate of the second point (i.e. bottom left) of the rectangle.
-\param rad The radius of the corner arc.
-\param r The red value of the rectangle to draw.
-\param g The green value of the rectangle to draw.
-\param b The blue value of the rectangle to draw.
-\param a The alpha value of the rectangle to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int roundedRectangleRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result = 0;
- Sint16 tmp;
- Sint16 w, h;
- Sint16 xx1, xx2;
- Sint16 yy1, yy2;
-
- /*
- * Check renderer
- */
- if (renderer == NULL)
- {
- return -1;
- }
-
- /*
- * Check radius vor valid range
- */
- if (rad < 0) {
- return -1;
- }
-
- /*
- * Special case - no rounding
- */
- if (rad == 0) {
- return rectangleRGBA(renderer, x1, y1, x2, y2, r, g, b, a);
- }
-
- /*
- * Test for special cases of straight lines or single point
- */
- if (x1 == x2) {
- if (y1 == y2) {
- return (pixelRGBA(renderer, x1, y1, r, g, b, a));
- } else {
- return (vlineRGBA(renderer, x1, y1, y2, r, g, b, a));
- }
- } else {
- if (y1 == y2) {
- return (hlineRGBA(renderer, x1, x2, y1, r, g, b, a));
- }
- }
-
- /*
- * Swap x1, x2 if required
- */
- if (x1 > x2) {
- tmp = x1;
- x1 = x2;
- x2 = tmp;
- }
-
- /*
- * Swap y1, y2 if required
- */
- if (y1 > y2) {
- tmp = y1;
- y1 = y2;
- y2 = tmp;
- }
-
- /*
- * Calculate width&height
- */
- w = x2 - x1;
- h = y2 - y1;
-
- /*
- * Maybe adjust radius
- */
- if ((rad * 2) > w)
- {
- rad = w / 2;
- }
- if ((rad * 2) > h)
- {
- rad = h / 2;
- }
-
- /*
- * Draw corners
- */
- xx1 = x1 + rad;
- xx2 = x2 - rad;
- yy1 = y1 + rad;
- yy2 = y2 - rad;
- result |= arcRGBA(renderer, xx1, yy1, rad, 180, 270, r, g, b, a);
- result |= arcRGBA(renderer, xx2, yy1, rad, 270, 360, r, g, b, a);
- result |= arcRGBA(renderer, xx1, yy2, rad, 90, 180, r, g, b, a);
- result |= arcRGBA(renderer, xx2, yy2, rad, 0, 90, r, g, b, a);
-
- /*
- * Draw lines
- */
- if (xx1 <= xx2) {
- result |= hlineRGBA(renderer, xx1, xx2, y1, r, g, b, a);
- result |= hlineRGBA(renderer, xx1, xx2, y2, r, g, b, a);
- }
- if (yy1 <= yy2) {
- result |= vlineRGBA(renderer, x1, yy1, yy2, r, g, b, a);
- result |= vlineRGBA(renderer, x2, yy1, yy2, r, g, b, a);
- }
-
- return result;
-}
-
-/* ---- Rounded Box */
-
-/*!
-\brief Draw rounded-corner box (filled rectangle) with blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point (i.e. top right) of the box.
-\param y1 Y coordinate of the first point (i.e. top right) of the box.
-\param x2 X coordinate of the second point (i.e. bottom left) of the box.
-\param y2 Y coordinate of the second point (i.e. bottom left) of the box.
-\param rad The radius of the corner arcs of the box.
-\param color The color value of the box to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int roundedBoxColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 rad, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return roundedBoxRGBA(renderer, x1, y1, x2, y2, rad, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw rounded-corner box (filled rectangle) with blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point (i.e. top right) of the box.
-\param y1 Y coordinate of the first point (i.e. top right) of the box.
-\param x2 X coordinate of the second point (i.e. bottom left) of the box.
-\param y2 Y coordinate of the second point (i.e. bottom left) of the box.
-\param rad The radius of the corner arcs of the box.
-\param r The red value of the box to draw.
-\param g The green value of the box to draw.
-\param b The blue value of the box to draw.
-\param a The alpha value of the box to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int roundedBoxRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2,
- Sint16 y2, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result = 0;
- Sint16 w, h, tmp;
- Sint16 xx1, xx2, yy1, yy2;
-
- /*
- * Check destination renderer
- */
- if (renderer == NULL)
- {
- return -1;
- }
-
- /*
- * Check radius vor valid range
- */
- if (rad < 0) {
- return -1;
- }
-
- /*
- * Special case - no rounding
- */
- if (rad == 0) {
- return rectangleRGBA(renderer, x1, y1, x2, y2, r, g, b, a);
- }
-
- /*
- * Test for special cases of straight lines or single point
- */
- if (x1 == x2) {
- if (y1 == y2) {
- return (pixelRGBA(renderer, x1, y1, r, g, b, a));
- } else {
- return (vlineRGBA(renderer, x1, y1, y2, r, g, b, a));
- }
- } else {
- if (y1 == y2) {
- return (hlineRGBA(renderer, x1, x2, y1, r, g, b, a));
- }
- }
-
- /*
- * Swap x1, x2 if required
- */
- if (x1 > x2) {
- tmp = x1;
- x1 = x2;
- x2 = tmp;
- }
-
- /*
- * Swap y1, y2 if required
- */
- if (y1 > y2) {
- tmp = y1;
- y1 = y2;
- y2 = tmp;
- }
-
- /*
- * Calculate width&height
- */
- w = x2 - x1;
- h = y2 - y1;
-
- /*
- * Maybe adjust radius
- */
- if ((rad * 2) > w)
- {
- rad = w / 2;
- }
- if ((rad * 2) > h)
- {
- rad = h / 2;
- }
-
- /*
- * Draw corners
- */
- xx1 = x1 + rad;
- xx2 = x2 - rad;
- yy1 = y1 + rad;
- yy2 = y2 - rad;
- result |= filledPieRGBA(renderer, xx1, yy1, rad, 180, 270, r, g, b, a);
- result |= filledPieRGBA(renderer, xx2, yy1, rad, 270, 360, r, g, b, a);
- result |= filledPieRGBA(renderer, xx1, yy2, rad, 90, 180, r, g, b, a);
- result |= filledPieRGBA(renderer, xx2, yy2, rad, 0, 90, r, g, b, a);
-
- /*
- * Draw body
- */
- xx1++;
- xx2--;
- yy1++;
- yy2--;
- if (xx1 <= xx2) {
- result |= boxRGBA(renderer, xx1, y1, xx2, y2, r, g, b, a);
- }
- if (yy1 <= yy2) {
- result |= boxRGBA(renderer, x1, yy1, xx1-1, yy2, r, g, b, a);
- result |= boxRGBA(renderer, xx2+1, yy1, x2, yy2, r, g, b, a);
- }
-
- return result;
-}
-
-/* ---- Box */
-
-/*!
-\brief Draw box (filled rectangle) with blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point (i.e. top right) of the box.
-\param y1 Y coordinate of the first point (i.e. top right) of the box.
-\param x2 X coordinate of the second point (i.e. bottom left) of the box.
-\param y2 Y coordinate of the second point (i.e. bottom left) of the box.
-\param color The color value of the box to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int boxColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return boxRGBA(renderer, x1, y1, x2, y2, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw box (filled rectangle) with blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point (i.e. top right) of the box.
-\param y1 Y coordinate of the first point (i.e. top right) of the box.
-\param x2 X coordinate of the second point (i.e. bottom left) of the box.
-\param y2 Y coordinate of the second point (i.e. bottom left) of the box.
-\param r The red value of the box to draw.
-\param g The green value of the box to draw.
-\param b The blue value of the box to draw.
-\param a The alpha value of the box to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int boxRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result;
- Sint16 tmp;
- SDL_Rect rect;
-
- /*
- * Test for special cases of straight lines or single point
- */
- if (x1 == x2) {
- if (y1 == y2) {
- return (pixelRGBA(renderer, x1, y1, r, g, b, a));
- } else {
- return (vlineRGBA(renderer, x1, y1, y2, r, g, b, a));
- }
- } else {
- if (y1 == y2) {
- return (hlineRGBA(renderer, x1, x2, y1, r, g, b, a));
- }
- }
-
- /*
- * Swap x1, x2 if required
- */
- if (x1 > x2) {
- tmp = x1;
- x1 = x2;
- x2 = tmp;
- }
-
- /*
- * Swap y1, y2 if required
- */
- if (y1 > y2) {
- tmp = y1;
- y1 = y2;
- y2 = tmp;
- }
-
- /*
- * Create destination rect
- */
- rect.x = x1;
- rect.y = y1;
- rect.w = x2 - x1;
- rect.h = y2 - y1;
-
- /*
- * Draw
- */
- result = 0;
- result |= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND);
- result |= SDL_SetRenderDrawColor(renderer, r, g, b, a);
- result |= SDL_RenderFillRect(renderer, &rect);
- return result;
-}
-
-/* ----- Line */
-
-/*!
-\brief Draw line with alpha blending using the currently set color.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point of the line.
-\param y1 Y coordinate of the first point of the line.
-\param x2 X coordinate of the second point of the line.
-\param y2 Y coordinate of the second point of the line.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int line(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2)
-{
- /*
- * Draw
- */
- return SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
-}
-
-/*!
-\brief Draw line with alpha blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point of the line.
-\param y1 Y coordinate of the first point of the line.
-\param x2 X coordinate of the second point of the line.
-\param y2 Y coordinate of the seond point of the line.
-\param color The color value of the line to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int lineColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return lineRGBA(renderer, x1, y1, x2, y2, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw line with alpha blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point of the line.
-\param y1 Y coordinate of the first point of the line.
-\param x2 X coordinate of the second point of the line.
-\param y2 Y coordinate of the second point of the line.
-\param r The red value of the line to draw.
-\param g The green value of the line to draw.
-\param b The blue value of the line to draw.
-\param a The alpha value of the line to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int lineRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- /*
- * Draw
- */
- int result = 0;
- result |= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND);
- result |= SDL_SetRenderDrawColor(renderer, r, g, b, a);
- result |= SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
- return result;
-}
-
-/* ---- AA Line */
-
-#define AAlevels 256
-#define AAbits 8
-
-/*!
-\brief Internal function to draw anti-aliased line with alpha blending and endpoint control.
-
-This implementation of the Wu antialiasing code is based on Mike Abrash's
-DDJ article which was reprinted as Chapter 42 of his Graphics Programming
-Black Book, but has been optimized to work with SDL and utilizes 32-bit
-fixed-point arithmetic by A. Schiffler. The endpoint control allows the
-supression to draw the last pixel useful for rendering continous aa-lines
-with alpha<255.
-
-\param dst The surface to draw on.
-\param x1 X coordinate of the first point of the aa-line.
-\param y1 Y coordinate of the first point of the aa-line.
-\param x2 X coordinate of the second point of the aa-line.
-\param y2 Y coordinate of the second point of the aa-line.
-\param r The red value of the aa-line to draw.
-\param g The green value of the aa-line to draw.
-\param b The blue value of the aa-line to draw.
-\param a The alpha value of the aa-line to draw.
-\param draw_endpoint Flag indicating if the endpoint should be drawn; draw if non-zero.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int _aalineRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a, int draw_endpoint)
-{
- Sint32 xx0, yy0, xx1, yy1;
- int result;
- Uint32 intshift, erracc, erradj;
- Uint32 erracctmp, wgt, wgtcompmask;
- int dx, dy, tmp, xdir, y0p1, x0pxdir;
-
- /*
- * Keep on working with 32bit numbers
- */
- xx0 = x1;
- yy0 = y1;
- xx1 = x2;
- yy1 = y2;
-
- /*
- * Reorder points if required
- */
- if (yy0 > yy1) {
- tmp = yy0;
- yy0 = yy1;
- yy1 = tmp;
- tmp = xx0;
- xx0 = xx1;
- xx1 = tmp;
- }
-
- /*
- * Calculate distance
- */
- dx = xx1 - xx0;
- dy = yy1 - yy0;
-
- /*
- * Check for special cases
- */
- if (dx == 0) {
- /*
- * Vertical line
- */
- if (draw_endpoint)
- {
- return (vlineRGBA(renderer, x1, y1, y2, r, g, b, a));
- } else {
- if (dy>0) {
- return (vlineRGBA(renderer, x1, yy0, yy0+dy, r, g, b, a));
- } else {
- return (pixelRGBA(renderer, x1, y1, r, g, b, a));
- }
- }
- } else if (dy == 0) {
- /*
- * Horizontal line
- */
- if (draw_endpoint)
- {
- return (hlineRGBA(renderer, x1, x2, y1, r, g, b, a));
- } else {
- if (dx>0) {
- return (hlineRGBA(renderer, xx0, xx0+dx, y1, r, g, b, a));
- } else {
- return (pixelRGBA(renderer, x1, y1, r, g, b, a));
- }
- }
- } else if ((dx == dy) && (draw_endpoint)) {
- /*
- * Diagonal line (with endpoint)
- */
- return (lineRGBA(renderer, x1, y1, x2, y2, r, g, b, a));
- }
-
- /*
- * Adjust for negative dx and set xdir
- */
- if (dx >= 0) {
- xdir = 1;
- } else {
- xdir = -1;
- dx = (-dx);
- }
-
- /*
- * Line is not horizontal, vertical or diagonal (with endpoint)
- */
- result = 0;
-
- /*
- * Zero accumulator
- */
- erracc = 0;
-
- /*
- * # of bits by which to shift erracc to get intensity level
- */
- intshift = 32 - AAbits;
-
- /*
- * Mask used to flip all bits in an intensity weighting
- */
- wgtcompmask = AAlevels - 1;
-
- /*
- * Draw the initial pixel in the foreground color
- */
- result |= pixelRGBA(renderer, x1, y1, r, g, b, a);
-
- /*
- * x-major or y-major?
- */
- if (dy > dx) {
-
- /*
- * y-major. Calculate 16-bit fixed point fractional part of a pixel that
- * X advances every time Y advances 1 pixel, truncating the result so that
- * we won't overrun the endpoint along the X axis
- */
- /*
- * Not-so-portable version: erradj = ((Uint64)dx << 32) / (Uint64)dy;
- */
- erradj = ((dx << 16) / dy) << 16;
-
- /*
- * draw all pixels other than the first and last
- */
- x0pxdir = xx0 + xdir;
- while (--dy) {
- erracctmp = erracc;
- erracc += erradj;
- if (erracc <= erracctmp) {
- /*
- * rollover in error accumulator, x coord advances
- */
- xx0 = x0pxdir;
- x0pxdir += xdir;
- }
- yy0++; /* y-major so always advance Y */
-
- /*
- * the AAbits most significant bits of erracc give us the intensity
- * weighting for this pixel, and the complement of the weighting for
- * the paired pixel.
- */
- wgt = (erracc >> intshift) & 255;
- result |= pixelRGBAWeight (renderer, xx0, yy0, r, g, b, a, 255 - wgt);
- result |= pixelRGBAWeight (renderer, x0pxdir, yy0, r, g, b, a, wgt);
- }
-
- } else {
-
- /*
- * x-major line. Calculate 16-bit fixed-point fractional part of a pixel
- * that Y advances each time X advances 1 pixel, truncating the result so
- * that we won't overrun the endpoint along the X axis.
- */
- /*
- * Not-so-portable version: erradj = ((Uint64)dy << 32) / (Uint64)dx;
- */
- erradj = ((dy << 16) / dx) << 16;
-
- /*
- * draw all pixels other than the first and last
- */
- y0p1 = yy0 + 1;
- while (--dx) {
-
- erracctmp = erracc;
- erracc += erradj;
- if (erracc <= erracctmp) {
- /*
- * Accumulator turned over, advance y
- */
- yy0 = y0p1;
- y0p1++;
- }
- xx0 += xdir; /* x-major so always advance X */
- /*
- * the AAbits most significant bits of erracc give us the intensity
- * weighting for this pixel, and the complement of the weighting for
- * the paired pixel.
- */
- wgt = (erracc >> intshift) & 255;
- result |= pixelRGBAWeight (renderer, xx0, yy0, r, g, b, a, 255 - wgt);
- result |= pixelRGBAWeight (renderer, xx0, y0p1, r, g, b, a, wgt);
- }
- }
-
- /*
- * Do we have to draw the endpoint
- */
- if (draw_endpoint) {
- /*
- * Draw final pixel, always exactly intersected by the line and doesn't
- * need to be weighted.
- */
- result |= pixelRGBA (renderer, x2, y2, r, g, b, a);
- }
-
- return (result);
-}
-
-/*!
-\brief Draw anti-aliased line with alpha blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point of the aa-line.
-\param y1 Y coordinate of the first point of the aa-line.
-\param x2 X coordinate of the second point of the aa-line.
-\param y2 Y coordinate of the second point of the aa-line.
-\param color The color value of the aa-line to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int aalineColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return _aalineRGBA(renderer, x1, y1, x2, y2, c[0], c[1], c[2], c[3], 1);
-}
-
-/*!
-\brief Draw anti-aliased line with alpha blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point of the aa-line.
-\param y1 Y coordinate of the first point of the aa-line.
-\param x2 X coordinate of the second point of the aa-line.
-\param y2 Y coordinate of the second point of the aa-line.
-\param r The red value of the aa-line to draw.
-\param g The green value of the aa-line to draw.
-\param b The blue value of the aa-line to draw.
-\param a The alpha value of the aa-line to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int aalineRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- return _aalineRGBA(renderer, x1, y1, x2, y2, r, g, b, a, 1);
-}
-
-/* ----- Circle */
-
-/*!
-\brief Draw circle with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the circle.
-\param y Y coordinate of the center of the circle.
-\param rad Radius in pixels of the circle.
-\param color The color value of the circle to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int circleColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return ellipseRGBA(renderer, x, y, rad, rad, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw circle with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the circle.
-\param y Y coordinate of the center of the circle.
-\param rad Radius in pixels of the circle.
-\param r The red value of the circle to draw.
-\param g The green value of the circle to draw.
-\param b The blue value of the circle to draw.
-\param a The alpha value of the circle to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int circleRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- return ellipseRGBA(renderer, x, y, rad, rad, r, g, b, a);
-}
-
-/* ----- Arc */
-
-/*!
-\brief Arc with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the arc.
-\param y Y coordinate of the center of the arc.
-\param rad Radius in pixels of the arc.
-\param start Starting radius in degrees of the arc. 0 degrees is down, increasing counterclockwise.
-\param end Ending radius in degrees of the arc. 0 degrees is down, increasing counterclockwise.
-\param color The color value of the arc to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int arcColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return arcRGBA(renderer, x, y, rad, start, end, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Arc with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the arc.
-\param y Y coordinate of the center of the arc.
-\param rad Radius in pixels of the arc.
-\param start Starting radius in degrees of the arc. 0 degrees is down, increasing counterclockwise.
-\param end Ending radius in degrees of the arc. 0 degrees is down, increasing counterclockwise.
-\param r The red value of the arc to draw.
-\param g The green value of the arc to draw.
-\param b The blue value of the arc to draw.
-\param a The alpha value of the arc to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int arcRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result;
- Sint16 cx = 0;
- Sint16 cy = rad;
- Sint16 df = 1 - rad;
- Sint16 d_e = 3;
- Sint16 d_se = -2 * rad + 5;
- Sint16 xpcx, xmcx, xpcy, xmcy;
- Sint16 ypcy, ymcy, ypcx, ymcx;
- Uint8 drawoct;
- int startoct, endoct, oct, stopval_start = 0, stopval_end = 0;
- double dstart, dend, temp = 0.;
-
- /*
- * Sanity check radius
- */
- if (rad < 0) {
- return (-1);
- }
-
- /*
- * Special case for rad=0 - draw a point
- */
- if (rad == 0) {
- return (pixelRGBA(renderer, x, y, r, g, b, a));
- }
-
- // Octant labelling
- //
- // \ 5 | 6 /
- // \ | /
- // 4 \ | / 7
- // \|/
- //------+------ +x
- // /|\
- // 3 / | \ 0
- // / | \
- // / 2 | 1 \
- // +y
-
- // Initially reset bitmask to 0x00000000
- // the set whether or not to keep drawing a given octant.
- // For example: 0x00111100 means we're drawing in octants 2-5
- drawoct = 0;
-
- /*
- * Fixup angles
- */
- start %= 360;
- end %= 360;
- // 0 <= start & end < 360; note that sometimes start > end - if so, arc goes back through 0.
- while (start < 0) start += 360;
- while (end < 0) end += 360;
- start %= 360;
- end %= 360;
-
- // now, we find which octants we're drawing in.
- startoct = start / 45;
- endoct = end / 45;
- oct = startoct - 1; // we increment as first step in loop
-
- // stopval_start, stopval_end;
- // what values of cx to stop at.
- do {
- oct = (oct + 1) % 8;
-
- if (oct == startoct) {
- // need to compute stopval_start for this octant. Look at picture above if this is unclear
- dstart = (double)start;
- switch (oct)
- {
- case 0:
- case 3:
- temp = sin(dstart * M_PI / 180.);
- break;
- case 1:
- case 6:
- temp = cos(dstart * M_PI / 180.);
- break;
- case 2:
- case 5:
- temp = -cos(dstart * M_PI / 180.);
- break;
- case 4:
- case 7:
- temp = -sin(dstart * M_PI / 180.);
- break;
- }
- temp *= rad;
- stopval_start = (int)temp; // always round down.
-
- // This isn't arbitrary, but requires graph paper to explain well.
- // The basic idea is that we're always changing drawoct after we draw, so we
- // stop immediately after we render the last sensible pixel at x = ((int)temp).
-
- // and whether to draw in this octant initially
- if (oct % 2) drawoct |= (1 << oct); // this is basically like saying drawoct[oct] = true, if drawoct were a bool array
- else drawoct &= 255 - (1 << oct); // this is basically like saying drawoct[oct] = false
- }
- if (oct == endoct) {
- // need to compute stopval_end for this octant
- dend = (double)end;
- switch (oct)
- {
- case 0:
- case 3:
- temp = sin(dend * M_PI / 180);
- break;
- case 1:
- case 6:
- temp = cos(dend * M_PI / 180);
- break;
- case 2:
- case 5:
- temp = -cos(dend * M_PI / 180);
- break;
- case 4:
- case 7:
- temp = -sin(dend * M_PI / 180);
- break;
- }
- temp *= rad;
- stopval_end = (int)temp;
-
- // and whether to draw in this octant initially
- if (startoct == endoct) {
- // note: we start drawing, stop, then start again in this case
- // otherwise: we only draw in this octant, so initialize it to false, it will get set back to true
- if (start > end) {
- // unfortunately, if we're in the same octant and need to draw over the whole circle,
- // we need to set the rest to true, because the while loop will end at the bottom.
- drawoct = 255;
- } else {
- drawoct &= 255 - (1 << oct);
- }
- }
- else if (oct % 2) drawoct &= 255 - (1 << oct);
- else drawoct |= (1 << oct);
- } else if (oct != startoct) { // already verified that it's != endoct
- drawoct |= (1 << oct); // draw this entire segment
- }
- } while (oct != endoct);
-
- // so now we have what octants to draw and when to draw them. all that's left is the actual raster code.
-
- /*
- * Set color
- */
- result = 0;
- result |= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND);
- result |= SDL_SetRenderDrawColor(renderer, r, g, b, a);
-
- /*
- * Draw arc
- */
- do {
- ypcy = y + cy;
- ymcy = y - cy;
- if (cx > 0) {
- xpcx = x + cx;
- xmcx = x - cx;
-
- // always check if we're drawing a certain octant before adding a pixel to that octant.
- if (drawoct & 4) result |= pixel(renderer, xmcx, ypcy);
- if (drawoct & 2) result |= pixel(renderer, xpcx, ypcy);
- if (drawoct & 32) result |= pixel(renderer, xmcx, ymcy);
- if (drawoct & 64) result |= pixel(renderer, xpcx, ymcy);
- } else {
- if (drawoct & 96) result |= pixel(renderer, x, ymcy);
- if (drawoct & 6) result |= pixel(renderer, x, ypcy);
- }
-
- xpcy = x + cy;
- xmcy = x - cy;
- if (cx > 0 && cx != cy) {
- ypcx = y + cx;
- ymcx = y - cx;
- if (drawoct & 8) result |= pixel(renderer, xmcy, ypcx);
- if (drawoct & 1) result |= pixel(renderer, xpcy, ypcx);
- if (drawoct & 16) result |= pixel(renderer, xmcy, ymcx);
- if (drawoct & 128) result |= pixel(renderer, xpcy, ymcx);
- } else if (cx == 0) {
- if (drawoct & 24) result |= pixel(renderer, xmcy, y);
- if (drawoct & 129) result |= pixel(renderer, xpcy, y);
- }
-
- /*
- * Update whether we're drawing an octant
- */
- if (stopval_start == cx) {
- // works like an on-off switch.
- // This is just in case start & end are in the same octant.
- if (drawoct & (1 << startoct)) drawoct &= 255 - (1 << startoct);
- else drawoct |= (1 << startoct);
- }
- if (stopval_end == cx) {
- if (drawoct & (1 << endoct)) drawoct &= 255 - (1 << endoct);
- else drawoct |= (1 << endoct);
- }
-
- /*
- * Update pixels
- */
- if (df < 0) {
- df += d_e;
- d_e += 2;
- d_se += 2;
- } else {
- df += d_se;
- d_e += 2;
- d_se += 4;
- cy--;
- }
- cx++;
- } while (cx <= cy);
-
- return (result);
-}
-
-/* ----- AA Circle */
-
-/*!
-\brief Draw anti-aliased circle with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the aa-circle.
-\param y Y coordinate of the center of the aa-circle.
-\param rad Radius in pixels of the aa-circle.
-\param color The color value of the aa-circle to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int aacircleColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return aaellipseRGBA(renderer, x, y, rad, rad, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw anti-aliased circle with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the aa-circle.
-\param y Y coordinate of the center of the aa-circle.
-\param rad Radius in pixels of the aa-circle.
-\param r The red value of the aa-circle to draw.
-\param g The green value of the aa-circle to draw.
-\param b The blue value of the aa-circle to draw.
-\param a The alpha value of the aa-circle to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int aacircleRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- /*
- * Draw
- */
- return aaellipseRGBA(renderer, x, y, rad, rad, r, g, b, a);
-}
-
-/* ----- Filled Circle */
-
-/*!
-\brief Draw filled circle with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the filled circle.
-\param y Y coordinate of the center of the filled circle.
-\param rad Radius in pixels of the filled circle.
-\param color The color value of the filled circle to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int filledCircleColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return filledEllipseRGBA(renderer, x, y, rad, rad, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw filled circle with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the filled circle.
-\param y Y coordinate of the center of the filled circle.
-\param rad Radius in pixels of the filled circle.
-\param r The red value of the filled circle to draw.
-\param g The green value of the filled circle to draw.
-\param b The blue value of the filled circle to draw.
-\param a The alpha value of the filled circle to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int filledCircleRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result;
- Sint16 cx = 0;
- Sint16 cy = rad;
- Sint16 ocx = (Sint16) 0xffff;
- Sint16 ocy = (Sint16) 0xffff;
- Sint16 df = 1 - rad;
- Sint16 d_e = 3;
- Sint16 d_se = -2 * rad + 5;
- Sint16 xpcx, xmcx, xpcy, xmcy;
- Sint16 ypcy, ymcy, ypcx, ymcx;
-
- /*
- * Sanity check radius
- */
- if (rad < 0) {
- return (-1);
- }
-
- /*
- * Special case for rad=0 - draw a point
- */
- if (rad == 0) {
- return (pixelRGBA(renderer, x, y, r, g, b, a));
- }
-
- /*
- * Set color
- */
- result = 0;
- result |= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND);
- result |= SDL_SetRenderDrawColor(renderer, r, g, b, a);
-
- /*
- * Draw
- */
- do {
- xpcx = x + cx;
- xmcx = x - cx;
- xpcy = x + cy;
- xmcy = x - cy;
- if (ocy != cy) {
- if (cy > 0) {
- ypcy = y + cy;
- ymcy = y - cy;
- result |= hline(renderer, xmcx, xpcx, ypcy);
- result |= hline(renderer, xmcx, xpcx, ymcy);
- } else {
- result |= hline(renderer, xmcx, xpcx, y);
- }
- ocy = cy;
- }
- if (ocx != cx) {
- if (cx != cy) {
- if (cx > 0) {
- ypcx = y + cx;
- ymcx = y - cx;
- result |= hline(renderer, xmcy, xpcy, ymcx);
- result |= hline(renderer, xmcy, xpcy, ypcx);
- } else {
- result |= hline(renderer, xmcy, xpcy, y);
- }
- }
- ocx = cx;
- }
-
- /*
- * Update
- */
- if (df < 0) {
- df += d_e;
- d_e += 2;
- d_se += 2;
- } else {
- df += d_se;
- d_e += 2;
- d_se += 4;
- cy--;
- }
- cx++;
- } while (cx <= cy);
-
- return (result);
-}
-
-/* ----- Ellipse */
-
-/*!
-\brief Draw ellipse with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the ellipse.
-\param y Y coordinate of the center of the ellipse.
-\param rx Horizontal radius in pixels of the ellipse.
-\param ry Vertical radius in pixels of the ellipse.
-\param color The color value of the ellipse to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int ellipseColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return ellipseRGBA(renderer, x, y, rx, ry, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw ellipse with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the ellipse.
-\param y Y coordinate of the center of the ellipse.
-\param rx Horizontal radius in pixels of the ellipse.
-\param ry Vertical radius in pixels of the ellipse.
-\param r The red value of the ellipse to draw.
-\param g The green value of the ellipse to draw.
-\param b The blue value of the ellipse to draw.
-\param a The alpha value of the ellipse to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int ellipseRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result;
- int ix, iy;
- int h, i, j, k;
- int oh, oi, oj, ok;
- int xmh, xph, ypk, ymk;
- int xmi, xpi, ymj, ypj;
- int xmj, xpj, ymi, ypi;
- int xmk, xpk, ymh, yph;
-
- /*
- * Sanity check radii
- */
- if ((rx < 0) || (ry < 0)) {
- return (-1);
- }
-
- /*
- * Special case for rx=0 - draw a vline
- */
- if (rx == 0) {
- return (vlineRGBA(renderer, x, y - ry, y + ry, r, g, b, a));
- }
- /*
- * Special case for ry=0 - draw a hline
- */
- if (ry == 0) {
- return (hlineRGBA(renderer, x - rx, x + rx, y, r, g, b, a));
- }
-
- /*
- * Set color
- */
- result = 0;
- result |= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND);
- result |= SDL_SetRenderDrawColor(renderer, r, g, b, a);
-
- /*
- * Init vars
- */
- oh = oi = oj = ok = 0xFFFF;
-
- /*
- * Draw
- */
- if (rx > ry) {
- ix = 0;
- iy = rx * 64;
-
- do {
- h = (ix + 32) >> 6;
- i = (iy + 32) >> 6;
- j = (h * ry) / rx;
- k = (i * ry) / rx;
-
- if (((ok != k) && (oj != k)) || ((oj != j) && (ok != j)) || (k != j)) {
- xph = x + h;
- xmh = x - h;
- if (k > 0) {
- ypk = y + k;
- ymk = y - k;
- result |= pixel(renderer, xmh, ypk);
- result |= pixel(renderer, xph, ypk);
- result |= pixel(renderer, xmh, ymk);
- result |= pixel(renderer, xph, ymk);
- } else {
- result |= pixel(renderer, xmh, y);
- result |= pixel(renderer, xph, y);
- }
- ok = k;
- xpi = x + i;
- xmi = x - i;
- if (j > 0) {
- ypj = y + j;
- ymj = y - j;
- result |= pixel(renderer, xmi, ypj);
- result |= pixel(renderer, xpi, ypj);
- result |= pixel(renderer, xmi, ymj);
- result |= pixel(renderer, xpi, ymj);
- } else {
- result |= pixel(renderer, xmi, y);
- result |= pixel(renderer, xpi, y);
- }
- oj = j;
- }
-
- ix = ix + iy / rx;
- iy = iy - ix / rx;
-
- } while (i > h);
- } else {
- ix = 0;
- iy = ry * 64;
-
- do {
- h = (ix + 32) >> 6;
- i = (iy + 32) >> 6;
- j = (h * rx) / ry;
- k = (i * rx) / ry;
-
- if (((oi != i) && (oh != i)) || ((oh != h) && (oi != h) && (i != h))) {
- xmj = x - j;
- xpj = x + j;
- if (i > 0) {
- ypi = y + i;
- ymi = y - i;
- result |= pixel(renderer, xmj, ypi);
- result |= pixel(renderer, xpj, ypi);
- result |= pixel(renderer, xmj, ymi);
- result |= pixel(renderer, xpj, ymi);
- } else {
- result |= pixel(renderer, xmj, y);
- result |= pixel(renderer, xpj, y);
- }
- oi = i;
- xmk = x - k;
- xpk = x + k;
- if (h > 0) {
- yph = y + h;
- ymh = y - h;
- result |= pixel(renderer, xmk, yph);
- result |= pixel(renderer, xpk, yph);
- result |= pixel(renderer, xmk, ymh);
- result |= pixel(renderer, xpk, ymh);
- } else {
- result |= pixel(renderer, xmk, y);
- result |= pixel(renderer, xpk, y);
- }
- oh = h;
- }
-
- ix = ix + iy / ry;
- iy = iy - ix / ry;
-
- } while (i > h);
- }
-
- return (result);
-}
-
-/* ----- AA Ellipse */
-
-/* Windows targets do not have lrint, so provide a local inline version */
-#if defined(_MSC_VER)
-/* Detect 64bit and use intrinsic version */
-#ifdef _M_X64
-#include <emmintrin.h>
-static __inline long
- lrint(float f)
-{
- return _mm_cvtss_si32(_mm_load_ss(&f));
-}
-#elif defined(_M_IX86)
-__inline long int
- lrint (double flt)
-{
- int intgr;
- _asm
- {
- fld flt
- fistp intgr
- };
- return intgr;
-}
-#elif defined(_M_ARM)
-#include <armintr.h>
-#pragma warning(push)
-#pragma warning(disable: 4716)
-__declspec(naked) long int
- lrint (double flt)
-{
- __emit(0xEC410B10); // fmdrr d0, r0, r1
- __emit(0xEEBD0B40); // ftosid s0, d0
- __emit(0xEE100A10); // fmrs r0, s0
- __emit(0xE12FFF1E); // bx lr
-}
-#pragma warning(pop)
-#else
-#error lrint needed for MSVC on non X86/AMD64/ARM targets.
-#endif
-#endif
-
-/*!
-\brief Draw anti-aliased ellipse with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the aa-ellipse.
-\param y Y coordinate of the center of the aa-ellipse.
-\param rx Horizontal radius in pixels of the aa-ellipse.
-\param ry Vertical radius in pixels of the aa-ellipse.
-\param color The color value of the aa-ellipse to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int aaellipseColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return aaellipseRGBA(renderer, x, y, rx, ry, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw anti-aliased ellipse with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the aa-ellipse.
-\param y Y coordinate of the center of the aa-ellipse.
-\param rx Horizontal radius in pixels of the aa-ellipse.
-\param ry Vertical radius in pixels of the aa-ellipse.
-\param r The red value of the aa-ellipse to draw.
-\param g The green value of the aa-ellipse to draw.
-\param b The blue value of the aa-ellipse to draw.
-\param a The alpha value of the aa-ellipse to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int aaellipseRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result;
- int i;
- int a2, b2, ds, dt, dxt, t, s, d;
- Sint16 xp, yp, xs, ys, dyt, od, xx, yy, xc2, yc2;
- float cp;
- double sab;
- Uint8 weight, iweight;
-
- /*
- * Sanity check radii
- */
- if ((rx < 0) || (ry < 0)) {
- return (-1);
- }
-
- /*
- * Special case for rx=0 - draw a vline
- */
- if (rx == 0) {
- return (vlineRGBA(renderer, x, y - ry, y + ry, r, g, b, a));
- }
- /*
- * Special case for ry=0 - draw an hline
- */
- if (ry == 0) {
- return (hlineRGBA(renderer, x - rx, x + rx, y, r, g, b, a));
- }
-
- /* Variable setup */
- a2 = rx * rx;
- b2 = ry * ry;
-
- ds = 2 * a2;
- dt = 2 * b2;
-
- xc2 = 2 * x;
- yc2 = 2 * y;
-
- sab = sqrt((double)(a2 + b2));
- od = (Sint16)lrint(sab*0.01) + 1; /* introduce some overdraw */
- dxt = (Sint16)lrint((double)a2 / sab) + od;
-
- t = 0;
- s = -2 * a2 * ry;
- d = 0;
-
- xp = x;
- yp = y - ry;
-
- /* Draw */
- result = 0;
- result |= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND);
-
- /* "End points" */
- result |= pixelRGBA(renderer, xp, yp, r, g, b, a);
- result |= pixelRGBA(renderer, xc2 - xp, yp, r, g, b, a);
- result |= pixelRGBA(renderer, xp, yc2 - yp, r, g, b, a);
- result |= pixelRGBA(renderer, xc2 - xp, yc2 - yp, r, g, b, a);
-
- for (i = 1; i <= dxt; i++) {
- xp--;
- d += t - b2;
-
- if (d >= 0)
- ys = yp - 1;
- else if ((d - s - a2) > 0) {
- if ((2 * d - s - a2) >= 0)
- ys = yp + 1;
- else {
- ys = yp;
- yp++;
- d -= s + a2;
- s += ds;
- }
- } else {
- yp++;
- ys = yp + 1;
- d -= s + a2;
- s += ds;
- }
-
- t -= dt;
-
- /* Calculate alpha */
- if (s != 0) {
- cp = (float) abs(d) / (float) abs(s);
- if (cp > 1.0) {
- cp = 1.0;
- }
- } else {
- cp = 1.0;
- }
-
- /* Calculate weights */
- weight = (Uint8) (cp * 255);
- iweight = 255 - weight;
-
- /* Upper half */
- xx = xc2 - xp;
- result |= pixelRGBAWeight(renderer, xp, yp, r, g, b, a, iweight);
- result |= pixelRGBAWeight(renderer, xx, yp, r, g, b, a, iweight);
-
- result |= pixelRGBAWeight(renderer, xp, ys, r, g, b, a, weight);
- result |= pixelRGBAWeight(renderer, xx, ys, r, g, b, a, weight);
-
- /* Lower half */
- yy = yc2 - yp;
- result |= pixelRGBAWeight(renderer, xp, yy, r, g, b, a, iweight);
- result |= pixelRGBAWeight(renderer, xx, yy, r, g, b, a, iweight);
-
- yy = yc2 - ys;
- result |= pixelRGBAWeight(renderer, xp, yy, r, g, b, a, weight);
- result |= pixelRGBAWeight(renderer, xx, yy, r, g, b, a, weight);
- }
-
- /* Replaces original approximation code dyt = abs(yp - yc); */
- dyt = (Sint16)lrint((double)b2 / sab ) + od;
-
- for (i = 1; i <= dyt; i++) {
- yp++;
- d -= s + a2;
-
- if (d <= 0)
- xs = xp + 1;
- else if ((d + t - b2) < 0) {
- if ((2 * d + t - b2) <= 0)
- xs = xp - 1;
- else {
- xs = xp;
- xp--;
- d += t - b2;
- t -= dt;
- }
- } else {
- xp--;
- xs = xp - 1;
- d += t - b2;
- t -= dt;
- }
-
- s += ds;
-
- /* Calculate alpha */
- if (t != 0) {
- cp = (float) abs(d) / (float) abs(t);
- if (cp > 1.0) {
- cp = 1.0;
- }
- } else {
- cp = 1.0;
- }
-
- /* Calculate weight */
- weight = (Uint8) (cp * 255);
- iweight = 255 - weight;
-
- /* Left half */
- xx = xc2 - xp;
- yy = yc2 - yp;
- result |= pixelRGBAWeight(renderer, xp, yp, r, g, b, a, iweight);
- result |= pixelRGBAWeight(renderer, xx, yp, r, g, b, a, iweight);
-
- result |= pixelRGBAWeight(renderer, xp, yy, r, g, b, a, iweight);
- result |= pixelRGBAWeight(renderer, xx, yy, r, g, b, a, iweight);
-
- /* Right half */
- xx = xc2 - xs;
- result |= pixelRGBAWeight(renderer, xs, yp, r, g, b, a, weight);
- result |= pixelRGBAWeight(renderer, xx, yp, r, g, b, a, weight);
-
- result |= pixelRGBAWeight(renderer, xs, yy, r, g, b, a, weight);
- result |= pixelRGBAWeight(renderer, xx, yy, r, g, b, a, weight);
- }
-
- return (result);
-}
-
-/* ---- Filled Ellipse */
-
-/*!
-\brief Draw filled ellipse with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the filled ellipse.
-\param y Y coordinate of the center of the filled ellipse.
-\param rx Horizontal radius in pixels of the filled ellipse.
-\param ry Vertical radius in pixels of the filled ellipse.
-\param color The color value of the filled ellipse to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int filledEllipseColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return filledEllipseRGBA(renderer, x, y, rx, ry, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw filled ellipse with blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the filled ellipse.
-\param y Y coordinate of the center of the filled ellipse.
-\param rx Horizontal radius in pixels of the filled ellipse.
-\param ry Vertical radius in pixels of the filled ellipse.
-\param r The red value of the filled ellipse to draw.
-\param g The green value of the filled ellipse to draw.
-\param b The blue value of the filled ellipse to draw.
-\param a The alpha value of the filled ellipse to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int filledEllipseRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result;
- int ix, iy;
- int h, i, j, k;
- int oh, oi, oj, ok;
- int xmh, xph;
- int xmi, xpi;
- int xmj, xpj;
- int xmk, xpk;
-
- /*
- * Sanity check radii
- */
- if ((rx < 0) || (ry < 0)) {
- return (-1);
- }
-
- /*
- * Special case for rx=0 - draw a vline
- */
- if (rx == 0) {
- return (vlineRGBA(renderer, x, y - ry, y + ry, r, g, b, a));
- }
- /*
- * Special case for ry=0 - draw a hline
- */
- if (ry == 0) {
- return (hlineRGBA(renderer, x - rx, x + rx, y, r, g, b, a));
- }
-
- /*
- * Set color
- */
- result = 0;
- result |= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND);
- result |= SDL_SetRenderDrawColor(renderer, r, g, b, a);
-
- /*
- * Init vars
- */
- oh = oi = oj = ok = 0xFFFF;
-
- /*
- * Draw
- */
- if (rx > ry) {
- ix = 0;
- iy = rx * 64;
-
- do {
- h = (ix + 32) >> 6;
- i = (iy + 32) >> 6;
- j = (h * ry) / rx;
- k = (i * ry) / rx;
-
- if ((ok != k) && (oj != k)) {
- xph = x + h;
- xmh = x - h;
- if (k > 0) {
- result |= hline(renderer, xmh, xph, y + k);
- result |= hline(renderer, xmh, xph, y - k);
- } else {
- result |= hline(renderer, xmh, xph, y);
- }
- ok = k;
- }
- if ((oj != j) && (ok != j) && (k != j)) {
- xmi = x - i;
- xpi = x + i;
- if (j > 0) {
- result |= hline(renderer, xmi, xpi, y + j);
- result |= hline(renderer, xmi, xpi, y - j);
- } else {
- result |= hline(renderer, xmi, xpi, y);
- }
- oj = j;
- }
-
- ix = ix + iy / rx;
- iy = iy - ix / rx;
-
- } while (i > h);
- } else {
- ix = 0;
- iy = ry * 64;
-
- do {
- h = (ix + 32) >> 6;
- i = (iy + 32) >> 6;
- j = (h * rx) / ry;
- k = (i * rx) / ry;
-
- if ((oi != i) && (oh != i)) {
- xmj = x - j;
- xpj = x + j;
- if (i > 0) {
- result |= hline(renderer, xmj, xpj, y + i);
- result |= hline(renderer, xmj, xpj, y - i);
- } else {
- result |= hline(renderer, xmj, xpj, y);
- }
- oi = i;
- }
- if ((oh != h) && (oi != h) && (i != h)) {
- xmk = x - k;
- xpk = x + k;
- if (h > 0) {
- result |= hline(renderer, xmk, xpk, y + h);
- result |= hline(renderer, xmk, xpk, y - h);
- } else {
- result |= hline(renderer, xmk, xpk, y);
- }
- oh = h;
- }
-
- ix = ix + iy / ry;
- iy = iy - ix / ry;
-
- } while (i > h);
- }
-
- return (result);
-}
-
-/* ----- Pie */
-
-/*!
-\brief Internal float (low-speed) pie-calc implementation by drawing polygons.
-
-Note: Determines vertex array and uses polygon or filledPolygon drawing routines to render.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the pie.
-\param y Y coordinate of the center of the pie.
-\param rad Radius in pixels of the pie.
-\param start Starting radius in degrees of the pie.
-\param end Ending radius in degrees of the pie.
-\param color The color value of the pie to draw (0xRRGGBBAA).
-\param filled Flag indicating if the pie should be filled (=1) or not (=0).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int _pieRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Uint8 filled)
-{
- int result;
- double angle, start_angle, end_angle;
- double deltaAngle;
- double dr;
- int numpoints, i;
- Sint16 *vx, *vy;
-
- /*
- * Sanity check radii
- */
- if (rad < 0) {
- return (-1);
- }
-
- /*
- * Fixup angles
- */
- start = start % 360;
- end = end % 360;
-
- /*
- * Special case for rad=0 - draw a point
- */
- if (rad == 0) {
- return (pixelRGBA(renderer, x, y, r, g, b, a));
- }
-
- /*
- * Variable setup
- */
- dr = (double) rad;
- deltaAngle = 3.0 / dr;
- start_angle = (double) start *(2.0 * M_PI / 360.0);
- end_angle = (double) end *(2.0 * M_PI / 360.0);
- if (start > end) {
- end_angle += (2.0 * M_PI);
- }
-
- /* We will always have at least 2 points */
- numpoints = 2;
-
- /* Count points (rather than calculating it) */
- angle = start_angle;
- while (angle < end_angle) {
- angle += deltaAngle;
- numpoints++;
- }
-
- /* Allocate combined vertex array */
- vx = vy = (Sint16 *) malloc(2 * sizeof(Uint16) * numpoints);
- if (vx == NULL) {
- return (-1);
- }
-
- /* Update point to start of vy */
- vy += numpoints;
-
- /* Center */
- vx[0] = x;
- vy[0] = y;
-
- /* First vertex */
- angle = start_angle;
- vx[1] = x + (int) (dr * cos(angle));
- vy[1] = y + (int) (dr * sin(angle));
-
- if (numpoints<3)
- {
- result = lineRGBA(renderer, vx[0], vy[0], vx[1], vy[1], r, g, b, a);
- }
- else
- {
- /* Calculate other vertices */
- i = 2;
- angle = start_angle;
- while (angle < end_angle) {
- angle += deltaAngle;
- if (angle>end_angle)
- {
- angle = end_angle;
- }
- vx[i] = x + (int) (dr * cos(angle));
- vy[i] = y + (int) (dr * sin(angle));
- i++;
- }
-
- /* Draw */
- if (filled) {
- result = filledPolygonRGBA(renderer, vx, vy, numpoints, r, g, b, a);
- } else {
- result = polygonRGBA(renderer, vx, vy, numpoints, r, g, b, a);
- }
- }
-
- /* Free combined vertex array */
- free(vx);
-
- return (result);
-}
-
-/*!
-\brief Draw pie (outline) with alpha blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the pie.
-\param y Y coordinate of the center of the pie.
-\param rad Radius in pixels of the pie.
-\param start Starting radius in degrees of the pie.
-\param end Ending radius in degrees of the pie.
-\param color The color value of the pie to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int pieColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad,
- Sint16 start, Sint16 end, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return _pieRGBA(renderer, x, y, rad, start, end, c[0], c[1], c[2], c[3], 0);
-}
-
-/*!
-\brief Draw pie (outline) with alpha blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the pie.
-\param y Y coordinate of the center of the pie.
-\param rad Radius in pixels of the pie.
-\param start Starting radius in degrees of the pie.
-\param end Ending radius in degrees of the pie.
-\param r The red value of the pie to draw.
-\param g The green value of the pie to draw.
-\param b The blue value of the pie to draw.
-\param a The alpha value of the pie to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int pieRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad,
- Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- return _pieRGBA(renderer, x, y, rad, start, end, r, g, b, a, 0);
-}
-
-/*!
-\brief Draw filled pie with alpha blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the filled pie.
-\param y Y coordinate of the center of the filled pie.
-\param rad Radius in pixels of the filled pie.
-\param start Starting radius in degrees of the filled pie.
-\param end Ending radius in degrees of the filled pie.
-\param color The color value of the filled pie to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int filledPieColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return _pieRGBA(renderer, x, y, rad, start, end, c[0], c[1], c[2], c[3], 1);
-}
-
-/*!
-\brief Draw filled pie with alpha blending.
-
-\param renderer The renderer to draw on.
-\param x X coordinate of the center of the filled pie.
-\param y Y coordinate of the center of the filled pie.
-\param rad Radius in pixels of the filled pie.
-\param start Starting radius in degrees of the filled pie.
-\param end Ending radius in degrees of the filled pie.
-\param r The red value of the filled pie to draw.
-\param g The green value of the filled pie to draw.
-\param b The blue value of the filled pie to draw.
-\param a The alpha value of the filled pie to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int filledPieRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad,
- Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- return _pieRGBA(renderer, x, y, rad, start, end, r, g, b, a, 1);
-}
-
-/* ------ Trigon */
-
-/*!
-\brief Draw trigon (triangle outline) with alpha blending.
-
-Note: Creates vertex array and uses polygon routine to render.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point of the trigon.
-\param y1 Y coordinate of the first point of the trigon.
-\param x2 X coordinate of the second point of the trigon.
-\param y2 Y coordinate of the second point of the trigon.
-\param x3 X coordinate of the third point of the trigon.
-\param y3 Y coordinate of the third point of the trigon.
-\param color The color value of the trigon to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int trigonColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color)
-{
- Sint16 vx[3];
- Sint16 vy[3];
-
- vx[0]=x1;
- vx[1]=x2;
- vx[2]=x3;
- vy[0]=y1;
- vy[1]=y2;
- vy[2]=y3;
-
- return(polygonColor(renderer,vx,vy,3,color));
-}
-
-/*!
-\brief Draw trigon (triangle outline) with alpha blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point of the trigon.
-\param y1 Y coordinate of the first point of the trigon.
-\param x2 X coordinate of the second point of the trigon.
-\param y2 Y coordinate of the second point of the trigon.
-\param x3 X coordinate of the third point of the trigon.
-\param y3 Y coordinate of the third point of the trigon.
-\param r The red value of the trigon to draw.
-\param g The green value of the trigon to draw.
-\param b The blue value of the trigon to draw.
-\param a The alpha value of the trigon to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int trigonRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
- Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- Sint16 vx[3];
- Sint16 vy[3];
-
- vx[0]=x1;
- vx[1]=x2;
- vx[2]=x3;
- vy[0]=y1;
- vy[1]=y2;
- vy[2]=y3;
-
- return(polygonRGBA(renderer,vx,vy,3,r,g,b,a));
-}
-
-/* ------ AA-Trigon */
-
-/*!
-\brief Draw anti-aliased trigon (triangle outline) with alpha blending.
-
-Note: Creates vertex array and uses aapolygon routine to render.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point of the aa-trigon.
-\param y1 Y coordinate of the first point of the aa-trigon.
-\param x2 X coordinate of the second point of the aa-trigon.
-\param y2 Y coordinate of the second point of the aa-trigon.
-\param x3 X coordinate of the third point of the aa-trigon.
-\param y3 Y coordinate of the third point of the aa-trigon.
-\param color The color value of the aa-trigon to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int aatrigonColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color)
-{
- Sint16 vx[3];
- Sint16 vy[3];
-
- vx[0]=x1;
- vx[1]=x2;
- vx[2]=x3;
- vy[0]=y1;
- vy[1]=y2;
- vy[2]=y3;
-
- return(aapolygonColor(renderer,vx,vy,3,color));
-}
-
-/*!
-\brief Draw anti-aliased trigon (triangle outline) with alpha blending.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point of the aa-trigon.
-\param y1 Y coordinate of the first point of the aa-trigon.
-\param x2 X coordinate of the second point of the aa-trigon.
-\param y2 Y coordinate of the second point of the aa-trigon.
-\param x3 X coordinate of the third point of the aa-trigon.
-\param y3 Y coordinate of the third point of the aa-trigon.
-\param r The red value of the aa-trigon to draw.
-\param g The green value of the aa-trigon to draw.
-\param b The blue value of the aa-trigon to draw.
-\param a The alpha value of the aa-trigon to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int aatrigonRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
- Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- Sint16 vx[3];
- Sint16 vy[3];
-
- vx[0]=x1;
- vx[1]=x2;
- vx[2]=x3;
- vy[0]=y1;
- vy[1]=y2;
- vy[2]=y3;
-
- return(aapolygonRGBA(renderer,vx,vy,3,r,g,b,a));
-}
-
-/* ------ Filled Trigon */
-
-/*!
-\brief Draw filled trigon (triangle) with alpha blending.
-
-Note: Creates vertex array and uses aapolygon routine to render.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point of the filled trigon.
-\param y1 Y coordinate of the first point of the filled trigon.
-\param x2 X coordinate of the second point of the filled trigon.
-\param y2 Y coordinate of the second point of the filled trigon.
-\param x3 X coordinate of the third point of the filled trigon.
-\param y3 Y coordinate of the third point of the filled trigon.
-\param color The color value of the filled trigon to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int filledTrigonColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color)
-{
- Sint16 vx[3];
- Sint16 vy[3];
-
- vx[0]=x1;
- vx[1]=x2;
- vx[2]=x3;
- vy[0]=y1;
- vy[1]=y2;
- vy[2]=y3;
-
- return(filledPolygonColor(renderer,vx,vy,3,color));
-}
-
-/*!
-\brief Draw filled trigon (triangle) with alpha blending.
-
-Note: Creates vertex array and uses aapolygon routine to render.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point of the filled trigon.
-\param y1 Y coordinate of the first point of the filled trigon.
-\param x2 X coordinate of the second point of the filled trigon.
-\param y2 Y coordinate of the second point of the filled trigon.
-\param x3 X coordinate of the third point of the filled trigon.
-\param y3 Y coordinate of the third point of the filled trigon.
-\param r The red value of the filled trigon to draw.
-\param g The green value of the filled trigon to draw.
-\param b The blue value of the filled trigon to draw.
-\param a The alpha value of the filled trigon to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int filledTrigonRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
- Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- Sint16 vx[3];
- Sint16 vy[3];
-
- vx[0]=x1;
- vx[1]=x2;
- vx[2]=x3;
- vy[0]=y1;
- vy[1]=y2;
- vy[2]=y3;
-
- return(filledPolygonRGBA(renderer,vx,vy,3,r,g,b,a));
-}
-
-/* ---- Polygon */
-
-/*!
-\brief Draw polygon with alpha blending.
-
-\param renderer The renderer to draw on.
-\param vx Vertex array containing X coordinates of the points of the polygon.
-\param vy Vertex array containing Y coordinates of the points of the polygon.
-\param n Number of points in the vertex array. Minimum number is 3.
-\param color The color value of the polygon to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int polygonColor(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return polygonRGBA(renderer, vx, vy, n, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw polygon with the currently set color and blend mode.
-
-\param renderer The renderer to draw on.
-\param vx Vertex array containing X coordinates of the points of the polygon.
-\param vy Vertex array containing Y coordinates of the points of the polygon.
-\param n Number of points in the vertex array. Minimum number is 3.
-\param r The red value of the polygon to draw.
-\param g The green value of the polygon to draw.
-\param b The blue value of the polygon to draw.
-\param a The alpha value of the polygon to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int polygon(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy, int n)
-{
- /*
- * Draw
- */
- int result;
- int i, nn;
- SDL_Point* points;
-
- /*
- * Vertex array NULL check
- */
- if (vx == NULL) {
- return (-1);
- }
- if (vy == NULL) {
- return (-1);
- }
-
- /*
- * Sanity check
- */
- if (n < 3) {
- return (-1);
- }
-
- /*
- * Create array of points
- */
- nn = n + 1;
- points = (SDL_Point*)malloc(sizeof(SDL_Point) * nn);
- if (points == NULL)
- {
- return -1;
- }
- for (i=0; i<n; i++)
- {
- points[i].x = vx[i];
- points[i].y = vy[i];
- }
- points[n].x = vx[0];
- points[n].y = vy[0];
-
- /*
- * Draw
- */
- result |= SDL_RenderDrawLines(renderer, points, nn);
- free(points);
-
- return (result);
-}
-
-/*!
-\brief Draw polygon with alpha blending.
-
-\param renderer The renderer to draw on.
-\param vx Vertex array containing X coordinates of the points of the polygon.
-\param vy Vertex array containing Y coordinates of the points of the polygon.
-\param n Number of points in the vertex array. Minimum number is 3.
-\param r The red value of the polygon to draw.
-\param g The green value of the polygon to draw.
-\param b The blue value of the polygon to draw.
-\param a The alpha value of the polygon to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int polygonRGBA(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- /*
- * Draw
- */
- int result;
- const Sint16 *x1, *y1, *x2, *y2;
-
- /*
- * Vertex array NULL check
- */
- if (vx == NULL) {
- return (-1);
- }
- if (vy == NULL) {
- return (-1);
- }
-
- /*
- * Sanity check
- */
- if (n < 3) {
- return (-1);
- }
-
- /*
- * Pointer setup
- */
- x1 = x2 = vx;
- y1 = y2 = vy;
- x2++;
- y2++;
-
- /*
- * Set color
- */
- result = 0;
- result |= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND);
- result |= SDL_SetRenderDrawColor(renderer, r, g, b, a);
-
- /*
- * Draw
- */
- result |= polygon(renderer, vx, vy, n);
-
- return (result);
-}
-
-/* ---- AA-Polygon */
-
-/*!
-\brief Draw anti-aliased polygon with alpha blending.
-
-\param renderer The renderer to draw on.
-\param vx Vertex array containing X coordinates of the points of the aa-polygon.
-\param vy Vertex array containing Y coordinates of the points of the aa-polygon.
-\param n Number of points in the vertex array. Minimum number is 3.
-\param color The color value of the aa-polygon to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int aapolygonColor(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return aapolygonRGBA(renderer, vx, vy, n, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw anti-aliased polygon with alpha blending.
-
-\param renderer The renderer to draw on.
-\param vx Vertex array containing X coordinates of the points of the aa-polygon.
-\param vy Vertex array containing Y coordinates of the points of the aa-polygon.
-\param n Number of points in the vertex array. Minimum number is 3.
-\param r The red value of the aa-polygon to draw.
-\param g The green value of the aa-polygon to draw.
-\param b The blue value of the aa-polygon to draw.
-\param a The alpha value of the aa-polygon to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int aapolygonRGBA(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result;
- int i;
- const Sint16 *x1, *y1, *x2, *y2;
-
- /*
- * Vertex array NULL check
- */
- if (vx == NULL) {
- return (-1);
- }
- if (vy == NULL) {
- return (-1);
- }
-
- /*
- * Sanity check
- */
- if (n < 3) {
- return (-1);
- }
-
- /*
- * Pointer setup
- */
- x1 = x2 = vx;
- y1 = y2 = vy;
- x2++;
- y2++;
-
- /*
- * Draw
- */
- result = 0;
- for (i = 1; i < n; i++) {
- result |= _aalineRGBA(renderer, *x1, *y1, *x2, *y2, r, g, b, a, 0);
- x1 = x2;
- y1 = y2;
- x2++;
- y2++;
- }
-
- result |= _aalineRGBA(renderer, *x1, *y1, *vx, *vy, r, g, b, a, 0);
-
- return (result);
-}
-
-/* ---- Filled Polygon */
-
-/*!
-\brief Internal helper qsort callback functions used in filled polygon drawing.
-
-\param a The surface to draw on.
-\param b Vertex array containing X coordinates of the points of the polygon.
-
-\returns Returns 0 if a==b, a negative number if a<b or a positive number if a>b.
-*/
-int _gfxPrimitivesCompareInt(const void *a, const void *b)
-{
- return (*(const int *) a) - (*(const int *) b);
-}
-
-/*!
-\brief Global vertex array to use if optional parameters are not given in filledPolygonMT calls.
-
-Note: Used for non-multithreaded (default) operation of filledPolygonMT.
-*/
-static int *gfxPrimitivesPolyIntsGlobal = NULL;
-
-/*!
-\brief Flag indicating if global vertex array was already allocated.
-
-Note: Used for non-multithreaded (default) operation of filledPolygonMT.
-*/
-static int gfxPrimitivesPolyAllocatedGlobal = 0;
-
-/*!
-\brief Draw filled polygon with alpha blending (multi-threaded capable).
-
-Note: The last two parameters are optional; but are required for multithreaded operation.
-
-\param dst The surface to draw on.
-\param vx Vertex array containing X coordinates of the points of the filled polygon.
-\param vy Vertex array containing Y coordinates of the points of the filled polygon.
-\param n Number of points in the vertex array. Minimum number is 3.
-\param r The red value of the filled polygon to draw.
-\param g The green value of the filled polygon to draw.
-\param b The blue value of the filled polygon to draw.
-\param a The alpha value of the filled polygon to draw.
-\param polyInts Preallocated, temporary vertex array used for sorting vertices. Required for multithreaded operation; set to NULL otherwise.
-\param polyAllocated Flag indicating if temporary vertex array was allocated. Required for multithreaded operation; set to NULL otherwise.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int filledPolygonRGBAMT(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a, int **polyInts, int *polyAllocated)
-{
- int result;
- int i;
- int y, xa, xb;
- int miny, maxy;
- int x1, y1;
- int x2, y2;
- int ind1, ind2;
- int ints;
- int *gfxPrimitivesPolyInts = NULL;
- int *gfxPrimitivesPolyIntsNew = NULL;
- int gfxPrimitivesPolyAllocated = 0;
-
- /*
- * Vertex array NULL check
- */
- if (vx == NULL) {
- return (-1);
- }
- if (vy == NULL) {
- return (-1);
- }
-
- /*
- * Sanity check number of edges
- */
- if (n < 3) {
- return -1;
- }
-
- /*
- * Map polygon cache
- */
- if ((polyInts==NULL) || (polyAllocated==NULL)) {
- /* Use global cache */
- gfxPrimitivesPolyInts = gfxPrimitivesPolyIntsGlobal;
- gfxPrimitivesPolyAllocated = gfxPrimitivesPolyAllocatedGlobal;
- } else {
- /* Use local cache */
- gfxPrimitivesPolyInts = *polyInts;
- gfxPrimitivesPolyAllocated = *polyAllocated;
- }
-
- /*
- * Allocate temp array, only grow array
- */
- if (!gfxPrimitivesPolyAllocated) {
- gfxPrimitivesPolyInts = (int *) malloc(sizeof(int) * n);
- gfxPrimitivesPolyAllocated = n;
- } else {
- if (gfxPrimitivesPolyAllocated < n) {
- gfxPrimitivesPolyIntsNew = (int *) realloc(gfxPrimitivesPolyInts, sizeof(int) * n);
- if (!gfxPrimitivesPolyIntsNew) {
- if (!gfxPrimitivesPolyInts) {
- free(gfxPrimitivesPolyInts);
- gfxPrimitivesPolyInts = NULL;
- }
- gfxPrimitivesPolyAllocated = 0;
- } else {
- gfxPrimitivesPolyInts = gfxPrimitivesPolyIntsNew;
- gfxPrimitivesPolyAllocated = n;
- }
- }
- }
-
- /*
- * Check temp array
- */
- if (gfxPrimitivesPolyInts==NULL) {
- gfxPrimitivesPolyAllocated = 0;
- }
-
- /*
- * Update cache variables
- */
- if ((polyInts==NULL) || (polyAllocated==NULL)) {
- gfxPrimitivesPolyIntsGlobal = gfxPrimitivesPolyInts;
- gfxPrimitivesPolyAllocatedGlobal = gfxPrimitivesPolyAllocated;
- } else {
- *polyInts = gfxPrimitivesPolyInts;
- *polyAllocated = gfxPrimitivesPolyAllocated;
- }
-
- /*
- * Check temp array again
- */
- if (gfxPrimitivesPolyInts==NULL) {
- return(-1);
- }
-
- /*
- * Determine Y maxima
- */
- miny = vy[0];
- maxy = vy[0];
- for (i = 1; (i < n); i++) {
- if (vy[i] < miny) {
- miny = vy[i];
- } else if (vy[i] > maxy) {
- maxy = vy[i];
- }
- }
-
- /*
- * Draw, scanning y
- */
- result = 0;
- for (y = miny; (y <= maxy); y++) {
- ints = 0;
- for (i = 0; (i < n); i++) {
- if (!i) {
- ind1 = n - 1;
- ind2 = 0;
- } else {
- ind1 = i - 1;
- ind2 = i;
- }
- y1 = vy[ind1];
- y2 = vy[ind2];
- if (y1 < y2) {
- x1 = vx[ind1];
- x2 = vx[ind2];
- } else if (y1 > y2) {
- y2 = vy[ind1];
- y1 = vy[ind2];
- x2 = vx[ind1];
- x1 = vx[ind2];
- } else {
- continue;
- }
- if ( ((y >= y1) && (y < y2)) || ((y == maxy) && (y > y1) && (y <= y2)) ) {
- gfxPrimitivesPolyInts[ints++] = ((65536 * (y - y1)) / (y2 - y1)) * (x2 - x1) + (65536 * x1);
- }
- }
-
- qsort(gfxPrimitivesPolyInts, ints, sizeof(int), _gfxPrimitivesCompareInt);
-
- /*
- * Set color
- */
- result = 0;
- result |= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND);
- result |= SDL_SetRenderDrawColor(renderer, r, g, b, a);
-
- for (i = 0; (i < ints); i += 2) {
- xa = gfxPrimitivesPolyInts[i] + 1;
- xa = (xa >> 16) + ((xa & 32768) >> 15);
- xb = gfxPrimitivesPolyInts[i+1] - 1;
- xb = (xb >> 16) + ((xb & 32768) >> 15);
- result |= hline(renderer, xa, xb, y);
- }
- }
-
- return (result);
-}
-
-/*!
-\brief Draw filled polygon with alpha blending.
-
-\param renderer The renderer to draw on.
-\param vx Vertex array containing X coordinates of the points of the filled polygon.
-\param vy Vertex array containing Y coordinates of the points of the filled polygon.
-\param n Number of points in the vertex array. Minimum number is 3.
-\param color The color value of the filled polygon to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int filledPolygonColor(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return filledPolygonRGBAMT(renderer, vx, vy, n, c[0], c[1], c[2], c[3], NULL, NULL);
-}
-
-/*!
-\brief Draw filled polygon with alpha blending.
-
-\param renderer The renderer to draw on.
-\param vx Vertex array containing X coordinates of the points of the filled polygon.
-\param vy Vertex array containing Y coordinates of the points of the filled polygon.
-\param n Number of points in the vertex array. Minimum number is 3.
-\param r The red value of the filled polygon to draw.
-\param g The green value of the filled polygon to draw.
-\param b The blue value of the filed polygon to draw.
-\param a The alpha value of the filled polygon to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int filledPolygonRGBA(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- return filledPolygonRGBAMT(renderer, vx, vy, n, r, g, b, a, NULL, NULL);
-}
-
-/* ---- Textured Polygon */
-
-/*!
-\brief Internal function to draw a textured horizontal line.
-
-\param renderer The renderer to draw on.
-\param x1 X coordinate of the first point (i.e. left) of the line.
-\param x2 X coordinate of the second point (i.e. right) of the line.
-\param y Y coordinate of the points of the line.
-\param texture The texture to retrieve color information from.
-\param texture_w The width of the texture.
-\param texture_h The height of the texture.
-\param texture_dx The X offset for the texture lookup.
-\param texture_dy The Y offset for the textured lookup.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int _HLineTextured(SDL_Renderer *renderer, Sint16 x1, Sint16 x2, Sint16 y, SDL_Texture *texture, int texture_w, int texture_h, int texture_dx, int texture_dy)
-{
- Sint16 w;
- Sint16 xtmp;
- int result = 0;
- int texture_x_walker;
- int texture_y_start;
- SDL_Rect source_rect,dst_rect;
- int pixels_written,write_width;
-
- /*
- * Swap x1, x2 if required to ensure x1<=x2
- */
- if (x1 > x2) {
- xtmp = x1;
- x1 = x2;
- x2 = xtmp;
- }
-
- /*
- * Calculate width to draw
- */
- w = x2 - x1 + 1;
-
- /*
- * Determine where in the texture we start drawing
- */
- texture_x_walker = (x1 - texture_dx) % texture_w;
- if (texture_x_walker < 0){
- texture_x_walker = texture_w + texture_x_walker ;
- }
-
- texture_y_start = (y + texture_dy) % texture_h;
- if (texture_y_start < 0){
- texture_y_start = texture_h + texture_y_start;
- }
-
- // setup the source rectangle; we are only drawing one horizontal line
- source_rect.y = texture_y_start;
- source_rect.x = texture_x_walker;
- source_rect.h = 1;
-
- // we will draw to the current y
- dst_rect.y = y;
-
- // if there are enough pixels left in the current row of the texture
- // draw it all at once
- if (w <= texture_w -texture_x_walker){
- source_rect.w = w;
- source_rect.x = texture_x_walker;
- dst_rect.x= x1;
- result = (SDL_RenderCopy(renderer, texture, &source_rect ,&dst_rect) == 0);
- } else { // we need to draw multiple times
- // draw the first segment
- pixels_written = texture_w - texture_x_walker;
- source_rect.w = pixels_written;
- source_rect.x = texture_x_walker;
- dst_rect.x= x1;
- result |= (SDL_RenderCopy(renderer, texture, &source_rect , &dst_rect) == 0);
- write_width = texture_w;
-
- // now draw the rest
- // set the source x to 0
- source_rect.x = 0;
- while (pixels_written < w){
- if (write_width >= w - pixels_written) {
- write_width = w - pixels_written;
- }
- source_rect.w = write_width;
- dst_rect.x = x1 + pixels_written;
- result |= (SDL_RenderCopy(renderer,texture,&source_rect , &dst_rect) == 0);
- pixels_written += write_width;
- }
- }
-
- return result;
-}
-
-/*!
-\brief Draws a polygon filled with the given texture (Multi-Threading Capable).
-
-\param renderer The renderer to draw on.
-\param vx array of x vector components
-\param vy array of x vector components
-\param n the amount of vectors in the vx and vy array
-\param texture the sdl surface to use to fill the polygon
-\param texture_dx the offset of the texture relative to the screeen. If you move the polygon 10 pixels
-to the left and want the texture to apear the same you need to increase the texture_dx value
-\param texture_dy see texture_dx
-\param polyInts Preallocated temp array storage for vertex sorting (used for multi-threaded operation)
-\param polyAllocated Flag indicating oif the temp array was allocated (used for multi-threaded operation)
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int texturedPolygonMT(SDL_Renderer *renderer, const Sint16 * vx, const Sint16 * vy, int n,
- SDL_Surface * texture, int texture_dx, int texture_dy, int **polyInts, int *polyAllocated)
-{
- int result;
- int i;
- int y, xa, xb;
- int minx,maxx,miny, maxy;
- int x1, y1;
- int x2, y2;
- int ind1, ind2;
- int ints;
- int *gfxPrimitivesPolyInts = NULL;
- int gfxPrimitivesPolyAllocated = 0;
- SDL_Texture *textureAsTexture;
-
- /*
- * Sanity check number of edges
- */
- if (n < 3) {
- return -1;
- }
-
- /*
- * Map polygon cache
- */
- if ((polyInts==NULL) || (polyAllocated==NULL)) {
- /* Use global cache */
- gfxPrimitivesPolyInts = gfxPrimitivesPolyIntsGlobal;
- gfxPrimitivesPolyAllocated = gfxPrimitivesPolyAllocatedGlobal;
- } else {
- /* Use local cache */
- gfxPrimitivesPolyInts = *polyInts;
- gfxPrimitivesPolyAllocated = *polyAllocated;
- }
-
- /*
- * Allocate temp array, only grow array
- */
- if (!gfxPrimitivesPolyAllocated) {
- gfxPrimitivesPolyInts = (int *) malloc(sizeof(int) * n);
- gfxPrimitivesPolyAllocated = n;
- } else {
- if (gfxPrimitivesPolyAllocated < n) {
- gfxPrimitivesPolyInts = (int *) realloc(gfxPrimitivesPolyInts, sizeof(int) * n);
- gfxPrimitivesPolyAllocated = n;
- }
- }
-
- /*
- * Check temp array
- */
- if (gfxPrimitivesPolyInts==NULL) {
- gfxPrimitivesPolyAllocated = 0;
- }
-
- /*
- * Update cache variables
- */
- if ((polyInts==NULL) || (polyAllocated==NULL)) {
- gfxPrimitivesPolyIntsGlobal = gfxPrimitivesPolyInts;
- gfxPrimitivesPolyAllocatedGlobal = gfxPrimitivesPolyAllocated;
- } else {
- *polyInts = gfxPrimitivesPolyInts;
- *polyAllocated = gfxPrimitivesPolyAllocated;
- }
-
- /*
- * Check temp array again
- */
- if (gfxPrimitivesPolyInts==NULL) {
- return(-1);
- }
-
- /*
- * Determine X,Y minima,maxima
- */
- miny = vy[0];
- maxy = vy[0];
- minx = vx[0];
- maxx = vx[0];
- for (i = 1; (i < n); i++) {
- if (vy[i] < miny) {
- miny = vy[i];
- } else if (vy[i] > maxy) {
- maxy = vy[i];
- }
- if (vx[i] < minx) {
- minx = vx[i];
- } else if (vx[i] > maxx) {
- maxx = vx[i];
- }
- }
-
- /*
- * Draw, scanning y
- */
- result = 0;
- for (y = miny; (y <= maxy); y++) {
- ints = 0;
- for (i = 0; (i < n); i++) {
- if (!i) {
- ind1 = n - 1;
- ind2 = 0;
- } else {
- ind1 = i - 1;
- ind2 = i;
- }
- y1 = vy[ind1];
- y2 = vy[ind2];
- if (y1 < y2) {
- x1 = vx[ind1];
- x2 = vx[ind2];
- } else if (y1 > y2) {
- y2 = vy[ind1];
- y1 = vy[ind2];
- x2 = vx[ind1];
- x1 = vx[ind2];
- } else {
- continue;
- }
- if ( ((y >= y1) && (y < y2)) || ((y == maxy) && (y > y1) && (y <= y2)) ) {
- gfxPrimitivesPolyInts[ints++] = ((65536 * (y - y1)) / (y2 - y1)) * (x2 - x1) + (65536 * x1);
- }
- }
-
- qsort(gfxPrimitivesPolyInts, ints, sizeof(int), _gfxPrimitivesCompareInt);
-
- textureAsTexture = SDL_CreateTextureFromSurface(renderer, texture);
- if (textureAsTexture == NULL)
- {
- return (-1);
- }
-
- for (i = 0; (i < ints); i += 2) {
- xa = gfxPrimitivesPolyInts[i] + 1;
- xa = (xa >> 16) + ((xa & 32768) >> 15);
- xb = gfxPrimitivesPolyInts[i+1] - 1;
- xb = (xb >> 16) + ((xb & 32768) >> 15);
- result |= _HLineTextured(renderer, xa, xb, y, textureAsTexture, texture->w, texture->h, texture_dx, texture_dy);
- }
- SDL_DestroyTexture(textureAsTexture);
- }
-
- return (result);
-}
-
-/*!
-\brief Draws a polygon filled with the given texture.
-
-This standard version is calling multithreaded versions with NULL cache parameters.
-
-\param renderer The renderer to draw on.
-\param vx array of x vector components
-\param vy array of x vector components
-\param n the amount of vectors in the vx and vy array
-\param texture the sdl surface to use to fill the polygon
-\param texture_dx the offset of the texture relative to the screeen. if you move the polygon 10 pixels
-to the left and want the texture to apear the same you need to increase the texture_dx value
-\param texture_dy see texture_dx
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int texturedPolygon(SDL_Renderer *renderer, const Sint16 * vx, const Sint16 * vy, int n, SDL_Surface *texture, int texture_dx, int texture_dy)
-{
- /*
- * Draw
- */
- return (texturedPolygonMT(renderer, vx, vy, n, texture, texture_dx, texture_dy, NULL, NULL));
-}
-
-/* ---- Character */
-
-/*!
-\brief Global cache for NxM pixel font textures created at runtime.
-*/
-static SDL_Texture *gfxPrimitivesFont[256];
-
-/*!
-\brief Pointer to the current font data. Default is a 8x8 pixel internal font.
-*/
-static const unsigned char *currentFontdata = gfxPrimitivesFontdata;
-
-/*!
-\brief Width of the current font. Default is 8.
-*/
-static Uint32 charWidth = 8;
-
-/*!
-\brief Height of the current font. Default is 8.
-*/
-static Uint32 charHeight = 8;
-
-/*!
-\brief Width for rendering. Autocalculated.
-*/
-static Uint32 charWidthLocal = 8;
-
-/*!
-\brief Height for rendering. Autocalculated.
-*/
-static Uint32 charHeightLocal = 8;
-
-/*!
-\brief Pitch of the current font in bytes. Default is 1.
-*/
-static Uint32 charPitch = 1;
-
-/*!
-\brief Characters 90deg clockwise rotations. Default is 0. Max is 3.
-*/
-static Uint32 charRotation = 0;
-
-/*!
-\brief Character data size in bytes of the current font. Default is 8.
-*/
-static Uint32 charSize = 8;
-
-/*!
-\brief Sets or resets the current global font data.
-
-The font data array is organized in follows:
-[fontdata] = [character 0][character 1]...[character 255] where
-[character n] = [byte 1 row 1][byte 2 row 1]...[byte {pitch} row 1][byte 1 row 2] ...[byte {pitch} row height] where
-[byte n] = [bit 0]...[bit 7] where
-[bit n] = [0 for transparent pixel|1 for colored pixel]
-
-\param fontdata Pointer to array of font data. Set to NULL, to reset global font to the default 8x8 font.
-\param cw Width of character in bytes. Ignored if fontdata==NULL.
-\param ch Height of character in bytes. Ignored if fontdata==NULL.
-*/
-void gfxPrimitivesSetFont(const void *fontdata, Uint32 cw, Uint32 ch)
-{
- int i;
-
- if ((fontdata) && (cw) && (ch)) {
- currentFontdata = (unsigned char *)fontdata;
- charWidth = cw;
- charHeight = ch;
- } else {
- currentFontdata = gfxPrimitivesFontdata;
- charWidth = 8;
- charHeight = 8;
- }
-
- charPitch = (charWidth+7)/8;
- charSize = charPitch * charHeight;
-
- /* Maybe flip width/height for rendering */
- if ((charRotation==1) || (charRotation==3))
- {
- charWidthLocal = charHeight;
- charHeightLocal = charWidth;
- }
- else
- {
- charWidthLocal = charWidth;
- charHeightLocal = charHeight;
- }
-
- /* Clear character cache */
- for (i = 0; i < 256; i++) {
- if (gfxPrimitivesFont[i]) {
- SDL_DestroyTexture(gfxPrimitivesFont[i]);
- gfxPrimitivesFont[i] = NULL;
- }
- }
-}
-
-/*!
-\brief Sets current global font character rotation steps.
-
-Default is 0 (no rotation). 1 = 90deg clockwise. 2 = 180deg clockwise. 3 = 270deg clockwise.
-Changing the rotation, will reset the character cache.
-
-\param rotation Number of 90deg clockwise steps to rotate
-*/
-void gfxPrimitivesSetFontRotation(Uint32 rotation)
-{
- int i;
-
- rotation = rotation & 3;
- if (charRotation != rotation)
- {
- /* Store rotation */
- charRotation = rotation;
-
- /* Maybe flip width/height for rendering */
- if ((charRotation==1) || (charRotation==3))
- {
- charWidthLocal = charHeight;
- charHeightLocal = charWidth;
- }
- else
- {
- charWidthLocal = charWidth;
- charHeightLocal = charHeight;
- }
-
- /* Clear character cache */
- for (i = 0; i < 256; i++) {
- if (gfxPrimitivesFont[i]) {
- SDL_DestroyTexture(gfxPrimitivesFont[i]);
- gfxPrimitivesFont[i] = NULL;
- }
- }
- }
-}
-
-/*!
-\brief Draw a character of the currently set font.
-
-\param dst The surface to draw on.
-\param x X (horizontal) coordinate of the upper left corner of the character.
-\param y Y (vertical) coordinate of the upper left corner of the character.
-\param c The character to draw.
-\param r The red value of the character to draw.
-\param g The green value of the character to draw.
-\param b The blue value of the character to draw.
-\param a The alpha value of the character to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int characterRGBA(SDL_Renderer *renderer, Sint16 x, Sint16 y, char c, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- SDL_Rect srect;
- SDL_Rect drect;
- int result;
- Uint32 ix, iy;
- const unsigned char *charpos;
- Uint8 *curpos;
- Uint8 patt, mask;
- Uint8 *linepos;
- Uint32 pitch;
- SDL_Surface *character;
- SDL_Surface *rotatedCharacter;
- Uint32 ci;
-
- /*
- * Setup source rectangle
- */
- srect.x = 0;
- srect.y = 0;
- srect.w = charWidthLocal;
- srect.h = charHeightLocal;
-
- /*
- * Setup destination rectangle
- */
- drect.x = x;
- drect.y = y;
- drect.w = charWidthLocal;
- drect.h = charHeightLocal;
-
- /* Character index in cache */
- ci = (unsigned char) c;
-
- /*
- * Create new charWidth x charHeight bitmap surface if not already present.
- * Might get rotated later.
- */
- if (gfxPrimitivesFont[ci] == NULL) {
- /*
- * Redraw character into surface
- */
- character = SDL_CreateRGBSurface(SDL_SWSURFACE,
- charWidth, charHeight, 32,
- 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
- if (character == NULL) {
- return (-1);
- }
-
- charpos = currentFontdata + ci * charSize;
- linepos = (Uint8 *)character->pixels;
- pitch = character->pitch;
-
- /*
- * Drawing loop
- */
- patt = 0;
- for (iy = 0; iy < charHeight; iy++) {
- mask = 0x00;
- curpos = linepos;
- for (ix = 0; ix < charWidth; ix++) {
- if (!(mask >>= 1)) {
- patt = *charpos++;
- mask = 0x80;
- }
- if (patt & mask) {
- *(Uint32 *)curpos = 0xffffffff;
- } else {
- *(Uint32 *)curpos = 0;
- }
- curpos += 4;
- }
- linepos += pitch;
- }
-
- /* Maybe rotate and replace cached image */
- if (charRotation>0)
- {
- rotatedCharacter = rotateSurface90Degrees(character, charRotation);
- SDL_FreeSurface(character);
- character = rotatedCharacter;
- }
-
- /* Convert temp surface into texture */
- gfxPrimitivesFont[ci] = SDL_CreateTextureFromSurface(renderer, character);
- SDL_FreeSurface(character);
-
- /*
- * Check pointer
- */
- if (gfxPrimitivesFont[ci] == NULL) {
- return (-1);
- }
- }
-
- /*
- * Set color
- */
- result = 0;
- result |= SDL_SetTextureColorMod(gfxPrimitivesFont[ci], r, g, b);
- result |= SDL_SetTextureAlphaMod(gfxPrimitivesFont[ci], a);
-
- /*
- * Draw texture onto destination
- */
- result |= SDL_RenderCopy(renderer, gfxPrimitivesFont[ci], &srect, &drect);
-
- return (result);
-}
-
-
-/*!
-\brief Draw a character of the currently set font.
-
-\param renderer The renderer to draw on.
-\param x X (horizontal) coordinate of the upper left corner of the character.
-\param y Y (vertical) coordinate of the upper left corner of the character.
-\param c The character to draw.
-\param color The color value of the character to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int characterColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, char c, Uint32 color)
-{
- Uint8 *co = (Uint8 *)&color;
- return characterRGBA(renderer, x, y, c, co[0], co[1], co[2], co[3]);
-}
-
-
-/*!
-\brief Draw a string in the currently set font.
-
-The spacing between consequtive characters in the string is the fixed number of pixels
-of the character width of the current global font.
-
-\param renderer The renderer to draw on.
-\param x X (horizontal) coordinate of the upper left corner of the string.
-\param y Y (vertical) coordinate of the upper left corner of the string.
-\param s The string to draw.
-\param color The color value of the string to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int stringColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, const char *s, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return stringRGBA(renderer, x, y, s, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw a string in the currently set font.
-
-\param renderer The renderer to draw on.
-\param x X (horizontal) coordinate of the upper left corner of the string.
-\param y Y (vertical) coordinate of the upper left corner of the string.
-\param s The string to draw.
-\param r The red value of the string to draw.
-\param g The green value of the string to draw.
-\param b The blue value of the string to draw.
-\param a The alpha value of the string to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int stringRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, const char *s, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result = 0;
- Sint16 curx = x;
- Sint16 cury = y;
- const char *curchar = s;
-
- while (*curchar && !result) {
- result |= characterRGBA(renderer, curx, cury, *curchar, r, g, b, a);
- switch (charRotation)
- {
- case 0:
- curx += charWidthLocal;
- break;
- case 2:
- curx -= charWidthLocal;
- break;
- case 1:
- cury += charHeightLocal;
- break;
- case 3:
- cury -= charHeightLocal;
- break;
- }
- curchar++;
- }
-
- return (result);
-}
-
-/* ---- Bezier curve */
-
-/*!
-\brief Internal function to calculate bezier interpolator of data array with ndata values at position 't'.
-
-\param data Array of values.
-\param ndata Size of array.
-\param t Position for which to calculate interpolated value. t should be between [0, ndata].
-
-\returns Interpolated value at position t, value[0] when t<0, value[n-1] when t>n.
-*/
-double _evaluateBezier (double *data, int ndata, double t)
-{
- double mu, result;
- int n,k,kn,nn,nkn;
- double blend,muk,munk;
-
- /* Sanity check bounds */
- if (t<0.0) {
- return(data[0]);
- }
- if (t>=(double)ndata) {
- return(data[ndata-1]);
- }
-
- /* Adjust t to the range 0.0 to 1.0 */
- mu=t/(double)ndata;
-
- /* Calculate interpolate */
- n=ndata-1;
- result=0.0;
- muk = 1;
- munk = pow(1-mu,(double)n);
- for (k=0;k<=n;k++) {
- nn = n;
- kn = k;
- nkn = n - k;
- blend = muk * munk;
- muk *= mu;
- munk /= (1-mu);
- while (nn >= 1) {
- blend *= nn;
- nn--;
- if (kn > 1) {
- blend /= (double)kn;
- kn--;
- }
- if (nkn > 1) {
- blend /= (double)nkn;
- nkn--;
- }
- }
- result += data[k] * blend;
- }
-
- return (result);
-}
-
-/*!
-\brief Draw a bezier curve with alpha blending.
-
-\param renderer The renderer to draw on.
-\param vx Vertex array containing X coordinates of the points of the bezier curve.
-\param vy Vertex array containing Y coordinates of the points of the bezier curve.
-\param n Number of points in the vertex array. Minimum number is 3.
-\param s Number of steps for the interpolation. Minimum number is 2.
-\param color The color value of the bezier curve to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int bezierColor(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy, int n, int s, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return bezierRGBA(renderer, vx, vy, n, s, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw a bezier curve with alpha blending.
-
-\param renderer The renderer to draw on.
-\param vx Vertex array containing X coordinates of the points of the bezier curve.
-\param vy Vertex array containing Y coordinates of the points of the bezier curve.
-\param n Number of points in the vertex array. Minimum number is 3.
-\param s Number of steps for the interpolation. Minimum number is 2.
-\param r The red value of the bezier curve to draw.
-\param g The green value of the bezier curve to draw.
-\param b The blue value of the bezier curve to draw.
-\param a The alpha value of the bezier curve to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int bezierRGBA(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy, int n, int s, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result;
- int i;
- double *x, *y, t, stepsize;
- Sint16 x1, y1, x2, y2;
-
- /*
- * Sanity check
- */
- if (n < 3) {
- return (-1);
- }
- if (s < 2) {
- return (-1);
- }
-
- /*
- * Variable setup
- */
- stepsize=(double)1.0/(double)s;
-
- /* Transfer vertices into float arrays */
- if ((x=(double *)malloc(sizeof(double)*(n+1)))==NULL) {
- return(-1);
- }
- if ((y=(double *)malloc(sizeof(double)*(n+1)))==NULL) {
- free(x);
- return(-1);
- }
- for (i=0; i<n; i++) {
- x[i]=(double)vx[i];
- y[i]=(double)vy[i];
- }
- x[n]=(double)vx[0];
- y[n]=(double)vy[0];
-
- /*
- * Set color
- */
- result = 0;
- result |= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND);
- result |= SDL_SetRenderDrawColor(renderer, r, g, b, a);
-
- /*
- * Draw
- */
- t=0.0;
- x1=(Sint16)lrint(_evaluateBezier(x,n+1,t));
- y1=(Sint16)lrint(_evaluateBezier(y,n+1,t));
- for (i = 0; i <= (n*s); i++) {
- t += stepsize;
- x2=(Sint16)_evaluateBezier(x,n,t);
- y2=(Sint16)_evaluateBezier(y,n,t);
- result |= line(renderer, x1, y1, x2, y2);
- x1 = x2;
- y1 = y2;
- }
-
- /* Clean up temporary array */
- free(x);
- free(y);
-
- return (result);
-}
-
-
-/* ---- Thick Line */
-
-/*!
-\brief Internal function to initialize the Bresenham line iterator.
-
-Example of use:
-SDL2_gfxBresenhamIterator b;
-_bresenhamInitialize (&b, x1, y1, x2, y2);
-do {
-plot(b.x, b.y);
-} while (_bresenhamIterate(&b)==0);
-
-\param b Pointer to struct for bresenham line drawing state.
-\param x1 X coordinate of the first point of the line.
-\param y1 Y coordinate of the first point of the line.
-\param x2 X coordinate of the second point of the line.
-\param y2 Y coordinate of the second point of the line.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int _bresenhamInitialize(SDL2_gfxBresenhamIterator *b, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2)
-{
- int temp;
-
- if (b==NULL) {
- return(-1);
- }
-
- b->x = x1;
- b->y = y1;
-
- /* dx = abs(x2-x1), s1 = sign(x2-x1) */
- if ((b->dx = x2 - x1) != 0) {
- if (b->dx < 0) {
- b->dx = -b->dx;
- b->s1 = -1;
- } else {
- b->s1 = 1;
- }
- } else {
- b->s1 = 0;
- }
-
- /* dy = abs(y2-y1), s2 = sign(y2-y1) */
- if ((b->dy = y2 - y1) != 0) {
- if (b->dy < 0) {
- b->dy = -b->dy;
- b->s2 = -1;
- } else {
- b->s2 = 1;
- }
- } else {
- b->s2 = 0;
- }
-
- if (b->dy > b->dx) {
- temp = b->dx;
- b->dx = b->dy;
- b->dy = temp;
- b->swapdir = 1;
- } else {
- b->swapdir = 0;
- }
-
- b->count = (b->dx<0) ? 0 : (unsigned int)b->dx;
- b->dy <<= 1;
- b->error = b->dy - b->dx;
- b->dx <<= 1;
-
- return(0);
-}
-
-
-/*!
-\brief Internal function to move Bresenham line iterator to the next position.
-
-Maybe updates the x and y coordinates of the iterator struct.
-
-\param b Pointer to struct for bresenham line drawing state.
-
-\returns Returns 0 on success, 1 if last point was reached, 2 if moving past end-of-line, -1 on failure.
-*/
-int _bresenhamIterate(SDL2_gfxBresenhamIterator *b)
-{
- if (b==NULL) {
- return (-1);
- }
-
- /* last point check */
- if (b->count==0) {
- return (2);
- }
-
- while (b->error >= 0) {
- if (b->swapdir) {
- b->x += b->s1;
- } else {
- b->y += b->s2;
- }
-
- b->error -= b->dx;
- }
-
- if (b->swapdir) {
- b->y += b->s2;
- } else {
- b->x += b->s1;
- }
-
- b->error += b->dy;
- b->count--;
-
- /* count==0 indicates "end-of-line" */
- return ((b->count) ? 0 : 1);
-}
-
-
-/*!
-\brief Internal function to to draw parallel lines with Murphy algorithm.
-
-\param m Pointer to struct for murphy iterator.
-\param x X coordinate of point.
-\param y Y coordinate of point.
-\param d1 Direction square/diagonal.
-*/
-void _murphyParaline(SDL2_gfxMurphyIterator *m, Sint16 x, Sint16 y, int d1)
-{
- int p;
- d1 = -d1;
-
- for (p = 0; p <= m->u; p++) {
-
- pixel(m->renderer, x, y);
-
- if (d1 <= m->kt) {
- if (m->oct2 == 0) {
- x++;
- } else {
- if (m->quad4 == 0) {
- y++;
- } else {
- y--;
- }
- }
- d1 += m->kv;
- } else {
- x++;
- if (m->quad4 == 0) {
- y++;
- } else {
- y--;
- }
- d1 += m->kd;
- }
- }
-
- m->tempx = x;
- m->tempy = y;
-}
-
-/*!
-\brief Internal function to to draw one iteration of the Murphy algorithm.
-
-\param m Pointer to struct for murphy iterator.
-\param miter Iteration count.
-\param ml1bx X coordinate of a point.
-\param ml1by Y coordinate of a point.
-\param ml2bx X coordinate of a point.
-\param ml2by Y coordinate of a point.
-\param ml1x X coordinate of a point.
-\param ml1y Y coordinate of a point.
-\param ml2x X coordinate of a point.
-\param ml2y Y coordinate of a point.
-
-*/
-void _murphyIteration(SDL2_gfxMurphyIterator *m, Uint8 miter,
- Uint16 ml1bx, Uint16 ml1by, Uint16 ml2bx, Uint16 ml2by,
- Uint16 ml1x, Uint16 ml1y, Uint16 ml2x, Uint16 ml2y)
-{
- int atemp1, atemp2;
- int ftmp1, ftmp2;
- Uint16 m1x, m1y, m2x, m2y;
- Uint16 fix, fiy, lax, lay, curx, cury;
- Sint16 px[4], py[4];
- SDL2_gfxBresenhamIterator b;
-
- if (miter > 1) {
- if (m->first1x != -32768) {
- fix = (m->first1x + m->first2x) / 2;
- fiy = (m->first1y + m->first2y) / 2;
- lax = (m->last1x + m->last2x) / 2;
- lay = (m->last1y + m->last2y) / 2;
- curx = (ml1x + ml2x) / 2;
- cury = (ml1y + ml2y) / 2;
-
- atemp1 = (fix - curx);
- atemp2 = (fiy - cury);
- ftmp1 = atemp1 * atemp1 + atemp2 * atemp2;
- atemp1 = (lax - curx);
- atemp2 = (lay - cury);
- ftmp2 = atemp1 * atemp1 + atemp2 * atemp2;
-
- if (ftmp1 <= ftmp2) {
- m1x = m->first1x;
- m1y = m->first1y;
- m2x = m->first2x;
- m2y = m->first2y;
- } else {
- m1x = m->last1x;
- m1y = m->last1y;
- m2x = m->last2x;
- m2y = m->last2y;
- }
-
- atemp1 = (m2x - ml2x);
- atemp2 = (m2y - ml2y);
- ftmp1 = atemp1 * atemp1 + atemp2 * atemp2;
- atemp1 = (m2x - ml2bx);
- atemp2 = (m2y - ml2by);
- ftmp2 = atemp1 * atemp1 + atemp2 * atemp2;
-
- if (ftmp2 >= ftmp1) {
- ftmp1 = ml2bx;
- ftmp2 = ml2by;
- ml2bx = ml2x;
- ml2by = ml2y;
- ml2x = ftmp1;
- ml2y = ftmp2;
- ftmp1 = ml1bx;
- ftmp2 = ml1by;
- ml1bx = ml1x;
- ml1by = ml1y;
- ml1x = ftmp1;
- ml1y = ftmp2;
- }
-
- /*
- * Lock the surface
- */
- _bresenhamInitialize(&b, m2x, m2y, m1x, m1y);
- do {
- pixel(m->renderer, b.x, b.y);
- } while (_bresenhamIterate(&b)==0);
-
- _bresenhamInitialize(&b, m1x, m1y, ml1bx, ml1by);
- do {
- pixel(m->renderer, b.x, b.y);
- } while (_bresenhamIterate(&b)==0);
-
- _bresenhamInitialize(&b, ml1bx, ml1by, ml2bx, ml2by);
- do {
- pixel(m->renderer, b.x, b.y);
- } while (_bresenhamIterate(&b)==0);
-
- _bresenhamInitialize(&b, ml2bx, ml2by, m2x, m2y);
- do {
- pixel(m->renderer, b.x, b.y);
- } while (_bresenhamIterate(&b)==0);
-
- px[0] = m1x;
- px[1] = m2x;
- px[2] = ml1bx;
- px[3] = ml2bx;
- py[0] = m1y;
- py[1] = m2y;
- py[2] = ml1by;
- py[3] = ml2by;
- polygon(m->renderer, px, py, 4);
- }
- }
-
- m->last1x = ml1x;
- m->last1y = ml1y;
- m->last2x = ml2x;
- m->last2y = ml2y;
- m->first1x = ml1bx;
- m->first1y = ml1by;
- m->first2x = ml2bx;
- m->first2y = ml2by;
-}
-
-
-#define HYPOT(x,y) sqrt((double)(x)*(double)(x)+(double)(y)*(double)(y))
-
-/*!
-\brief Internal function to to draw wide lines with Murphy algorithm.
-
-Draws lines parallel to ideal line.
-
-\param m Pointer to struct for murphy iterator.
-\param x1 X coordinate of first point.
-\param y1 Y coordinate of first point.
-\param x2 X coordinate of second point.
-\param y2 Y coordinate of second point.
-\param width Width of line.
-\param miter Iteration count.
-
-*/
-void _murphyWideline(SDL2_gfxMurphyIterator *m, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 width, Uint8 miter)
-{
- float offset = (float)width / 2.f;
-
- Sint16 temp;
- Sint16 ptx, pty, ptxx, ptxy, ml1x, ml1y, ml2x, ml2y, ml1bx, ml1by, ml2bx, ml2by;
-
- int d0, d1; /* difference terms d0=perpendicular to line, d1=along line */
-
- int q; /* pel counter,q=perpendicular to line */
- int tmp;
-
- int dd; /* distance along line */
- int tk; /* thickness threshold */
- double ang; /* angle for initial point calculation */
- double sang, cang;
-
- /* Initialisation */
- m->u = x2 - x1; /* delta x */
- m->v = y2 - y1; /* delta y */
-
- if (m->u < 0) { /* swap to make sure we are in quadrants 1 or 4 */
- temp = x1;
- x1 = x2;
- x2 = temp;
- temp = y1;
- y1 = y2;
- y2 = temp;
- m->u *= -1;
- m->v *= -1;
- }
-
- if (m->v < 0) { /* swap to 1st quadrant and flag */
- m->v *= -1;
- m->quad4 = 1;
- } else {
- m->quad4 = 0;
- }
-
- if (m->v > m->u) { /* swap things if in 2 octant */
- tmp = m->u;
- m->u = m->v;
- m->v = tmp;
- m->oct2 = 1;
- } else {
- m->oct2 = 0;
- }
-
- m->ku = m->u + m->u; /* change in l for square shift */
- m->kv = m->v + m->v; /* change in d for square shift */
- m->kd = m->kv - m->ku; /* change in d for diagonal shift */
- m->kt = m->u - m->kv; /* diag/square decision threshold */
-
- d0 = 0;
- d1 = 0;
- dd = 0;
-
- ang = atan((double) m->v / (double) m->u); /* calc new initial point - offset both sides of ideal */
- sang = sin(ang);
- cang = cos(ang);
-
- if (m->oct2 == 0) {
- ptx = x1 + (Sint16)lrint(offset * sang);
- if (m->quad4 == 0) {
- pty = y1 - (Sint16)lrint(offset * cang);
- } else {
- pty = y1 + (Sint16)lrint(offset * cang);
- }
- } else {
- ptx = x1 - (Sint16)lrint(offset * cang);
- if (m->quad4 == 0) {
- pty = y1 + (Sint16)lrint(offset * sang);
- } else {
- pty = y1 - (Sint16)lrint(offset * sang);
- }
- }
-
- /* used here for constant thickness line */
- tk = (int) (4. * HYPOT(ptx - x1, pty - y1) * HYPOT(m->u, m->v));
-
- if (miter == 0) {
- m->first1x = -32768;
- m->first1y = -32768;
- m->first2x = -32768;
- m->first2y = -32768;
- m->last1x = -32768;
- m->last1y = -32768;
- m->last2x = -32768;
- m->last2y = -32768;
- }
- ptxx = ptx;
- ptxy = pty;
-
- for (q = 0; dd <= tk; q++) { /* outer loop, stepping perpendicular to line */
-
- _murphyParaline(m, ptx, pty, d1); /* call to inner loop - right edge */
- if (q == 0) {
- ml1x = ptx;
- ml1y = pty;
- ml1bx = m->tempx;
- ml1by = m->tempy;
- } else {
- ml2x = ptx;
- ml2y = pty;
- ml2bx = m->tempx;
- ml2by = m->tempy;
- }
- if (d0 < m->kt) { /* square move */
- if (m->oct2 == 0) {
- if (m->quad4 == 0) {
- pty++;
- } else {
- pty--;
- }
- } else {
- ptx++;
- }
- } else { /* diagonal move */
- dd += m->kv;
- d0 -= m->ku;
- if (d1 < m->kt) { /* normal diagonal */
- if (m->oct2 == 0) {
- ptx--;
- if (m->quad4 == 0) {
- pty++;
- } else {
- pty--;
- }
- } else {
- ptx++;
- if (m->quad4 == 0) {
- pty--;
- } else {
- pty++;
- }
- }
- d1 += m->kv;
- } else { /* double square move, extra parallel line */
- if (m->oct2 == 0) {
- ptx--;
- } else {
- if (m->quad4 == 0) {
- pty--;
- } else {
- pty++;
- }
- }
- d1 += m->kd;
- if (dd > tk) {
- _murphyIteration(m, miter, ml1bx, ml1by, ml2bx, ml2by, ml1x, ml1y, ml2x, ml2y);
- return; /* breakout on the extra line */
- }
- _murphyParaline(m, ptx, pty, d1);
- if (m->oct2 == 0) {
- if (m->quad4 == 0) {
- pty++;
- } else {
-
- pty--;
- }
- } else {
- ptx++;
- }
- }
- }
- dd += m->ku;
- d0 += m->kv;
- }
-
- _murphyIteration(m, miter, ml1bx, ml1by, ml2bx, ml2by, ml1x, ml1y, ml2x, ml2y);
-}
-
-
-/*!
-\brief Draw a thick line with alpha blending.
-
-\param dst The surface to draw on.
-\param x1 X coordinate of the first point of the line.
-\param y1 Y coordinate of the first point of the line.
-\param x2 X coordinate of the second point of the line.
-\param y2 Y coordinate of the second point of the line.
-\param width Width of the line in pixels. Must be >0.
-\param color The color value of the line to draw (0xRRGGBBAA).
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int thickLineColor(SDL_Renderer *renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 width, Uint32 color)
-{
- Uint8 *c = (Uint8 *)&color;
- return thickLineRGBA(renderer, x1, y1, x2, y2, width, c[0], c[1], c[2], c[3]);
-}
-
-/*!
-\brief Draw a thick line with alpha blending.
-
-\param dst The surface to draw on.
-\param x1 X coordinate of the first point of the line.
-\param y1 Y coordinate of the first point of the line.
-\param x2 X coordinate of the second point of the line.
-\param y2 Y coordinate of the second point of the line.
-\param width Width of the line in pixels. Must be >0.
-\param r The red value of the character to draw.
-\param g The green value of the character to draw.
-\param b The blue value of the character to draw.
-\param a The alpha value of the character to draw.
-
-\returns Returns 0 on success, -1 on failure.
-*/
-int thickLineRGBA(SDL_Renderer *renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 width, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- int result;
- int wh;
- SDL2_gfxMurphyIterator m;
-
- if (renderer == NULL) {
- return -1;
- }
- if (width < 1) {
- return -1;
- }
-
- /* Special case: thick "point" */
- if ((x1 == x2) && (y1 == y2)) {
- wh = width / 2;
- return boxRGBA(renderer, x1 - wh, y1 - wh, x2 + width, y2 + width, r, g, b, a);
- }
-
- /*
- * Set color
- */
- result = 0;
- result |= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND);
- result |= SDL_SetRenderDrawColor(renderer, r, g, b, a);
-
- /*
- * Draw
- */
- m.renderer = renderer;
- _murphyWideline(&m, x1, y1, x2, y2, width, 0);
- _murphyWideline(&m, x1, y1, x2, y2, width, 1);
-
- return(0);
-}