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>
This commit is contained in:
2026-07-08 15:50:00 +03:00
parent e761d21505
commit 5a48f7fafb
9 changed files with 162 additions and 29 deletions
+30 -28
View File
@@ -1,61 +1,63 @@
/*
* bgitest — демонстрация BGI-слоя graphics.h (режим 320×256×256).
*
* Собирается с `--gfx 256` (см. Makefile). Рисует рамку, заголовок,
* палитровую полосу, веер линий, вложенные окружности и залитые бары —
* визуальная проверка ядра BGI (Фаза 1).
* Собирается с `--gfx 256` (см. Makefile). Показывает примитивы
* Фазы 1 (рамка/бары/линии/окружность/текст) и Фазы 2a
* (эллипс/дуга/полигон) — визуальная проверка в MAME.
*/
#include <graphics.h>
int main(void)
{
int i, mx, my, cx, cy;
int i, mx, my;
/* треугольник для drawpoly (замкнут повтором первой точки). */
static const int tri[] = { 120, 244, 210, 244, 165, 210, 120, 244 };
initgraph();
mx = getmaxx(); /* 319 */
my = getmaxy(); /* 255 */
cx = mx / 2;
cy = my / 2;
cleardevice();
/* Рамка по краю экрана. */
setcolor(WHITE);
rectangle(0, 0, mx, my);
/* Заголовок. */
setcolor(YELLOW);
outtextxy(88, 6, "SPRINTER BGI 256");
outtextxy(96, 6, "SPRINTER BGI P2");
/* Палитровая полоса: 15 залитых баров цветами 1..15. */
for (i = 1; i <= 15; i++) {
int x0 = 8 + (i - 1) * 20;
setcolor(i);
bar(x0, 24, x0 + 16, 44);
bar(x0, 22, x0 + 16, 40);
}
/* Веер линий из центра к верхней кромке. */
for (i = 0; i <= mx; i += 16) {
setcolor(1 + (i / 16) % 15);
line(cx, cy, i, 52);
}
/* Окружность (Фаза 1). */
setcolor(LIGHTRED);
circle(60, 120, 40);
/* Вложенные окружности. */
for (i = 8; i < 90; i += 8) {
setcolor(9 + (i / 8) % 7);
circle(cx, cy, i);
}
/* Полный эллипс (Фаза 2a). */
setcolor(LIGHTGREEN);
ellipse(165, 120, 0, 360, 70, 40);
/* Точечная диагональ (putpixel). */
for (i = 0; i < 60; i++)
putpixel(10 + i, 200 + i, LIGHTGREEN);
/* Подпись внизу текущей позицией (outtext). */
/* Верхняя половина дуги (Фаза 2a). */
setcolor(LIGHTCYAN);
moveto(8, 240);
outtext("Phase 1: lines rects circles text");
arc(270, 140, 0, 180, 35);
/* Треугольник через drawpoly (Фаза 2a). */
setcolor(LIGHTMAGENTA);
drawpoly(4, tri);
/* Веер линий слева. */
for (i = 150; i <= my - 6; i += 8) {
setcolor(1 + ((i - 150) / 8) % 15);
line(6, 175, 110, i);
}
setcolor(YELLOW);
outtextxy(120, 190, "circle ellipse arc poly");
for (;;) { } /* держим картинку на экране */
return 0;
}