Files
Sprinter-SDCC/libc/bgi/_bgi_trig.c
T
snark13 5a48f7fafb libc: BGI Фаза 2a — arc/ellipse/drawpoly
Дуги/эллипсы через целочисленную тригонометрию Q7 (_bgi_trig.c, ×128) +
общий рисователь полилинией (_bgi_arc_draw.c). arc(x,y,st,end,r),
ellipse(x,y,st,end,xr,yr), drawpoly(n,pts). Проверено в MAME (tests/
bgitest): окружность/эллипс/дуга/полигон рисуются корректно.

ВАЖНО: тригонометрию считаем в int (Q7), НЕ через (long)…>>8 — первая
версия на 32-бит арифметике рисовала эллипс прямоугольником (SDCC/z80
криво собирает 32-бит; см. memory/avoid_32bit_arith_z80). Q7 даёт
радиус×значение ≤ 255×128 < 32767 — всё влезает в 16 бит.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 15:50:00 +03:00

44 lines
1.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* _bgi_trig — целочисленная тригонометрия для дуг/эллипсов BGI.
*
* Угол в градусах (Turbo-C); sin/cos масштабированы на 128 (Q7):
* _bgi_sin128(90) = 128. Масштаб 128 (а не 256) выбран так, чтобы
* произведение радиус×значение помещалось в 16-бит int для любого
* экранного радиуса (255×128 = 32640 < 32767) — и НЕ приходилось
* трогать 32-битную арифметику, которую SDCC/Z80 собирает криво
* (см. memory/avoid_32bit_arith_z80; ловили эллипс-в-прямоугольник).
*/
#include "_bgi.h"
/* sin(0°..90°) × 128. */
static const int _bgi_sintab[91] = {
0, 2, 4, 7, 9, 11, 13, 16, 18, 20,
22, 24, 27, 29, 31, 33, 35, 37, 40, 42,
44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
64, 66, 68, 70, 72, 73, 75, 77, 79, 81,
82, 84, 86, 87, 89, 91, 92, 94, 95, 97,
98, 99, 101, 102, 104, 105, 106, 107, 109, 110,
111, 112, 113, 114, 115, 116, 117, 118, 119, 119,
120, 121, 122, 122, 123, 124, 124, 125, 125, 126,
126, 126, 127, 127, 127, 128, 128, 128, 128, 128,
128,
};
/* sin(угол°) × 128, угол приводится к 0..359. */
int _bgi_sin128(int deg)
{
deg %= 360;
if (deg < 0) deg += 360;
if (deg <= 90) return _bgi_sintab[deg];
if (deg <= 180) return _bgi_sintab[180 - deg];
if (deg <= 270) return -_bgi_sintab[deg - 180];
return -_bgi_sintab[360 - deg];
}
/* cos(угол°) × 128 = sin(угол+90). */
int _bgi_cos128(int deg)
{
return _bgi_sin128(deg + 90);
}