libbgi: vflip-блиты для row-major картинок (шаг I.2 плана L9-INVERT)
gfx_blit_noclip_vflip / gfx_blit_part_noclip_vflip / gfx_blit_part_vflip. Ассемблера не потребовалось: у row-major вертикальное зеркало — это порядок строк, а он задаётся ЗНАКОМ src-страйда, который _bgi_blit_rows_raw и так принимает знаковым и патчит SMC. Даём адрес последней строки и -stride. Клип у part_vflip свой: обрезка сверху экрана съедает НИЖНИЕ строки источника, и первая строка обязана считаться от высоты ДО клипа (поймано тестом — сначала формула брала уже укороченную). tests/pageflip расширен до 8 проверок, все PASS в MAME. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -48,12 +48,44 @@
|
||||
#define WW 320
|
||||
#define WH 16
|
||||
|
||||
#define IW 16 /* картинка в памяти: ширина */
|
||||
#define IH 8 /* высота */
|
||||
#define IX 8 /* куда блитим (без клипа) */
|
||||
#define IY 216
|
||||
#define CX 8 /* клипающий вариант: частью за верхом экрана */
|
||||
#define CY -3
|
||||
|
||||
#define ROW_C0 0x41 /* цвет строки i = ROW_C0 + i */
|
||||
#define MARK_L 0x21 /* маркер левого края строки */
|
||||
#define MARK_R 0x22 /* маркер правого края */
|
||||
#define FRAME 0x2F /* рамка вокруг области */
|
||||
#define DIRT 0x35 /* чем забиваем приёмник до копии */
|
||||
|
||||
/* Картинка getimage-формата: w,h (16 бит) + пиксели row-major.
|
||||
* Значение = 0x40 + row*IW + col: и строки, и колонки различимы. */
|
||||
static uint8_t img[4 + IW * IH];
|
||||
|
||||
static void make_img(void)
|
||||
{
|
||||
int col, row;
|
||||
img[0] = IW; img[1] = 0; img[2] = IH; img[3] = 0;
|
||||
for (row = 0; row < IH; row++)
|
||||
for (col = 0; col < IW; col++)
|
||||
img[4 + row * IW + col] = (uint8_t)(0x40 + row * IW + col);
|
||||
}
|
||||
|
||||
/* Строка row картинки обязана лежать в экранной строке (IH-1-row). */
|
||||
static uint8_t img_vflip_ok(int x0, int y0, int sx, int sy, int w, int h)
|
||||
{
|
||||
int col, row;
|
||||
for (row = 0; row < h; row++)
|
||||
for (col = 0; col < w; col++) {
|
||||
uint8_t want = (uint8_t)(0x40 + (sy + row) * IW + sx + col);
|
||||
if ((uint8_t)getpixel(x0 + col, y0 + h - 1 - row) != want) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Нарисовать образец в ТЕКУЩЕЙ draw-странице: каждая строка своим цветом,
|
||||
* по краям маркеры. */
|
||||
static void draw_pattern(int x0, int y0, int w, int h)
|
||||
@@ -129,7 +161,7 @@ static void say(int y, const char *s, uint8_t ok)
|
||||
void main(void)
|
||||
{
|
||||
gfx_rect_t area;
|
||||
uint8_t t[5];
|
||||
uint8_t t[8];
|
||||
uint8_t i;
|
||||
|
||||
initgraph();
|
||||
@@ -168,6 +200,31 @@ void main(void)
|
||||
gfx_copy_page(&area, GFX_COPY_VFLIP);
|
||||
t[3] = check_vflip(WX, WY, WW, WH);
|
||||
|
||||
/* T6-T8: vflip-блиты row-major картинки (ядро то же, знак страйда). */
|
||||
make_img();
|
||||
setfillstyle(SOLID_FILL, BLACK);
|
||||
bar(0, IY - 1, 200, IY + IH);
|
||||
gfx_blit_noclip_vflip(IX, IY, img);
|
||||
t[5] = img_vflip_ok(IX, IY, 0, 0, IW, IH);
|
||||
|
||||
gfx_blit_part_noclip_vflip(IX + 40, IY, img, 4, 2, 8, 4);
|
||||
t[6] = img_vflip_ok(IX + 40, IY, 4, 2, 8, 4);
|
||||
|
||||
/* Клипающий вариант: три верхние экранные строки за краем — значит
|
||||
* съедены ТРИ НИЖНИЕ строки картинки (последние по порядку вывода). */
|
||||
gfx_blit_part_vflip(CX + 90, CY, img, 0, 0, IW, IH);
|
||||
/* y = -3 => первые три вывода срезаны, экранная строка 0 получает
|
||||
* источник IH-1-3 = 4, дальше вверх по источнику: строка row <- (4-row). */
|
||||
t[7] = 1;
|
||||
{
|
||||
int col, row;
|
||||
for (row = 0; row < IH - 3; row++)
|
||||
for (col = 0; col < IW; col++) {
|
||||
uint8_t want = (uint8_t)(0x40 + (IH - 1 - 3 - row) * IW + col);
|
||||
if ((uint8_t)getpixel(CX + 90 + col, row) != want) { t[7] = 0; break; }
|
||||
}
|
||||
}
|
||||
|
||||
/* T5: источник обязан остаться нетронутым. */
|
||||
gfx_set_draw_page(1);
|
||||
t[4] = check_direct(AX, AY, AW, AH);
|
||||
@@ -180,12 +237,14 @@ void main(void)
|
||||
say(174, "T3 frame intact", t[2]);
|
||||
say(186, "T4 vflip 320 wide", t[3]);
|
||||
say(198, "T5 source intact", t[4]);
|
||||
say(210, "T6 blit vflip", t[5]);
|
||||
say(222, "T7 part vflip", t[6]);
|
||||
say(234, "T8 part vflip clip", t[7]);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
for (i = 0; i < 8; i++)
|
||||
if (!t[i]) break;
|
||||
setcolor(WHITE);
|
||||
outtextxy(8, 216, i == 5 ? (char *)"ALL PASS" : (char *)"SOME FAILED");
|
||||
outtextxy(8, 228, "done");
|
||||
outtextxy(8, 246, i == 8 ? (char *)"ALL PASS" : (char *)"SOME FAILED");
|
||||
|
||||
for (;;) { }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user