📄 13506blt.c
字号:
DrawRect(4,(height-cwidth)/2+1,width-8,cwidth-2,green);
// We have a rectangle, the destination coords of the rectangle
// will be the source coords of all move blt.
// calculate the number of 16 bit words per one blt line
if (Control.BytesPerPixel == 2)
nWords = width;
else
nWords = (width+2)/2; //enough regardless of source phase
memaddress = (DWORD) malloc(2*nWords*height); //this many bytes
if (memaddress == 0)
{
printf("ERROR: Not enough system memory!");
return;
}
// Save the rectangle into system memory using ReadBlit.
Blt.SrcLeft = 0;
Blt.SrcTop = 0;
Blt.SrcHeight = Blt.DstHeight = height;
Blt.SrcWidth = Blt.DstWidth = width;
Blt.Attribute = 0;
ReadBlt(&Blt,memaddress);
w = Control.Width/4;
h = Control.Height/7;
// let's use invert ROP (DST = ~SRC)
Blt.ROP = 0x3;
i = 0;
while (!EscPressed())
{
Blt.DstLeft = (int)(sin(-i*0.0121)*w+w*2);
Blt.DstTop = (int)(cos(i*0.0121)*h+h*2);
// Write the bitmap on the screen...
WriteBlt(&Blt,memaddress);
Blt.SrcLeft = Blt.DstLeft;
Blt.SrcTop = Blt.DstTop;
// Read the latest bitmap.
ReadBlt(&Blt,memaddress);
i++;
}
free((void*)memaddress);
}
//---------------------------------------------------------------------------
//
// Demonstrate Color Expand Blt.
//
//---------------------------------------------------------------------------
static void ShowColorExpandBlt(void)
{
BLT_INFO Blt;
WORD *wpt;
char *string = "Hello World! ";
int stride,DstWidth;
if (!CreateMonoBitmap(string,&wpt,&stride))
{
printf("ERROR: Not enough system memory!");
return;
}
ClearVideoMemory();
printf("\nDrawing random color text at random screen coordinates using Color Expand Blt.");
printf("\nPress Esc to quit...\n");
DstWidth = strlen(string)*8;
Blt.SrcLeft = Blt.SrcTop = 0; //x,y coords of the first pixel in mono bitmap
while (!EscPressed())
{
RandomBltValues(&Blt);
Blt.Attribute = 0;
Blt.DstWidth = DstWidth;
Blt.DstHeight = 16;
ColorExpandBlt(&Blt,wpt,stride);
}
free((void*)wpt);
}
//---------------------------------------------------------------------------
//
// Demonstrate Color Expand Blt with Transparency.
//
//---------------------------------------------------------------------------
static void ShowTransparentColorExpandBlt(void)
{
BLT_INFO Blt;
WORD *wpt;
char *string = "Hello World! ";
int stride,i,j,DstWidth;
if (!CreateMonoBitmap(string,&wpt,&stride))
{
printf("ERROR: Not enough system memory!");
return;
}
ClearVideoMemory();
for (i = 0; i < 20; i++)
{
RandomBltValues(&Blt);
SolidFillBlt(&Blt);
}
printf("\nDrawing random color text using Transparent Color Expand Blt.");
printf("\nThe screen background contains some random color rectangles.");
printf("\nPress Esc to quit...\n");
DstWidth = strlen(string)*8;
i = j = 0;
Blt.SrcLeft = Blt.SrcTop = 0; //x,y coords of the first pixel in mono bitmap
while (!EscPressed())
{
RandomBltValues(&Blt);
if (i*DstWidth > (Control.Width-DstWidth))
i = 0;
if (j*16 > Control.Height)
j = 0;
Blt.DstLeft = i*DstWidth;
Blt.DstTop = j*16;
i++;
j++;
Blt.DstWidth = DstWidth;
Blt.DstHeight = 16;
Blt.Attribute = Transparent;
ColorExpandBlt(&Blt,wpt,stride);
}
free((void*)wpt);
}
//---------------------------------------------------------------------------
// MoveBlt()
//---------------------------------------------------------------------------
//
// Purpose: Performs rectangular Move Blit with ROP or Transparent.
//
// Source rectangle:
// lpBlt->SrcLeft
// lpBlt->SrcTop
// lpBlt->SrcWidth
// lpBlt->SrcHeight
//
// Destination rectangle:
// lpBlt->DstLeft
// lpBlt->DstTop
// lpBlt->DstWidth (same as lpBlt->SrcWidth)
// lpBlt->DstHeight (same as lpBlt->SrcHeight)
//
// Move Blt
// Transparent Blt:
// - transparent color in lpBlt->ColorBg
// Move Blit:
// - ROP in lpBlt->ROP
//
// Note:
// Source and destination rectangles must not overlap for the Transparent
// Move Blt.
//
//---------------------------------------------------------------------------
static void MoveBlt(LPBLT_INFO lpBlt)
{
int direction,byte;
int BytesPerPixel,stride;
DWORD dstAddr,srcAddr;
if (lpBlt->DstWidth == 0 || lpBlt->DstHeight == 0)
return;
BytesPerPixel = Control.BytesPerPixel;
// estabilish a known src & dst. background
stride = Control.Stride;
srcAddr = lpBlt->SrcLeft*BytesPerPixel + lpBlt->SrcTop * stride;
dstAddr = lpBlt->DstLeft*BytesPerPixel + lpBlt->DstTop * stride;
// If the blit is not transparent, determine the direction of the blt.
// Transparent blt supports only positive direction.
direction = 0;
if (!lpBlt->Attribute & Transparent)
{
if (RectOverlap(lpBlt))
{
if (dstAddr > srcAddr)
{
direction = 1;
// negative direction : get the coords of lower right corner
srcAddr += stride*(lpBlt->SrcHeight-1)+
BytesPerPixel*(lpBlt->SrcWidth-1);
dstAddr += stride*(lpBlt->DstHeight-1)+
BytesPerPixel*(lpBlt->DstWidth-1);
}
}
}
// wait for any pending blit to end
WaitForBltEnd();
// program the BLT stride
seWriteRegWord(0x10c, stride/2);
// Set the Source addr
seWriteRegByte(0x104, srcAddr);
seWriteRegByte(0x105, srcAddr>>8);
seWriteRegByte(0x106, srcAddr>>16);
// Set the Destination addr
seWriteRegByte(0x108, dstAddr);
seWriteRegByte(0x109, dstAddr>>8);
seWriteRegByte(0x10a, dstAddr>>16);
seWriteRegWord(0x110, lpBlt->DstWidth-1);
seWriteRegWord(0x112, lpBlt->DstHeight-1);
// set the blt type
if (lpBlt->Attribute & Transparent)
{
seWriteRegWord(0x114, lpBlt->ColorBg);
seWriteRegByte(0x103,5);
}
else
{
seWriteRegByte(0x102, lpBlt->ROP);
if (direction)
seWriteRegByte(0x103,3);
else
seWriteRegByte(0x103,2);
}
// Engage the blt engine.
byte = 0x80;
seWriteRegByte(0x100,byte);
}
//---------------------------------------------------------------------------
// ColorExpandBlt()
//---------------------------------------------------------------------------
//
// Purpose: Performs Color Expansion Blt
//
// Source :
// src: pointer to a monochrome bitmap
// srcstride: stride of the bitmap (bytes)
// lpBlt->SrcLeft : x-coord of the first pixel in the bitmap
// lpBlt->SrcTop: y-coord of the first pizel in the bitmap
//
// Destination rectangle:
// lpBlt->DstLeft
// lpBlt->DstTop
// lpBlt->DstWidth
// lpBlt->DstHeight
//
// Destination color:
// lpBlt->ColorFg
// lpBlt->ColorBg (unused for Transparent Color Expand)
//---------------------------------------------------------------------------
static void ColorExpandBlt(LPBLT_INFO lpBlt,WORD *src,int srcstride)
{
int i,j, nWords,Sx,Sy,BytesPerPixel;
DWORD dstAddr;
WORD *wpt,*wpt1;
volatile WORD *dst;
if (lpBlt->DstWidth == 0 || lpBlt->DstHeight == 0)
return;
// Wait for any pending blit to end
WaitForBltEnd();
BytesPerPixel = Control.BytesPerPixel;
Sx = lpBlt->SrcLeft;
Sy = lpBlt->SrcTop;
// Program the BLT registers
seWriteRegByte(0x102, (7 - Sx%8));
if (lpBlt->Attribute & Transparent)
seWriteRegByte(0x103, 0x09);
else
seWriteRegByte(0x103, 0x08);
seWriteRegByte(0x104, (BYTE)(Sx & 1));
dstAddr = lpBlt->DstLeft*BytesPerPixel + lpBlt->DstTop * Control.Stride;
seWriteRegByte(0x108, dstAddr);
seWriteRegByte(0x109, dstAddr>>8);
seWriteRegByte(0x10a, dstAddr>>16);
seWriteRegWord(0x10c, Control.Stride/2);
seWriteRegWord(0x110, lpBlt->DstWidth-1);
seWriteRegWord(0x112, lpBlt->DstHeight-1);
seWriteRegWord(0x114, lpBlt->ColorBg);
seWriteRegWord(0x118, lpBlt->ColorFg);
// Engage the blt engine.
seWriteRegByte(0x100,0x80);
// wait for the blit to start
while (seReadRegByte(0x100) & 0x80 == 0)
;
dst = (WORD*)gLinBltAddr;
// calculate the number of 16 bit words per one blt line
nWords = (Sx%16 + lpBlt->DstWidth + 15)/16;
wpt = src + (Sy*srcstride + Sx/16)/2;
for (i = 0; i < lpBlt->DstHeight; i++)
{
wpt1 = wpt;
for (j = 0; j < nWords; j++)
{
// loop until FIFO becomes empty...
while ((seReadRegByte(0x100) & 0x40) == 0x40)
;
*dst = *wpt1++;
}
wpt += srcstride/2;
}
}
//---------------------------------------------------------------------------
// SolidFillBlt()
//---------------------------------------------------------------------------
//
// Purpose: Performs Solid Fill Blit
//
// Source :
// Color in lpBlt->ColorFg
//
// Destination rectangle:
// lpBlt->DstLeft
// lpBlt->DstTop
// lpBlt->DstWidth
// lpBlt->DstHeight
//
//---------------------------------------------------------------------------
static void SolidFillBlt(LPBLT_INFO lpBlt)
{
WORD BytesPerPixel;
DWORD dstAddr;
if (lpBlt->DstWidth == 0 || lpBlt->DstHeight == 0)
return;
BytesPerPixel = Control.BytesPerPixel;
// wait for any pending blits to end
WaitForBltEnd();
// set Fill Blt
seWriteRegByte(0x103, 0x0c);
seWriteRegWord(0x10c, Control.Stride/2);
dstAddr = lpBlt->DstLeft*BytesPerPixel + lpBlt->DstTop * Control.Stride;
seWriteRegByte(0x108, dstAddr);
seWriteRegByte(0x109, dstAddr>>8);
seWriteRegByte(0x10a, dstAddr>>16);
seWriteRegWord(0x110, lpBlt->DstWidth-1);
seWriteRegWord(0x112, lpBlt->DstHeight-1);
seWriteRegWord(0x118, lpBlt->ColorFg);
// Engage the blt engine.
seWriteRegByte(0x100,0x80);
}
//---------------------------------------------------------------------------
// PatternFillBlt()
//---------------------------------------------------------------------------
//
// Purpose: Performs Pattern Fill Blit with ROP or Transparent.
//
// Source :
// PatStart : video memory offset to the start of the pattern.
//
// Pattern Phase:
// lpBlt->PatternX : x - coord of the first pattern pixel
// lpBlt->PatternY : y - coord of the first pattern pixel
//
// Destination rectangle:
// lpBlt->DstLeft
// lpBlt->DstTop
// lpBlt->DstWidth
// lpBlt->DstHeight
//
// Transparent Pattern Fill Blt:
// - transparent color in lpBlt->ColorBg
// Solid Pattern Fill Blt:
// - ROP in lpBlt->ROP
//
// Note:
// Some cases cannot be handled by hardware.
// PatStart is assumed to be aligned on 64 byte boundary for 8 Bpp mode,
// on 128 boundary for 15/16 Bpp modes
//---------------------------------------------------------------------------
static void PatternFillBlt(LPBLT_INFO lpBlt,DWORD PatStart)
{
int BytesPerPixel;
DWORD dstAddr;
if (lpBlt->DstWidth == 0 || lpBlt->DstHeight == 0)
return;
BytesPerPixel = Control.BytesPerPixel;
// eliminate cases we cannot do in hardware
if ((lpBlt->Attribute & Transparent) || lpBlt->ROP == 0x0c || lpBlt->ROP == 0x03)
{
if (lpBlt->DstWidth == 1 || (lpBlt->DstWidth == 2 && BytesPerPixel == 1))
return;
}
// The pattern is 8pixels*8lines.
// Adjust pattern start for x,y start phases
// add 8*PhaseY*BytesPerPixel + PhaseX*BytesPerPixel
PatStart += lpBlt->PatternY*BytesPerPixel*8 +
lpBlt->PatternX*BytesPerPixel;
// Wait for any pending blit to end
WaitForBltEnd();
// program relevant blt registers
seWriteRegByte(0x104,PatStart);
seWriteRegByte(0x105,PatStart >> 8);
seWriteRegByte(0x106,PatStart >> 16);
if (lpBlt->Attribute & Transparent)
{
seWriteRegWord(0x114, lpBlt->ColorBg);
seWriteRegByte(0x103, 0x07);
}
else
{
seWriteRegByte(0x102, lpBlt->ROP);
seWriteRegByte(0x103, 0x06);
}
seWriteRegWord(0x10c, Control.Stride/2);
dstAddr = lpBlt->DstLeft*BytesPerPixel + lpBlt->DstTop * Control.Stride;
seWriteRegByte(0x108, dstAddr);
seWriteRegByte(0x109, dstAddr>>8);
seWriteRegByte(0x10a, dstAddr>>16);
seWriteRegWord(0x110, lpBlt->DstWidth-1);
seWriteRegWord(0x112, lpBlt->DstHeight-1);
// Engage the blt engine.
seWriteRegByte(0x100,0x80);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -