Skip to content

Commit 7187c19

Browse files
committed
#1510: big circles fix by @ddelemeny
1 parent 2d5a15e commit 7187c19

File tree

1 file changed

+40
-51
lines changed

1 file changed

+40
-51
lines changed

src/core/draw.c

+40-51
Original file line numberDiff line numberDiff line change
@@ -477,34 +477,46 @@ static void setSideTexPixel(s32 x, s32 y, float u, float v)
477477
}
478478
}
479479

480-
static void drawEllipse(tic_mem* memory, s32 x0, s32 y0, s32 x1, s32 y1, u8 color, PixelFunc pix)
480+
static void drawEllipse(tic_mem* memory, s64 x0, s64 y0, s64 a, s64 b, u8 color, PixelFunc pix)
481481
{
482-
s32 a = abs(x1-x0), b = abs(y1-y0), b1 = b&1; /* values of diameter */
483-
s32 dx = 4*(1-a)*b*b, dy = 4*(b1+1)*a*a; /* error increment */
484-
s32 err = dx+dy+b1*a*a, e2; /* error of 1.step */
482+
if(a <= 0) return;
483+
if(b <= 0) return;
485484

486-
if (x0 > x1) { x0 = x1; x1 += a; } /* if called with swapped pos32s */
487-
if (y0 > y1) y0 = y1; /* .. exchange them */
488-
y0 += (b+1)/2; y1 = y0-b1; /* starting pixel */
489-
a *= 8*a; b1 = 8*b*b;
485+
s64 aa2 = a*a*2, bb2 = b*b*2;
490486

491-
do
492487
{
493-
pix(memory, x1, y0, color); /* I. Quadrant */
494-
pix(memory, x0, y0, color); /* II. Quadrant */
495-
pix(memory, x0, y1, color); /* III. Quadrant */
496-
pix(memory, x1, y1, color); /* IV. Quadrant */
497-
e2 = 2*err;
498-
if (e2 <= dy) { y0++; y1--; err += dy += a; } /* y step */
499-
if (e2 >= dx || 2*err > dy) { x0++; x1--; err += dx += b1; } /* x step */
500-
} while (x0 <= x1);
501-
502-
while (y0-y1 < b)
503-
{ /* too early stop of flat ellipses a=1 */
504-
pix(memory, x0-1, y0, color); /* -> finish tip of ellipse */
505-
pix(memory, x1+1, y0++, color);
506-
pix(memory, x0-1, y1, color);
507-
pix(memory, x1+1, y1--, color);
488+
s64 x = a, y = 0;
489+
s64 dx = (1-2*a)*b*b, dy = a*a;
490+
s64 sx = bb2*a, sy=0;
491+
s64 e = 0;
492+
493+
while (sx >= sy)
494+
{
495+
pix(memory, (s32)(x0+x), (s32)(y0+y), color); /* I. Quadrant */
496+
pix(memory, (s32)(x0+x), (s32)(y0-y), color); /* II. Quadrant */
497+
pix(memory, (s32)(x0-x), (s32)(y0+y), color); /* III. Quadrant */
498+
pix(memory, (s32)(x0-x), (s32)(y0-y), color); /* IV. Quadrant */
499+
y++; sy += aa2; e += dy; dy += aa2;
500+
if(2*e+dx >0) { x--; sx -= bb2; e += dx; dx += bb2; }
501+
}
502+
}
503+
504+
{
505+
s64 x = 0, y = b;
506+
s64 dx = b*b, dy = (1-2*b)*a*a;
507+
s64 sx = 0, sy=aa2*b;
508+
s64 e = 0;
509+
510+
while (sy >= sx)
511+
{
512+
pix(memory, (s32)(x0+x), (s32)(y0+y), color); /* I. Quadrant */
513+
pix(memory, (s32)(x0+x), (s32)(y0-y), color); /* II. Quadrant */
514+
pix(memory, (s32)(x0-x), (s32)(y0+y), color); /* III. Quadrant */
515+
pix(memory, (s32)(x0-x), (s32)(y0-y), color); /* IV. Quadrant */
516+
517+
x++; sx += bb2; e += dx; dx += bb2;
518+
if(2*e+dy >0) { y--; sy -= aa2; e += dy; dy += aa2; }
519+
}
508520
}
509521
}
510522

@@ -532,51 +544,28 @@ static void drawSidesBuffer(tic_mem* memory, s32 y0, s32 y1, u8 color)
532544
}
533545
}
534546

535-
static void drawCirc(tic_mem* memory, s32 xm, s32 ym, s32 radius, u8 color, PixelFunc pix)
536-
{
537-
s32 r = radius;
538-
s32 x = -r, y = 0, err = 2 - 2 * r;
539-
do {
540-
pix(memory, xm - x, ym + y, color);
541-
pix(memory, xm - y, ym - x, color);
542-
pix(memory, xm + x, ym - y, color);
543-
pix(memory, xm + y, ym + x, color);
544-
r = err;
545-
if (r <= y) err += ++y * 2 + 1;
546-
if (r > x || err > y) err += ++x * 2 + 1;
547-
} while (x < 0);
548-
}
549-
550547
void tic_api_circ(tic_mem* memory, s32 x, s32 y, s32 r, u8 color)
551548
{
552-
if(r < 0) return;
553-
554549
initSidesBuffer();
555-
drawCirc(memory, x, y, r, 0, setElliSide);
550+
drawEllipse(memory, x, y, r, r, 0, setElliSide);
556551
drawSidesBuffer(memory, y - r, y + r + 1, color);
557552
}
558553

559554
void tic_api_circb(tic_mem* memory, s32 x, s32 y, s32 r, u8 color)
560555
{
561-
if(r < 0) return;
562-
563-
drawCirc(memory, x, y, r, mapColor(memory, color), setElliPixel);
556+
drawEllipse(memory, x, y, r, r, mapColor(memory, color), setElliPixel);
564557
}
565558

566559
void tic_api_elli(tic_mem* memory, s32 x, s32 y, s32 a, s32 b, u8 color)
567560
{
568-
if(a < 0 || b < 0) return;
569-
570561
initSidesBuffer();
571-
drawEllipse(memory, x - a, y - b, x + a, y + b, 0, setElliSide);
562+
drawEllipse(memory, x , y, a, b, 0, setElliSide);
572563
drawSidesBuffer(memory, y - b, y + b + 1, color);
573564
}
574565

575566
void tic_api_ellib(tic_mem* memory, s32 x, s32 y, s32 a, s32 b, u8 color)
576567
{
577-
if(a < 0 || b < 0) return;
578-
579-
drawEllipse(memory, x - a, y - b, x + a, y + b, mapColor(memory, color), setElliPixel);
568+
drawEllipse(memory, x, y, a, b, mapColor(memory, color), setElliPixel);
580569
}
581570

582571
static void ticLine(tic_mem* memory, s32 x0, s32 y0, s32 x1, s32 y1, u8 color, PixelFunc func)

0 commit comments

Comments
 (0)