libc: BGI Фаза 2d-2 — setlinestyle (стили и толщина линий)
setlinestyle/getlinesettings: SOLID/DOTTED/CENTER/DASHED/USERBIT + NORM/THICK. _bgi_styled_line — Брезенхэм с 16-битной маской (пропуск пикселя по биту) и дублированием ±1 перпендикулярно оси для THICK; SOLID+NORM идёт быстрым путём (accel _bgi_lineseg). line/lineto/linerel/ rectangle/drawpoly переведены на него. Проверено в MAME (tests/bgitest). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,7 @@ banked 1056
|
|||||||
bankedbg 1067
|
bankedbg 1067
|
||||||
banklocl 4832
|
banklocl 4832
|
||||||
banktest 3767
|
banktest 3767
|
||||||
bgitest 5482
|
bgitest 3896
|
||||||
bios_text 4470
|
bios_text 4470
|
||||||
cat 915
|
cat 915
|
||||||
cblstream 6277
|
cblstream 6277
|
||||||
|
|||||||
|
@@ -58,6 +58,14 @@ void _bgi_ellipse_arc(int cx, int cy, int stangle, int endangle,
|
|||||||
/* Целочисленный sqrt (0..~32767) для fillellipse (_bgi_isqrt.c). */
|
/* Целочисленный sqrt (0..~32767) для fillellipse (_bgi_isqrt.c). */
|
||||||
int _bgi_isqrt(int n);
|
int _bgi_isqrt(int n);
|
||||||
|
|
||||||
|
/* ---- Состояние линий (_bgi_line_state.c) ------------------------- */
|
||||||
|
extern uint8_t _bgi_line_style; /* SOLID_LINE..USERBIT_LINE */
|
||||||
|
extern uint8_t _bgi_line_thick; /* 1 (NORM) или 3 (THICK) */
|
||||||
|
extern uint16_t _bgi_line_pattern; /* маска для USERBIT_LINE */
|
||||||
|
|
||||||
|
/* Отрезок текущим стилем/толщиной линии (_bgi_styled_line.c). */
|
||||||
|
void _bgi_styled_line(int x0, int y0, int x1, int y1, uint8_t color);
|
||||||
|
|
||||||
/* ---- Состояние заливки (_bgi_fill_state.c) ----------------------- */
|
/* ---- Состояние заливки (_bgi_fill_state.c) ----------------------- */
|
||||||
extern uint8_t _bgi_fill_pattern; /* *_FILL */
|
extern uint8_t _bgi_fill_pattern; /* *_FILL */
|
||||||
extern uint8_t _bgi_fill_color;
|
extern uint8_t _bgi_fill_color;
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* _bgi_line_state — текущий стиль/толщина/маска линий BGI.
|
||||||
|
* initgraph ставит SOLID_LINE / NORM / 0xFFFF. Без инициализации.
|
||||||
|
*/
|
||||||
|
#include "_bgi.h"
|
||||||
|
|
||||||
|
uint8_t _bgi_line_style;
|
||||||
|
uint8_t _bgi_line_thick;
|
||||||
|
uint16_t _bgi_line_pattern;
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* _bgi_styled_line — отрезок текущим стилем и толщиной линии.
|
||||||
|
*
|
||||||
|
* SOLID+NORM → быстрый _bgi_lineseg (accel). Иначе — Брезенхэм с
|
||||||
|
* 16-битной маской (бит на шаг; когда бит 0 — пропуск) и, для THICK,
|
||||||
|
* дублированием перпендикулярно основной оси (±1). Всё raw в одной
|
||||||
|
* W3-скобке.
|
||||||
|
*/
|
||||||
|
#include "_bgi.h"
|
||||||
|
|
||||||
|
/* Маски стандартных стилей (SOLID/DOTTED/CENTER/DASHED). */
|
||||||
|
static const uint16_t _bgi_line_pat[4] = { 0xFFFF, 0xCCCC, 0xFF18, 0xF8F8 };
|
||||||
|
|
||||||
|
void _bgi_styled_line(int x0, int y0, int x1, int y1, uint8_t color)
|
||||||
|
{
|
||||||
|
uint16_t pat;
|
||||||
|
uint8_t bit, style, thick;
|
||||||
|
int dx, dy, sx, sy, err, e2, major_x;
|
||||||
|
|
||||||
|
style = _bgi_line_style;
|
||||||
|
thick = _bgi_line_thick;
|
||||||
|
if (style == SOLID_LINE && thick <= 1) {
|
||||||
|
_bgi_lineseg(x0, y0, x1, y1, color);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pat = (style == USERBIT_LINE) ? _bgi_line_pattern
|
||||||
|
: _bgi_line_pat[style & 3];
|
||||||
|
|
||||||
|
dx = x1 - x0; if (dx < 0) dx = -dx;
|
||||||
|
dy = y1 - y0; if (dy < 0) dy = -dy;
|
||||||
|
sx = (x0 < x1) ? 1 : -1;
|
||||||
|
sy = (y0 < y1) ? 1 : -1;
|
||||||
|
err = dx - dy;
|
||||||
|
major_x = (dx >= dy);
|
||||||
|
bit = 0;
|
||||||
|
|
||||||
|
_bgi_begin();
|
||||||
|
for (;;) {
|
||||||
|
if ((pat >> (bit & 15)) & 1) {
|
||||||
|
_bgi_plot_raw(x0, y0, color);
|
||||||
|
if (thick > 1) {
|
||||||
|
if (major_x) {
|
||||||
|
_bgi_plot_raw(x0, y0 - 1, color);
|
||||||
|
_bgi_plot_raw(x0, y0 + 1, color);
|
||||||
|
} else {
|
||||||
|
_bgi_plot_raw(x0 - 1, y0, color);
|
||||||
|
_bgi_plot_raw(x0 + 1, y0, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bit++;
|
||||||
|
if (x0 == x1 && y0 == y1) break;
|
||||||
|
e2 = 2 * err;
|
||||||
|
if (e2 > -dy) { err -= dy; x0 += sx; }
|
||||||
|
if (e2 < dx) { err += dx; y0 += sy; }
|
||||||
|
}
|
||||||
|
_bgi_end();
|
||||||
|
}
|
||||||
+1
-1
@@ -10,7 +10,7 @@ void drawpoly(int numpoints, const int *polypoints)
|
|||||||
int i;
|
int i;
|
||||||
if (numpoints < 2) return;
|
if (numpoints < 2) return;
|
||||||
for (i = 0; i < numpoints - 1; i++) {
|
for (i = 0; i < numpoints - 1; i++) {
|
||||||
_bgi_lineseg(polypoints[2 * i], polypoints[2 * i + 1],
|
_bgi_styled_line(polypoints[2 * i], polypoints[2 * i + 1],
|
||||||
polypoints[2 * i + 2], polypoints[2 * i + 3],
|
polypoints[2 * i + 2], polypoints[2 * i + 3],
|
||||||
_bgi_fg);
|
_bgi_fg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
/* getlinesettings — прочитать текущий стиль/маску/толщину линий. */
|
||||||
|
#include "_bgi.h"
|
||||||
|
|
||||||
|
void getlinesettings(struct linesettingstype *lineinfo)
|
||||||
|
{
|
||||||
|
if (!lineinfo) return;
|
||||||
|
lineinfo->linestyle = _bgi_line_style;
|
||||||
|
lineinfo->upattern = _bgi_line_pattern;
|
||||||
|
lineinfo->thickness = _bgi_line_thick;
|
||||||
|
}
|
||||||
@@ -17,4 +17,7 @@ void initgraph(void)
|
|||||||
_bgi_result = grOk;
|
_bgi_result = grOk;
|
||||||
_bgi_fill_pattern = SOLID_FILL;
|
_bgi_fill_pattern = SOLID_FILL;
|
||||||
_bgi_fill_color = WHITE;
|
_bgi_fill_color = WHITE;
|
||||||
|
_bgi_line_style = SOLID_LINE;
|
||||||
|
_bgi_line_thick = NORM_WIDTH;
|
||||||
|
_bgi_line_pattern = 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -3,5 +3,5 @@
|
|||||||
|
|
||||||
void line(int x1, int y1, int x2, int y2)
|
void line(int x1, int y1, int x2, int y2)
|
||||||
{
|
{
|
||||||
_bgi_lineseg(x1, y1, x2, y2, _bgi_fg);
|
_bgi_styled_line(x1, y1, x2, y2, _bgi_fg);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ void linerel(int dx, int dy)
|
|||||||
{
|
{
|
||||||
int nx = _bgi_cx + dx;
|
int nx = _bgi_cx + dx;
|
||||||
int ny = _bgi_cy + dy;
|
int ny = _bgi_cy + dy;
|
||||||
_bgi_lineseg(_bgi_cx, _bgi_cy, nx, ny, _bgi_fg);
|
_bgi_styled_line(_bgi_cx, _bgi_cy, nx, ny, _bgi_fg);
|
||||||
_bgi_cx = nx;
|
_bgi_cx = nx;
|
||||||
_bgi_cy = ny;
|
_bgi_cy = ny;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
void lineto(int x, int y)
|
void lineto(int x, int y)
|
||||||
{
|
{
|
||||||
_bgi_lineseg(_bgi_cx, _bgi_cy, x, y, _bgi_fg);
|
_bgi_styled_line(_bgi_cx, _bgi_cy, x, y, _bgi_fg);
|
||||||
_bgi_cx = x;
|
_bgi_cx = x;
|
||||||
_bgi_cy = y;
|
_bgi_cy = y;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
void rectangle(int left, int top, int right, int bottom)
|
void rectangle(int left, int top, int right, int bottom)
|
||||||
{
|
{
|
||||||
uint8_t c = _bgi_fg;
|
uint8_t c = _bgi_fg;
|
||||||
_bgi_lineseg(left, top, right, top, c); /* верх */
|
_bgi_styled_line(left, top, right, top, c); /* верх */
|
||||||
_bgi_lineseg(right, top, right, bottom, c); /* право */
|
_bgi_styled_line(right, top, right, bottom, c); /* право */
|
||||||
_bgi_lineseg(right, bottom, left, bottom, c); /* низ */
|
_bgi_styled_line(right, bottom, left, bottom, c); /* низ */
|
||||||
_bgi_lineseg(left, bottom, left, top, c); /* лево */
|
_bgi_styled_line(left, bottom, left, top, c); /* лево */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
/* setlinestyle — задать стиль, пользовательскую маску и толщину линий. */
|
||||||
|
#include "_bgi.h"
|
||||||
|
|
||||||
|
void setlinestyle(int linestyle, unsigned upattern, int thickness)
|
||||||
|
{
|
||||||
|
_bgi_line_style = (uint8_t)linestyle;
|
||||||
|
_bgi_line_pattern = (uint16_t)upattern;
|
||||||
|
_bgi_line_thick = (thickness >= THICK_WIDTH) ? THICK_WIDTH : NORM_WIDTH;
|
||||||
|
}
|
||||||
@@ -93,6 +93,19 @@ void ellipse(int x, int y, int stangle, int endangle,
|
|||||||
/* Ломаная по numpoints точкам {x0,y0,x1,y1,…}; НЕ замыкается сама. */
|
/* Ломаная по numpoints точкам {x0,y0,x1,y1,…}; НЕ замыкается сама. */
|
||||||
void drawpoly(int numpoints, const int *polypoints);
|
void drawpoly(int numpoints, const int *polypoints);
|
||||||
|
|
||||||
|
/* ---- Стиль линий ------------------------------------------------- *
|
||||||
|
* Действует на line/lineto/linerel/rectangle/drawpoly. USERBIT_LINE
|
||||||
|
* использует 16-битный upattern. thickness: NORM_WIDTH или THICK_WIDTH.
|
||||||
|
* (Окружности/дуги пока всегда сплошные 1px — упрощение.) */
|
||||||
|
enum { SOLID_LINE = 0, DOTTED_LINE, CENTER_LINE, DASHED_LINE, USERBIT_LINE };
|
||||||
|
#define NORM_WIDTH 1
|
||||||
|
#define THICK_WIDTH 3
|
||||||
|
|
||||||
|
struct linesettingstype { int linestyle; unsigned upattern; int thickness; };
|
||||||
|
|
||||||
|
void setlinestyle(int linestyle, unsigned upattern, int thickness);
|
||||||
|
void getlinesettings(struct linesettingstype *lineinfo);
|
||||||
|
|
||||||
/* ---- Заливки ----------------------------------------------------- *
|
/* ---- Заливки ----------------------------------------------------- *
|
||||||
* Стиль заливки — паттерн (8×8) + цвет; действует на bar/bar3d/
|
* Стиль заливки — паттерн (8×8) + цвет; действует на bar/bar3d/
|
||||||
* fillpoly/fillellipse. SOLID_FILL заполняет сплошняком, EMPTY_FILL —
|
* fillpoly/fillellipse. SOLID_FILL заполняет сплошняком, EMPTY_FILL —
|
||||||
|
|||||||
+29
-31
@@ -1,15 +1,14 @@
|
|||||||
/*
|
/*
|
||||||
* bgitest — демонстрация BGI-слоя graphics.h (режим 320×256×256).
|
* bgitest — демонстрация BGI-слоя graphics.h (режим 320×256×256).
|
||||||
* Фаза 2d-1: getimage/putimage/imagesize (спрайты, COPY/XOR/OR).
|
* Фаза 2d-2: setlinestyle (SOLID/DOTTED/CENTER/DASHED + THICK).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <graphics.h>
|
#include <graphics.h>
|
||||||
|
|
||||||
static unsigned char buf[2048];
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
int mx, my;
|
int mx, my, i, y;
|
||||||
|
static const char *name[4] = { "SOLID", "DOTTED", "CENTER", "DASHED" };
|
||||||
|
|
||||||
initgraph();
|
initgraph();
|
||||||
mx = getmaxx();
|
mx = getmaxx();
|
||||||
@@ -19,37 +18,36 @@ int main(void)
|
|||||||
setcolor(WHITE);
|
setcolor(WHITE);
|
||||||
rectangle(0, 0, mx, my);
|
rectangle(0, 0, mx, my);
|
||||||
setcolor(YELLOW);
|
setcolor(YELLOW);
|
||||||
outtextxy(88, 6, "BGI image / sprite");
|
outtextxy(104, 6, "BGI linestyle");
|
||||||
|
|
||||||
/* Исходный спрайт 40×30 в левом верхнем углу. */
|
/* Четыре стиля тонкой линией. */
|
||||||
setfillstyle(SOLID_FILL, LIGHTBLUE);
|
for (i = 0; i < 4; i++) {
|
||||||
bar(12, 28, 51, 57);
|
y = 40 + i * 22;
|
||||||
setcolor(YELLOW);
|
setcolor(WHITE);
|
||||||
rectangle(12, 28, 51, 57);
|
outtextxy(12, y - 3, name[i]);
|
||||||
setcolor(LIGHTRED);
|
setcolor(LIGHTGREEN);
|
||||||
line(12, 28, 51, 57);
|
setlinestyle(i, 0, NORM_WIDTH);
|
||||||
setfillstyle(SOLID_FILL, LIGHTGREEN);
|
line(80, y, 300, y);
|
||||||
fillellipse(31, 42, 8, 8);
|
}
|
||||||
|
|
||||||
|
/* Толстые версии тех же стилей. */
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
y = 140 + i * 16;
|
||||||
|
setcolor(LIGHTCYAN);
|
||||||
|
setlinestyle(i, 0, THICK_WIDTH);
|
||||||
|
line(80, y, 300, y);
|
||||||
|
}
|
||||||
setcolor(WHITE);
|
setcolor(WHITE);
|
||||||
outtextxy(12, 60, "src");
|
outtextxy(12, 150, "THICK");
|
||||||
|
|
||||||
/* Захват и раскладка копий (COPY_PUT). */
|
/* Прямоугольник пунктиром + диагонали. */
|
||||||
getimage(12, 28, 51, 57, buf);
|
setcolor(LIGHTMAGENTA);
|
||||||
putimage(80, 28, buf, COPY_PUT);
|
setlinestyle(DASHED_LINE, 0, NORM_WIDTH);
|
||||||
putimage(130, 28, buf, COPY_PUT);
|
rectangle(20, 212, 130, 250);
|
||||||
putimage(180, 28, buf, COPY_PUT);
|
line(20, 212, 130, 250);
|
||||||
setcolor(WHITE);
|
setcolor(WHITE);
|
||||||
outtextxy(80, 60, "copy x3");
|
setlinestyle(SOLID_LINE, 0, NORM_WIDTH);
|
||||||
|
outtextxy(150, 228, "dashed rect");
|
||||||
/* XOR и OR поверх серого фона. */
|
|
||||||
setfillstyle(SOLID_FILL, DARKGRAY);
|
|
||||||
bar(20, 110, 240, 170);
|
|
||||||
putimage(30, 122, buf, XOR_PUT);
|
|
||||||
outtextxy(30, 176, "xor");
|
|
||||||
putimage(110, 122, buf, OR_PUT);
|
|
||||||
outtextxy(110, 176, "or");
|
|
||||||
putimage(190, 122, buf, COPY_PUT);
|
|
||||||
outtextxy(190, 176, "copy");
|
|
||||||
|
|
||||||
for (;;) { }
|
for (;;) { }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user