SvgaLib/demos/accel.c

1018 lines
30 KiB
C

/*
* This is only a tool to test the acceleration primitives.
* Do not use the primitives as library graphics functions;
* have higher level functions make use of acceleration
* primitives if available, otherwise using normal framebuffer code.
* For example, the vgagl should use acceleration when it can.
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <math.h>
#include <alloca.h>
#include <string.h>
#include "vga.h"
#include "vgagl.h"
#include "wizard.xbm"
#include "wizardmsk.xbm"
#define CROSS_SZ 5
#define LOGO_NAME "linuxlogo.bitmap"
#define LOGO_WIDTH 201
#define LOGO_HEIGHT 85
#define BOXES_Y 3
#define BOXES_X 4
#define BOXES_B 10
#define BOXES_WIDTH (WIDTH/BOXES_X)
#define BOXES_HEIGHT ((HEIGHT - 8) / BOXES_Y)
#define COPY_OFF 3
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define abs(a) (((a) < 0) ? -(a) : (a))
#define QIXLINES 200
int vgamode;
int background_blits;
unsigned char *bitmap;
int accelfuncs, ropfuncs, transfuncs;
int ropmodes, transmodes;
int maxy;
unsigned char blitimage[LOGO_WIDTH * LOGO_HEIGHT], *scaleimage, *expandimage;
unsigned char conv_wizard_bits[wizard_height * ((wizard_width + 31) & ~31)];
unsigned char conv_wizardmsk_bits[wizardmsk_height * ((wizardmsk_width + 31) & ~31)];
void Configure(void);
void DrawDots(void);
void DoAccelTest(void (*accelfunc) (void), char *name, int exp_pixelrate,
int pixels_per_call);
void FillBoxTest(void);
void HlineBoxTest(void);
void ScreenCopyTest(void);
void ScrollTest(void);
void FillBoxXORTest(void);
void PutBitmapTest(void);
void PositionTest(void);
void GetLogo(void);
void ScaleLogo(void);
void RopTest(void);
void QixDemo(int rop, char *txt);
void convxbm(int width, int height, unsigned char *bits, unsigned char *conv_bits);
int main(void)
{
vga_modeinfo *minfo;
vga_init();
Configure();
/* Getting accel info only works if the mode it set. */
vga_setlinearaddressing();
vga_setmode(vgamode);
accelfuncs = vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_ACCEL);
ropfuncs = vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_ROP);
transfuncs = vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_TRANSPARENCY);
ropmodes = vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_ROPMODES);
transmodes = vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_TRANSMODES);
minfo = vga_getmodeinfo(vgamode);
if (minfo->bytesperpixel)
maxy = minfo->maxpixels / (minfo->linewidth / minfo->bytesperpixel);
else
maxy = HEIGHT;
usleep(100000);
vga_setmode(TEXT);
if (accelfuncs == 0) {
printf("No acceleration supported.\n");
exit(0);
}
printf("Accelflags: 0x%08X\n", accelfuncs);
if (accelfuncs & ACCELFLAG_FILLBOX)
printf("FillBox supported.\n");
if (accelfuncs & ACCELFLAG_SCREENCOPY)
printf("ScreenCopy supported.\n");
if (accelfuncs & ACCELFLAG_PUTIMAGE)
printf("PutImage supported.\n");
if (accelfuncs & ACCELFLAG_DRAWLINE)
printf("DrawLine.\n");
if (accelfuncs & ACCELFLAG_SETFGCOLOR)
printf("SetFGColor supported.\n");
if (accelfuncs & ACCELFLAG_SETBGCOLOR)
printf("SetBGColor supported.\n");
if (accelfuncs & ACCELFLAG_SETTRANSPARENCY)
printf("SetTransparency supported.\n");
if (accelfuncs & ACCELFLAG_SETRASTEROP)
printf("SetRasterOp supported.\n");
if (accelfuncs & ACCELFLAG_PUTBITMAP)
printf("PutBitmap supported.\n");
if (accelfuncs & ACCELFLAG_SCREENCOPYBITMAP)
printf("ScreenCopyBitmap supported.\n");
if (accelfuncs & ACCELFLAG_DRAWHLINELIST)
printf("DrawHLineList supported.\n");
if (accelfuncs & ACCELFLAG_POLYLINE)
printf("PolyLine supported.\n");
if (accelfuncs & ACCELFLAG_POLYHLINE)
printf("PolyHLine supported.\n");
if (accelfuncs & ACCELFLAG_POLYFILLMODE)
printf("PolyFillMode supported.\n");
if (accelfuncs & ACCELFLAG_SETMODE)
printf("SetMode supported.\n");
if (accelfuncs & ACCELFLAG_SYNC)
printf("Sync supported.\n");
if (accelfuncs & ACCELFLAG_SETRASTEROP) {
printf("\nRopAccelflags: 0x%08X\n", ropfuncs);
printf("RopModes: 0x%08X", ropmodes);
if (ropmodes & (1 << ROP_COPY))
printf(" Copy");
if (ropmodes & (1 << ROP_OR))
printf(" Or");
if (ropmodes & (1 << ROP_AND))
printf(" And");
if (ropmodes & (1 << ROP_XOR))
printf(" Xor");
if (ropmodes & (1 << ROP_INVERT))
printf(" Invert");
printf("\n");
if (ropfuncs & ACCELFLAG_FILLBOX)
printf("FillBox supported.\n");
if (ropfuncs & ACCELFLAG_SCREENCOPY)
printf("ScreenCopy supported.\n");
if (ropfuncs & ACCELFLAG_PUTIMAGE)
printf("PutImage supported.\n");
if (ropfuncs & ACCELFLAG_DRAWLINE)
printf("DrawLine.\n");
if (ropfuncs & ACCELFLAG_PUTBITMAP)
printf("PutBitmap supported.\n");
if (ropfuncs & ACCELFLAG_SCREENCOPYBITMAP)
printf("ScreenCopyBitmap supported.\n");
if (ropfuncs & ACCELFLAG_DRAWHLINELIST)
printf("DrawHLineList supported.\n");
if (ropfuncs & ACCELFLAG_POLYLINE)
printf("PolyLine supported.\n");
if (ropfuncs & ACCELFLAG_POLYHLINE)
printf("PolyHLine supported.\n");
if (ropfuncs & ACCELFLAG_POLYFILLMODE)
printf("PolyFillMode supported.\n");
}
if (accelfuncs & ACCELFLAG_SETTRANSPARENCY) {
printf("\nTransparencyAccelflags: 0x%08X\n", transfuncs);
printf("TranparencyModes: 0x%08X", transmodes);
if (transmodes & (1 << ENABLE_TRANSPARENCY_COLOR))
printf(" TransparentColor");
if (transmodes & (1 << ENABLE_BITMAP_TRANSPARENCY))
printf(" TransparentBitmap");
printf("\n");
if (transfuncs & ACCELFLAG_FILLBOX)
printf("FillBox supported.\n");
if (transfuncs & ACCELFLAG_SCREENCOPY)
printf("ScreenCopy supported.\n");
if (transfuncs & ACCELFLAG_PUTIMAGE)
printf("PutImage supported.\n");
if (transfuncs & ACCELFLAG_DRAWLINE)
printf("DrawLine.\n");
if (transfuncs & ACCELFLAG_PUTBITMAP)
printf("PutBitmap supported.\n");
if (transfuncs & ACCELFLAG_SCREENCOPYBITMAP)
printf("ScreenCopyBitmap supported.\n");
if (transfuncs & ACCELFLAG_DRAWHLINELIST)
printf("DrawHLineList supported.\n");
if (transfuncs & ACCELFLAG_POLYLINE)
printf("PolyLine supported.\n");
if (transfuncs & ACCELFLAG_POLYHLINE)
printf("PolyHLine supported.\n");
if (transfuncs & ACCELFLAG_POLYFILLMODE)
printf("PolyFillMode supported.\n");
}
printf("\nPress enter to start test.\n");
getchar();
convxbm(wizard_width, wizard_height, wizard_bits, conv_wizard_bits);
convxbm(wizardmsk_width, wizardmsk_height, wizardmsk_bits, conv_wizardmsk_bits);
GetLogo();
vga_setmode(vgamode);
gl_setcontextvga(vgamode);
ScaleLogo();
gl_setcontextvga(vgamode);
if (COLORS == 256)
gl_setrgbpalette();
gl_setwritemode(FONT_COMPRESSED);
gl_setfont(8, 8, gl_font8x8);
gl_setfontcolors(gl_rgbcolor(0, 0, 0), gl_rgbcolor(255, 255, 255));
background_blits = 0;
if (accelfuncs & ACCELFLAG_SYNC)
background_blits = 1;
PositionTest();
gl_clearscreen(0);
if (accelfuncs & ACCELFLAG_SETRASTEROP)
RopTest();
QixDemo(ROP_COPY, "Replace QuixDemo");
QixDemo(ROP_XOR, "Xor QuixDemo");
if (accelfuncs & ACCELFLAG_FILLBOX)
DoAccelTest(
FillBoxTest,
"FillBox",
50000000 / BYTESPERPIXEL,
WIDTH * HEIGHT * 256
);
if (accelfuncs & ACCELFLAG_SCREENCOPY) {
DrawDots();
gl_write(1, 1, "Measuring ACCEL_SCREENCOPY");
DoAccelTest(
ScreenCopyTest,
"ScreenCopy",
20000000 / BYTESPERPIXEL,
WIDTH * (HEIGHT / 3) * 3
);
}
if ((accelfuncs & ACCELFLAG_SCREENCOPY)
&& (accelfuncs & ACCELFLAG_FILLBOX)
&& (maxy > HEIGHT)) {
DrawDots();
gl_write(1, HEIGHT - 9, "Scrolling with SCREENCOPY & FILLBOX");
DoAccelTest(
ScrollTest,
"Scroll Demo",
20000000 / BYTESPERPIXEL,
WIDTH * HEIGHT
);
}
if (accelfuncs & ACCELFLAG_DRAWHLINELIST)
DoAccelTest(
HlineBoxTest,
"FillBox with DrawHlineList",
50000000 / BYTESPERPIXEL,
WIDTH * HEIGHT * 256
);
if ((accelfuncs & ACCELFLAG_FILLBOX)
&& (accelfuncs & ACCELFLAG_SETRASTEROP)
&& (ropfuncs & ACCELFLAG_FILLBOX)) {
DrawDots();
gl_write(1, 1, "FILLBOX, xor with varying colors");
DoAccelTest(
FillBoxXORTest,
"FillBox XOR",
30000000 / BYTESPERPIXEL,
WIDTH * HEIGHT * 256
);
}
if (accelfuncs & ACCELFLAG_PUTBITMAP) {
bitmap = malloc(WIDTH * HEIGHT / 8);
memset(bitmap, 0x55, WIDTH * HEIGHT / 8);
DrawDots();
DoAccelTest(
PutBitmapTest,
"PutBitmap",
30000000 / BYTESPERPIXEL,
WIDTH * HEIGHT * 2
);
}
vga_setmode(TEXT);
exit(-1);
}
void Configure(void)
{
int allowed[GLASTMODE + 1];
for (;;) {
int i;
int m;
for (i = G320x200x16; i <= GLASTMODE; i++) {
allowed[i] = 0;
if (vga_hasmode(i)
&& vga_getmodeinfo(i)->bytesperpixel >= 1) {
printf("%2d %s\n", i, vga_getmodename(i));
allowed[i] = 1;
}
}
printf("\nWhich mode? ");
scanf("%d", &m);
getchar();
printf("\n");
if (m >= G320x200x16 && m <= GLASTMODE) {
vgamode = m;
break;
}
}
}
void convxbm(int width, int height, unsigned char *bits, unsigned char *conv_bits)
{
int scanline = ((width + 31) & ~31);
int y;
scanline >>= 3;
width = (width + 7) >> 3;
for(y = 0; y < height; y++, conv_bits += scanline, bits += width) {
memcpy(conv_bits, bits, width);
if (width < scanline)
memset(conv_bits + width, 0, scanline - width);
}
}
static unsigned char rotbyte(unsigned char c)
{
unsigned char bit = 0x80, res = 0;
for (; c; c >>= 1, bit >>= 1)
if (c & 1)
res |= bit;
return res;
}
void DrawDots(void)
{
int i, n;
/* Fill the screen with random dots. */
gl_clearscreen(0);
n = WIDTH * HEIGHT / 100; /* 1% filled. */
for (i = 0; i < n; i++)
gl_setpixel(rand() % WIDTH, rand() % HEIGHT, rand() % COLORS);
}
void DoAccelTest(void (*accelfunc) (void), char *name, int exp_pixelrate,
int pixels_per_call)
{
int i, n, startclock, diffclock;
int rate, byterate;
if (exp_pixelrate < 0)
/* Special case, #iterations indicated. */
n = -exp_pixelrate;
else
/* Aim for about 5 seconds. */
n = exp_pixelrate * 5 / pixels_per_call + 1;
if (background_blits)
vga_accel(ACCEL_SETMODE, BLITS_IN_BACKGROUND);
startclock = clock();
for (i = 0; i < n; i++)
(*accelfunc) ();
if (background_blits)
vga_accel(ACCEL_SYNC);
diffclock = clock() - startclock;
if (diffclock == 0) {
/* At least let the program continue if something strange happens */
printf("%s: Timing Error",name);
} else {
rate = (long long) n *pixels_per_call * 100 / diffclock;
byterate = rate * BYTESPERPIXEL;
printf("%s: %ld.%ld Mpixels/s (%ld.%ld Mbytes/s)\n", name,
rate / 1000000L, (rate % 1000000L) / 100000L,
byterate / 1000000L, (byterate % 1000000L) / 100000L);
}
}
void FillBoxTest(void)
{
int i;
for (i = 0; i < 256; i++) {
vga_accel(ACCEL_SETFGCOLOR, i);
vga_accel(ACCEL_FILLBOX, 0, 0, WIDTH, HEIGHT);
}
}
void ScreenCopyTest(void)
{
/* Copy first 1/3 to second 1/3. */
vga_accel(ACCEL_SCREENCOPY, 0, 0, 0, HEIGHT / 3, WIDTH, HEIGHT / 3);
/* Copy third 1/3 to first 1/3. */
vga_accel(ACCEL_SCREENCOPY, 0, (HEIGHT / 3) * 2, 0, 0,
WIDTH, HEIGHT / 3);
/* Copy second 1/3 to third 1/3. */
vga_accel(ACCEL_SCREENCOPY, 0, HEIGHT / 3, 0, (HEIGHT / 3) * 2,
WIDTH, HEIGHT / 3);
}
void ScrollTest(void)
{
int i;
/*
* First write the line that will be scrolled into the screen,
* located after the visible screen.
*/
/* Clear the line. */
vga_accel(ACCEL_SETFGCOLOR, 0);
vga_accel(ACCEL_FILLBOX, 0, HEIGHT, WIDTH, 1);
if (background_blits)
vga_accel(ACCEL_SYNC);
/* Write some new dots. */
for (i = 0; i < WIDTH / 100; i++)
gl_setpixel(rand() % WIDTH, HEIGHT, rand() % COLORS);
/* Scroll. */
vga_accel(ACCEL_SCREENCOPY, 0, 1, 0, 0,
WIDTH, HEIGHT);
}
void FillBoxXORTest(void)
{
vga_accel(ACCEL_SETRASTEROP, ROP_XOR);
vga_accel(ACCEL_SYNC);
FillBoxTest();
vga_accel(ACCEL_SETRASTEROP, ROP_COPY);
}
void PutBitmapTest(void)
{
vga_accel(ACCEL_SETBGCOLOR, 0);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 0, 0));
vga_accel(ACCEL_PUTBITMAP, 0, 0, WIDTH, HEIGHT, bitmap);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 0, 255));
vga_accel(ACCEL_PUTBITMAP, 0, 0, WIDTH, HEIGHT, bitmap);
}
void DrawCross(int x, int y, int color) {
int i;
for(i = y - CROSS_SZ; i <= y + CROSS_SZ; i++)
if (y != i)
gl_setpixel(x, i, color);
for(i = x - CROSS_SZ; i <= x + CROSS_SZ; i++)
gl_setpixel(i, y, color);
}
void GetLogo(void) {
FILE *fd;
fd = fopen(LOGO_NAME, "rb");
if (!fd) {
read_err:
perror("Problems reading linuxlogo.bitmap");
exit(2);
}
if (1 != fread(blitimage, LOGO_WIDTH * LOGO_HEIGHT, 1, fd))
goto read_err;
fclose(fd);
}
void ScaleLogo(void) {
unsigned char *ptr;
int w, h, x, y;
expandimage = malloc(LOGO_WIDTH * LOGO_HEIGHT * BYTESPERPIXEL);
w = BOXES_WIDTH - 2 * BOXES_B - 2;
h = BOXES_HEIGHT - 2 * BOXES_B - 2;
scaleimage = malloc(w * h * BYTESPERPIXEL);
if (!scaleimage || !expandimage) {
perror("Out of buffer memory");
exit(2);
}
gl_setcontextvirtual(LOGO_WIDTH, LOGO_HEIGHT, BYTESPERPIXEL, BITSPERPIXEL, expandimage);
for(y = 0, ptr = blitimage; y < LOGO_HEIGHT; y++)
for(x = 0; x < LOGO_WIDTH; x++, ptr++) {
gl_setpixelrgb(x, y, (7 & *ptr) << 5, (7 & (*ptr >> 3)) << 5,
(3 & (*ptr >> 6)) << 6);
}
gl_scalebox(LOGO_WIDTH, LOGO_HEIGHT, expandimage, w, h, scaleimage);
}
void DrawFrame(int x1, int y1, int x2, int y2, int color) {
DrawCross(x1, y1, color);
DrawCross(x2, y1, color);
DrawCross(x1, y2, color);
DrawCross(x2, y2, color);
}
void DrawHlines(int x, int y, int w, int h) {
int i, *xmin, *xmax;
xmin = alloca(sizeof(int) * h);
xmax = alloca(sizeof(int) * h);
for(i = 0; i < h; i++)
xmin[i] = x + (i * w - i + (h >> 2)) / (h - 1);
x += w - 1;
for(i = 0; i < h; xmax[i++] = x);
vga_accel(ACCEL_DRAWHLINELIST, y, h, xmin, xmax);
}
void HlineBoxTest(void) {
int i, *xmin, *xmax;
xmin = alloca(sizeof(int) * HEIGHT);
xmax = alloca(sizeof(int) * HEIGHT);
memset(xmin, 0, sizeof(int) * HEIGHT);
for(i = 0; i < HEIGHT; xmax[i++] = WIDTH - 1);
for (i = 0; i < 256; i++) {
vga_accel(ACCEL_SETFGCOLOR, i);
vga_accel(ACCEL_DRAWHLINELIST, 0, HEIGHT, xmin, xmax);
}
}
static void draw_poly(unsigned short *coords) {
/* Intended bug: */
vga_accel(ACCEL_POLYLINE, ACCEL_START | ACCEL_END, 2, coords);
vga_accel(ACCEL_POLYLINE, ACCEL_START, 2, coords + 2);
/* Proper continuation: */
vga_accel(ACCEL_POLYLINE, 0, 7, coords + 4);
}
static void draw_polyhli(int x, int y, int w, int h) {
int n, i, j, dp, flag = ACCEL_START;
unsigned short coords[40];
vga_lockvc();
for(i = 0; i < h;) {
for(j = n = dp = 0; (j < 3) && (i < h); j++, i++) {
n++;
if (i < (h >> 1)) {
coords[dp++] = 6;
coords[dp++] = x;
coords[dp++] = x + (((w / 4) * (h - i)) / h);
coords[dp++] = x + (w / 2) - (((w / 6) * ((h >> 1) - i)) / h);
coords[dp++] = x + (w / 2) + (((w / 6) * ((h >> 1) - i)) / h);
coords[dp++] = x + w - 1 - (((w / 4) * (h - i)) / h);
coords[dp++] = x + w - 1;
} else {
coords[dp++] = 8;
coords[dp++] = x;
coords[dp++] = x + (((w / 4) * (h - i)) / h);
coords[dp++] = x + ((3 * w) / 8) - (((w / 6) * (i - (h >> 1))) / h);
coords[dp++] = x + ((3 * w) / 8) + (((w / 6) * (i - (h >> 1))) / h);
coords[dp++] = x + ((5 * w) / 8) - (((w / 6) * (i - (h >> 1))) / h);
coords[dp++] = x + ((5 * w) / 8) + (((w / 6) * (i - (h >> 1))) / h);
coords[dp++] = x + w - 1 - (((w / 4) * (h - i)) / h);
coords[dp++] = x + w - 1;
}
}
if (n)
vga_accel(ACCEL_POLYHLINE, flag | ((i >= h) ? ACCEL_END : 0), y, n, coords);
flag = 0;
}
vga_unlockvc();
}
static void draw_polygon(int mode, int x, int y, int w, int h) {
const unsigned short W = x + w - 1, H = y + h - 1;
unsigned short coords[] = {
x, y, W, y, W, H, (x + W)/2, y,
x, H, W, (y + H)/2, (x + W)/2, H,
x, (y + H)/2, W, (y + H)/2,
x, y};
if (mode) {
int i;
for(i = 0; i < (sizeof(coords) / sizeof(unsigned short) - 3); i += 2)
if (coords[i + 1] != coords[i + 3])
vga_accel(ACCEL_DRAWLINE, coords[i], coords[i + 1], coords[i + 2], coords[i + 3]);
} else {
vga_accel(ACCEL_POLYLINE, ACCEL_START, sizeof(coords) / (2 * sizeof(unsigned short)),
coords);
}
}
void PositionTest(void) {
int x, y, red, i = 0, w, h;
red = gl_rgbcolor(255, 0, 0);
w = BOXES_WIDTH - 2 * BOXES_B;
h = BOXES_HEIGHT - 2 * BOXES_B;
gl_write(0, 0, "Testing accelerator positioning:");
for(y = BOXES_B + 8; y < HEIGHT; y += BOXES_HEIGHT)
for(x = BOXES_B; x < WIDTH; x += BOXES_WIDTH) {
DrawFrame(x, y, x + w - 1, y + h - 1, red);
switch(i++) {
case 0:
if (accelfuncs & ACCELFLAG_FILLBOX) {
gl_write(x + 1, y + h + 3, "Fillbox");
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 255, 0));
vga_accel(ACCEL_FILLBOX, x + 1, y + 1, w - 2, h - 2);
}
break;
case 1:
if (accelfuncs & ACCELFLAG_DRAWLINE) {
gl_write(x + 1, y + h + 3, "Linedraw");
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 255, 0));
vga_accel(ACCEL_DRAWLINE, x + 1, y + 1, x + w - 2, y + h - 2);
vga_accel(ACCEL_DRAWLINE, x + w - 2, y + 1, x + 1, y + h - 2);
}
break;
case 2:
if (accelfuncs & ACCELFLAG_PUTIMAGE) {
gl_write(x + 1, y + h + 3, "Putimage");
vga_accel(ACCEL_PUTIMAGE, x + 1, y + 1, w - 2, h - 2, scaleimage);
}
break;
case 3:
if (accelfuncs & ACCELFLAG_SCREENCOPY) {
gl_write(x + 1, y + h + 3, "Screencopy (l->h)");
gl_putbox(x + 1, y + 1, w - 2, h - 2, scaleimage);
vga_accel(ACCEL_SCREENCOPY, x + 1, y + 1,
x + COPY_OFF, y + COPY_OFF, w - 2, h - 2);
DrawFrame(x + COPY_OFF - 1, y + COPY_OFF - 1,
x + COPY_OFF + w - 2, y + COPY_OFF + h - 2,
gl_rgbcolor(0, 255, 0));
}
break;
case 4:
if (accelfuncs & ACCELFLAG_SCREENCOPY) {
gl_write(x + 1, y + h + 3, "Screencopy (h->l)");
gl_putbox(x + 1, y + 1, w - 2, h - 2, scaleimage);
vga_accel(ACCEL_SCREENCOPY, x + 1, y + 1,
x - COPY_OFF, y - COPY_OFF, w - 2, h - 2);
DrawFrame(x - COPY_OFF - 1, y - COPY_OFF - 1,
x - COPY_OFF + w - 2, y - COPY_OFF + h - 2,
gl_rgbcolor(0, 255, 0));
}
break;
case 5:
if (accelfuncs & ACCELFLAG_DRAWHLINELIST) {
gl_write(x + 1, y + h + 3, "Hlinelist");
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 255, 0));
DrawHlines(x + 1, y + 1, w - 2, h - 2);
}
break;
case 6:
if (accelfuncs & ACCELFLAG_PUTBITMAP) {
int xo, yo, i;
unsigned int bmaptmp[8];
gl_write(x + 1, y + h + 3, "PutBitmap");
vga_accel(ACCEL_SETBGCOLOR, gl_rgbcolor(255, 0, 0));
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 255, 0));
for(i = 0; i < 8; i++)
bmaptmp[i] = rotbyte(gl_font8x8['0' * 8 + i]);
vga_accel(ACCEL_PUTBITMAP, x + 1, y + 1,
8, 8, bmaptmp);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 0, 0));
vga_accel(ACCEL_SETBGCOLOR, gl_rgbcolor(0, 255, 0));
for(i = 0; i < 8; i++)
bmaptmp[i] = rotbyte(gl_font8x8['1' * 8 + i]);
vga_accel(ACCEL_PUTBITMAP, x + w - 9, y + 1,
8, 8, bmaptmp);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 0, 0));
vga_accel(ACCEL_SETBGCOLOR, gl_rgbcolor(255, 255, 255));
for(i = 0; i < 8; i++)
bmaptmp[i] = rotbyte(gl_font8x8['2' * 8 + i]);
vga_accel(ACCEL_PUTBITMAP, x + 1, y + h - 9,
8, 8, bmaptmp);
vga_accel(ACCEL_SETBGCOLOR, gl_rgbcolor(0, 0, 0));
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 255, 255));
for(i = 0; i < 8; i++)
bmaptmp[i] = rotbyte(gl_font8x8['3' * 8 + i]);
vga_accel(ACCEL_PUTBITMAP, x + w - 9, y + h - 9,
8, 8, bmaptmp);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 255, 0));
xo = (w - wizard_width) / 2;
yo = (h - wizard_height) / 2;
vga_accel(ACCEL_PUTBITMAP, x + xo, y + yo,
wizard_width, wizard_height, conv_wizard_bits);
}
break;
case 7:
if ((accelfuncs & ACCELFLAG_PUTBITMAP) &&
(accelfuncs & ACCELFLAG_SETTRANSPARENCY) &&
(transfuncs & ACCELFLAG_PUTBITMAP) &&
(transmodes & (1 << ENABLE_BITMAP_TRANSPARENCY))) {
gl_write(x + 1, y + h + 3, "BitmapTransparency");
gl_putbox(x + 1, y + 1, w - 2, h - 2, scaleimage);
vga_accel(ACCEL_SETTRANSPARENCY, ENABLE_BITMAP_TRANSPARENCY);
vga_accel(ACCEL_SETBGCOLOR, gl_rgbcolor(255, 0, 0));
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 0, 0));
vga_accel(ACCEL_PUTBITMAP, x + 1, y + 1,
wizardmsk_width, wizardmsk_height, conv_wizardmsk_bits);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 255, 0));
vga_accel(ACCEL_PUTBITMAP, x + 1, y + 1,
wizard_width, wizard_height, conv_wizard_bits);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 0, 0));
vga_accel(ACCEL_PUTBITMAP, x + w - wizard_width - 1, y + 1,
wizard_width, wizard_height, conv_wizard_bits);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 255, 0));
vga_accel(ACCEL_PUTBITMAP, x + 1, y + h - wizard_height - 1,
wizard_width, wizard_height, conv_wizard_bits);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 255, 255));
vga_accel(ACCEL_PUTBITMAP, x + w - wizard_width - 1,
y + h - wizard_height - 1,
wizard_width, wizard_height, conv_wizard_bits);
vga_accel(ACCEL_SETTRANSPARENCY, DISABLE_BITMAP_TRANSPARENCY);
}
break;
case 8:
if (accelfuncs & ACCELFLAG_SCREENCOPYMONO) {
gl_write(x + 1, y + h + 3, "MonoScreenCopy");
vga_accel(ACCEL_SETBGCOLOR, gl_rgbcolor(255, 0, 0));
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 255, 0));
vga_accel(ACCEL_SCREENCOPYMONO, x + 1, y + h + 3,
x + 1, y + 1, 14 * 8, 8);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 0, 0));
vga_accel(ACCEL_SETBGCOLOR, gl_rgbcolor(0, 255, 0));
vga_accel(ACCEL_SCREENCOPYMONO, x + 1, y + h + 3,
x + w - 1 - 14 * 8, y + 1, 14 * 8, 8);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 0, 0));
vga_accel(ACCEL_SETBGCOLOR, gl_rgbcolor(255, 255, 255));
vga_accel(ACCEL_SCREENCOPYMONO, x + 1, y + h + 3,
x + 1, y + h - 9, 14 * 8, 8);
vga_accel(ACCEL_SETBGCOLOR, gl_rgbcolor(0, 0, 0));
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 255, 255));
vga_accel(ACCEL_SCREENCOPYMONO, x + 1, y + h + 3,
x + w - 1 - 14 * 8, y + h - 9, 14 * 8, 8);
}
break;
case 9:
if (accelfuncs & ACCELFLAG_POLYLINE) {
unsigned short X = x + 1, Y = y + 1, W = x + w - 2,
H = y + (h >> 1) - 2;
unsigned short coords[] = {
X, Y, (X + W)/2, Y, W, Y,
W, H, X + (3 * (W - X))/4, H,
(X + W)/2, (Y + H)/2,
X + (W - X)/4, H, X, H, X, Y
};
gl_write(x + 1, y + h + 3, "Polyline");
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 255, 0));
draw_poly(coords);
if ((ropfuncs & ACCELFLAG_POLYLINE) &&
(accelfuncs & ACCELFLAG_SETRASTEROP) &&
(ropmodes & (1 << ROP_XOR))) {
vga_accel(ACCEL_SETRASTEROP, ROP_XOR);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 255, 255));
}
H = y + h - 2 - H;
for (X = 1; X < (sizeof(coords) / sizeof(unsigned short)); X += 2) {
coords[X] += H;
}
draw_poly(coords);
if ((ropfuncs & ACCELFLAG_POLYLINE) &&
(accelfuncs & ACCELFLAG_SETRASTEROP)) {
vga_accel(ACCEL_SETRASTEROP, ROP_COPY);
}
}
break;
case 10:
if (accelfuncs & ACCELFLAG_POLYHLINE) {
gl_write(x + 1, y + h + 3, "PolyHLine");
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 255, 0));
draw_polyhli(x + 1, y + 1, w - 2, h - 2);
}
break;
case 11:
if ((accelfuncs & ACCELFLAG_POLYLINE) &&
(accelfuncs & ACCELFLAG_SETRASTEROP) &&
(accelfuncs & ACCELFLAG_SCREENCOPYMONO) &&
(accelfuncs & ACCELFLAG_POLYFILLMODE) &&
(accelfuncs & ACCELFLAG_DRAWLINE) &&
(ropfuncs & ACCELFLAG_DRAWLINE) &&
(maxy > (HEIGHT + h)) &&
(ropmodes & (1 << ROP_XOR))) {
gl_write(x + 1, y + h + 3, "PolygonFillMode");
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 0, 0));
vga_accel(ACCEL_FILLBOX, x + 1, HEIGHT, w - 2, h - 2);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 255, 255));
vga_accel(ACCEL_SETRASTEROP, ROP_XOR);
vga_accel(ACCEL_POLYFILLMODE, 1);
draw_polygon(1, x + 1, HEIGHT, w - 2, h - 2);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 0, 0));
vga_accel(ACCEL_SETRASTEROP, ROP_COPY);
vga_accel(ACCEL_SCREENCOPYMONO, x + 1, HEIGHT,
x + 1, y + 1, w - 2, h - 2);
vga_accel(ACCEL_POLYFILLMODE, 0);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 255, 0));
draw_polygon(0, x + 1, y + 1, w - 2, h - 2);
}
goto endtest;
}
}
endtest:
vga_getch();
}
void drawdisk(int x, int y, int n, int *xmin, int *xmax) {
int i;
int *xmin2, *xmax2;
xmin2 = alloca(sizeof(int) * n);
xmax2 = alloca(sizeof(int) * n);
for (i = 0; i < n; i++) {
xmin2[i] = xmin[i] + x;
xmax2[i] = xmax[i] + x;
}
vga_accel(ACCEL_DRAWHLINELIST, y, n, xmin2, xmax2);
}
char *RopNames[] = { "Copy/Replace", "Or", "And", "Xor", "Invert" };
void RopTest(void) {
int x, y, i, w, h, wsq, xo, yo, red, x1, x2;
int *xmin, *xmax;
if (!(ropfuncs & (ACCEL_DRAWHLINELIST | ACCELFLAG_FILLBOX))) {
printf("Rasteroperation test needs HLINELIST or FILLBOX\n");
return;
}
vga_accel(ACCEL_SETTRANSPARENCY, ENABLE_TRANSPARENCY_COLOR, gl_rgbcolor(255, 0, 0));
w = BOXES_WIDTH - 2 * BOXES_B;
h = BOXES_HEIGHT - 2 * BOXES_B;
wsq = min((w * 2)/3, (h * 2)/3);
xmin = alloca(sizeof(int) * wsq);
xmax = alloca(sizeof(int) * wsq);
xo = wsq / 2;
yo = xo * xo;
for (i = 0; i < wsq; i++) {
red = sqrt(yo - (i - xo) * (i - xo));
xmin[i] = xo - red;
xmax[i] = xo + red;
}
yo = h - wsq - 1;
xo = (w - wsq) / 2;
red = gl_rgbcolor(255, 0, 0);
x1 = xo - (wsq - yo)/2;
if (x1 < 1)
x1 = 1;
x2 = w - wsq - x1;
gl_write(0, 0, "Testing raster operations:");
for(y = BOXES_B + 8, i = 0; y < HEIGHT; y += BOXES_HEIGHT)
for(x = BOXES_B; x < WIDTH; x += BOXES_WIDTH) {
DrawFrame(x, y, x + w - 1, y + h - 1, red);
if (! (ropmodes & (1 << i)))
goto nextrop;
if ((i == ROP_AND) || (i == ROP_XOR)) {
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 255, 255));
vga_accel(ACCEL_FILLBOX, x + 1, y + 1, w - 2, h - 2);
if (accelfuncs & ACCELFLAG_DRAWHLINELIST) {
vga_accel(ACCEL_SETRASTEROP, i);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 255, 255));
drawdisk(x + x1, y + 1, wsq, xmin, xmax);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 0, 255));
drawdisk(x + x2, y + 1, wsq, xmin, xmax);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 255, 0));
drawdisk(x + xo, y + yo, wsq, xmin, xmax);
} else {
vga_accel(ACCEL_SETRASTEROP, i);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 255, 255));
vga_accel(ACCEL_FILLBOX, x + x1, y + 1, wsq, wsq);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 0, 255));
vga_accel(ACCEL_FILLBOX, x + x2, y + 1, wsq, wsq);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 255, 0));
vga_accel(ACCEL_FILLBOX, x + xo, y + yo, wsq, wsq);
}
} else {
if (accelfuncs & ACCELFLAG_DRAWHLINELIST) {
vga_accel(ACCEL_SETRASTEROP, i);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 0, 0));
drawdisk(x + x1, y + 1, wsq, xmin, xmax);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 255, 0));
drawdisk(x + x2, y + 1, wsq, xmin, xmax);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 0, 255));
drawdisk(x + xo, y + yo, wsq, xmin, xmax);
} else {
vga_accel(ACCEL_SETRASTEROP, i);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(255, 0, 0));
vga_accel(ACCEL_FILLBOX, x + x1, y + 1, wsq, wsq);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 255, 0));
vga_accel(ACCEL_FILLBOX, x + x2, y + 1, wsq, wsq);
vga_accel(ACCEL_SETFGCOLOR, gl_rgbcolor(0, 0, 255));
vga_accel(ACCEL_FILLBOX, x + xo, y + yo, wsq, wsq);
}
}
vga_accel(ACCEL_SETRASTEROP, ROP_COPY);
gl_write(x + 1, y + h + 3, RopNames[i]);
nextrop:
i++;
if (i >= (sizeof(RopNames) / sizeof(char *)))
goto endtest;
}
endtest:
vga_getch();
}
void QixDemo(int rop, char *txt) {
int current = 0, dx1, dy1, dx2, dy2, i, cols = 1, cx1, cx2, cy1, cy2;
int startclock, diffclock;
unsigned long pixels = 0;
unsigned int numlines = 0;
struct {
unsigned short x1;
unsigned short y1;
unsigned short x2;
unsigned short y2;
int col;
int pix;
} lines[QIXLINES];
if ( !(ropmodes & (1 << rop)) ||
!(accelfuncs & ACCELFLAG_DRAWLINE))
return;
if ((rop != ROP_COPY) &&
!(accelfuncs & ACCELFLAG_SETRASTEROP))
return;
DrawDots();
gl_write(1, 1, txt);
memset(lines, 0, sizeof(lines));
cx1 = rand() % WIDTH;
cy1 = rand() % HEIGHT;
cx2 = rand() % WIDTH;
cy2 = rand() % HEIGHT;
dx1 = 5 - rand() % 10;
dy1 = 5 - rand() % 10;
dx2 = 5 - rand() % 10;
dy2 = 5 - rand() % 10;
if (rop != ROP_COPY)
vga_accel(ACCEL_SETRASTEROP, rop);
startclock = clock();
for(i = 0; i < 10000; i++) {
diffclock = clock() - startclock;
if (diffclock > 5 * CLOCKS_PER_SEC)
break;
if (lines[current].col) {
if (rop != ROP_COPY)
vga_accel(ACCEL_SETFGCOLOR, lines[current].col);
else
vga_accel(ACCEL_SETFGCOLOR, 0);
vga_accel(ACCEL_DRAWLINE, lines[current].x1, lines[current].y1,
lines[current].x2, lines[current].y2);
numlines++;
pixels += lines[current].pix;
}
cx1 += dx1;
if ((cx1 < 0) || (cx1 >= WIDTH)) {
dx1 = -dx1;
cx1 += dx1 << 1;
}
cx2 += dx2;
if ((cx2 < 0) || (cx2 >= WIDTH)) {
dx2 = -dx2;
cx2 += dx2 << 1;
}
cy1 += dy1;
if ((cy1 < 0) || (cy1 >= HEIGHT)) {
dy1 = -dy1;
cy1 += dy1 << 1;
}
cy2 += dy2;
if ((cy2 < 0) || (cy2 >= HEIGHT)) {
dy2 = -dy2;
cy2 += dy2 << 1;
}
lines[current].x1 = cx1;
lines[current].x2 = cx2;
lines[current].y1 = cy1;
lines[current].y2 = cy2;
lines[current].col = cols;
vga_accel(ACCEL_SETFGCOLOR, cols++);
if (cols >= COLORS)
cols = 1;
vga_accel(ACCEL_DRAWLINE, lines[current].x1, lines[current].y1,
lines[current].x2, lines[current].y2);
numlines++;
pixels += lines[current].pix = max(abs(lines[current].x1 - lines[current].x2),
abs(lines[current].y1 - lines[current].y2));
current++;
if (current >= QIXLINES)
current = 0;
}
if (rop != ROP_COPY)
vga_accel(ACCEL_SETRASTEROP, ROP_COPY);
cy1 = ((long long) numlines * CLOCKS_PER_SEC) / diffclock;
cx1 = ((long long) pixels * CLOCKS_PER_SEC) / diffclock;
cx2 = cx1 * BYTESPERPIXEL;
printf("%s: %ld.%ld Klines/s (%ld.%ld Mpixels/s or %ld.%ld Mbytes/s)\n", txt,
cy1 / 1000L, (cy1 % 1000L) / 100L,
cx1 / 1000000L, (cx1 % 1000000L) / 100000L,
cx2 / 1000000L, (cx2 % 1000000L) / 100000L);
}