⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 13506blt.c

📁 epson13506 bitblt demo program
💻 C
📖 第 1 页 / 共 3 页
字号:
    }

//---------------------------------------------------------------------------
// ReadBlt()
//---------------------------------------------------------------------------
//
// Purpose: Performs Read Blit.
//
// Source :
//      lpBlt->SrcLeft
//      lpBlt->SrcTop
//      lpBlt->SrcWidth  
//      lpBlt->SrcHeight 
//
// Destination:
//      memaddress: pointer to memory to store the ReadBlt bitmap.
//      
//---------------------------------------------------------------------------
static void ReadBlt(LPBLT_INFO lpBlt,DWORD memaddress)
    {
    int j,BytesPerPixel;
    DWORD srcAddr;
    int nTotalWords,nWords,phase,nFIFO,byte100;
    volatile WORD *dst16;
    WORD *w16;

    BytesPerPixel = Control.BytesPerPixel;
    srcAddr = lpBlt->SrcLeft*BytesPerPixel + lpBlt->SrcTop * Control.Stride;
    phase = memaddress & 1;

    // Wait for any pending blits to finish...

    WaitForBltEnd();

    // ask for read blt

    seWriteRegByte(0x103, 0x01);

    seWriteRegByte(0x104, srcAddr);
    seWriteRegByte(0x105, srcAddr>>8);
    seWriteRegByte(0x106, srcAddr>>16);
    seWriteRegByte(0x108, phase);

    seWriteRegWord(0x10c, Control.Stride/2);

    // program the BLT rect dimensions

    seWriteRegWord(0x110, lpBlt->SrcWidth-1);
    seWriteRegWord(0x112, lpBlt->SrcHeight-1);

    // Engage the blt engine.

    seWriteRegByte(0x100,0x80);

    // wait for the blit to start

    while ((seReadRegByte(0x100) & 0x80) == 0)
        ;

    // calculate the address of the BLT aperture

    dst16 = (WORD*)gLinBltAddr;

    // calculate number of 16bit words per one line

    if (BytesPerPixel == 2)
        nWords = lpBlt->SrcWidth;
    else
        nWords = (lpBlt->SrcWidth + 1 + phase)/2;

    w16 = (WORD*)(memaddress & 0xFFFFFFFE);   // Word aligned 

    nTotalWords = nWords*lpBlt->SrcHeight;

    while (nTotalWords > 0)
        {
        // wait for the FIFO not empty
        byte100 = seReadRegByte(0x100);
        if (byte100 & 0x10)      //FIFO full, 16 WORDs available
            nFIFO = 16;
        else if (byte100 & 0x20) //FIFO half full, 8 WORDS available
            nFIFO = 8;
        else if (byte100 & 0x40) //FIFO not empty, (at least one word available)
            nFIFO = 1;
        else
            continue;

        for (j = 0; j < nFIFO && nTotalWords > 0; j++,nTotalWords--)
             *w16++ = *dst16;
        }
    }

//---------------------------------------------------------------------------
// WriteBlt()
//---------------------------------------------------------------------------
//
// Purpose: Performs Rectangular Write Blit.
//
// Destination:
//      lpBlt->SrcLeft
//      lpBlt->SrcTop
//      lpBlt->SrcWidth  
//      lpBlt->SrcHeight 
//
// Source :
//      memaddress: pointer to memory bitmap
//      
//---------------------------------------------------------------------------
static void WriteBlt(LPBLT_INFO lpBlt, DWORD memaddress)
    {
    int j,BytesPerPixel;
    DWORD dstAddr;
    int byte100,nTotalWords,nFIFO,nWords,phase,stride;
    volatile WORD *dst;
    WORD *w16;

    BytesPerPixel = Control.BytesPerPixel;
    stride = Control.Stride;
    dstAddr = lpBlt->DstLeft*BytesPerPixel + lpBlt->DstTop * stride;
    phase = memaddress & 1;

    // Wait for any pending blits to finish ...

    WaitForBltEnd();

    if (lpBlt->Attribute & Transparent)
        {
        seWriteRegWord(0x114, lpBlt->ColorBg);
        seWriteRegByte(0x103, 0x4);
        }
    else
        {
        seWriteRegByte(0x103, 0x0);
        seWriteRegByte(0x102, lpBlt->ROP);
        }

    seWriteRegByte(0x104, phase);
    seWriteRegWord(0x10c, Control.Stride/2);

    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);

    // 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 = phase + ((lpBlt->DstWidth-phase)*BytesPerPixel + 1)/2;
    nTotalWords = nWords*lpBlt->DstHeight;

    w16 = (WORD*)(memaddress & 0xFFFFFFFE);   // Word aligned 

    while (nTotalWords > 0)
        {
        // read the FIFO status
        byte100 = seReadRegByte(0x100);
        if ((byte100 & 0x30) == 0x20)  //FIFO at least half full, not full
            nFIFO = 1;
        else if ((byte100 & 0x40) == 0) //FIFO empty
            nFIFO = 16;
        else 
            continue;

        for (j = 0; j < nFIFO && nTotalWords > 0; j++,nTotalWords--)
            *dst = (WORD)*w16++;
        }
    }


//---------------------------------------------------------------------------
// InitModeInfo
//---------------------------------------------------------------------------
//
// Purpose: Fills in the mode dependent values in the control info structure.
//
//---------------------------------------------------------------------------
void InitModeInfo(LPCONTROL_INFO lpInfo)
    {
    unsigned byte,colordepth;

    lpInfo->TotalVmem = seGetAvailableMemorySize();

    // Crack the active display

    byte = seReadRegByte(0x1fc) & 0x7;
    if (byte == 0x00 || byte == 0x01)   // No display or LCD only...
        {
        lpInfo->Width = ((seReadRegByte(0x32)+1)*8);
        lpInfo->Height= ( seReadRegByte(0x38) | (seReadRegByte(0x39)<<8)) +1;
        colordepth = seReadRegByte(0x40);
        }
    else // CRT or CRT+LCD, TV etc...
        {
        lpInfo->Width = ((seReadRegByte(0x50)+1)*8);
        lpInfo->Height= ( seReadRegByte(0x56) | (seReadRegByte(0x57)<<8)) +1;
        colordepth = seReadRegByte(0x60);
        }

    switch (colordepth & 0x7)
        {
        case 3: lpInfo->ColorDepth =  8; break;
        case 4: lpInfo->ColorDepth = 15; break;
        case 5: lpInfo->ColorDepth = 16; break;
        default:
            printf("\nERROR: invalid chip configuration");
            exit(1);
        }
    
    switch (lpInfo->ColorDepth)
        {
        case 8:
            seWriteRegByte(0x101, 0x00);    //8BPP blit
            lpInfo->BytesPerPixel = 1;
            break;   

        case 15:
        case 16:
            seWriteRegByte(0x101, 0x01);    //15/16BPP blit
            lpInfo->BytesPerPixel = 2;
            break;
        }

    lpInfo->Stride = lpInfo->BytesPerPixel * lpInfo->Width;
    seWriteRegWord(0x46,lpInfo->Stride/2);
    seWriteRegWord(0x66,lpInfo->Stride/2);
    }

//---------------------------------------------------------------------------
// WaitForBltEnd()
//---------------------------------------------------------------------------
//
// Purpose: 
//
// Returns: 
//          
//
//---------------------------------------------------------------------------
static void WaitForBltEnd(void)
    {
    // wait until the Blt Engine is idle and Command Queue is empty

    while (seReadRegByte(0x100) & 0x80);
    }


//---------------------------------------------------------------------------
// ChkForBreak()
//---------------------------------------------------------------------------
//
// Purpose: Checks for an ESC key press.
//
// Returns: TRUE  if a break key sequence has been pressed.
//          FALSE for any other keyboard condition.
//
//---------------------------------------------------------------------------
static BOOL EscPressed(void)
    {
    if (kbhit())
        {
        if (getch() == ESC)
            return TRUE;
        }

    return FALSE;
    }

//---------------------------------------------------------------------------
//
// RandomBltValues: generate coodinates of a rectangle that does not 
// wrap or clip on screen edges. While at it generate ome random colors.
// Also randomizes ROP. Different fileds of the BLT_INFO are used by different
// blt routines.
//
//---------------------------------------------------------------------------
static WORD rand16(void)
    {
    // Bit 15 of MS rand() is always 0. We want full 16 bit range.

    return ((rand() << 1) | (rand() & 1)); 
    }

static void RandomBltValues(LPBLT_INFO lpBlt)
    {
    WORD nMaxX = Control.Width;
    WORD nMaxY = Control.Height;

    lpBlt->ColorFg = rand16();
    lpBlt->ColorBg = rand16();

    lpBlt->ROP = rand() & 0xF;

    lpBlt->PatternX = rand() & 0x7;
    lpBlt->PatternY = rand() & 0x7;

    // Make sure the foreground and background colors are different.
    
    if ((lpBlt->ColorBg & 0xFF) == (lpBlt->ColorFg & 0xFF))
        lpBlt->ColorBg ^= 0xFF;

    lpBlt->Attribute = rand() & Transparent;

    //
    // Dst location and size.
    //

    do
        {
        lpBlt->DstTop = (WORD)(rand() % nMaxY-10);
        } while (lpBlt->DstTop >= nMaxY - 1);

    do
        {
        lpBlt->DstLeft = (WORD)(rand() & 0x07FF);
        } while (lpBlt->DstLeft +8 >= nMaxX - 1);

    do
        {
        lpBlt->DstWidth = (WORD)(rand() % nMaxX);
        if (!lpBlt->DstWidth)
            lpBlt->DstWidth++;          //width cannot be 0

        } while (lpBlt->DstLeft + lpBlt->DstWidth >= nMaxX);

    do
        {
        lpBlt->DstHeight = (WORD)(rand() & 0x1FF);
        if (!lpBlt->DstHeight)
            lpBlt->DstHeight++;          //height cannot be 0
        } while (lpBlt->DstTop + lpBlt->DstHeight >= nMaxY-2);
    }


//---------------------------------------------------------------------------
//
// Given a character string, generate a monochrome bitmap based on bitmaps
// of inividual characters. 
//
//---------------------------------------------------------------------------
BOOL CreateMonoBitmap(char *str,WORD **wpt,int *strideout)
    {
    char *bpt,*bpt1;
    int stride,line,i;
    int len = strlen(str);
    stride = (len+1) & ~1;          //round up to be even

    bpt = malloc (stride * 16);     //16 bytes per character
    if (bpt == NULL)
        return FALSE;

    *wpt = (WORD*)bpt;
    *strideout = stride;

    for (line = 0; line < 16; line++)
        {
        bpt1 = bpt;
        for (i = 0; i < len; i++)
            {
            *bpt1++ = GetCharacterByte(str[i],line);
            }
        bpt += stride;
        }
    return TRUE;
    }

//---------------------------------------------------------------------------
//
//
//---------------------------------------------------------------------------
static int GetCharacterByte(int c,int line)
    {
    char *chpt = &CharSet16[16*c+line];
    return *chpt;   
    }

//---------------------------------------------------------------------------
//
//
//---------------------------------------------------------------------------
static void ClearVideoMemory(void)
    {
    memset((char*)gLinBufAddr,0,Control.TotalVmem);
    }

//---------------------------------------------------------------------------
//
//  Verify if Source and Destination rectangles overlap.
//
//---------------------------------------------------------------------------
static BOOL RectOverlap(LPBLT_INFO lpBlt)
    {
    int Sx0,Sx1,Dx0,Dx1,Sy0,Sy1,Dy0,Dy1;

    Sx0 = lpBlt->SrcLeft;
    Sx1 = Sx0 + lpBlt->SrcWidth;
    Dx0 = lpBlt->DstLeft;
    Dx1 = Dx0 + lpBlt->DstWidth;
    
    Sy0 = lpBlt->SrcTop;
    Sy1 = Sy0 + lpBlt->SrcHeight;
    Dy0 = lpBlt->DstTop;
    Dy1 = Dy0 + lpBlt->DstHeight;

    if (Dx0 > Sx1 || Dy0 > Sy1 || Dx1 < Sx0 || Dy1 < Sy0)
        return FALSE;
    
    return TRUE;
    }

//---------------------------------------------------------------------------
//
//
//---------------------------------------------------------------------------
void DrawRect(int x,int y,int width,int height,DWORD color)
    {
    BLT_INFO Blt;
    Blt.DstWidth = width;
    Blt.DstHeight = height;
    Blt.DstTop = y;
    Blt.DstLeft = x;
    Blt.Attribute = 0;  
    Blt.ColorFg = color;
    SolidFillBlt(&Blt);
    }
    
//---------------------------------------------------------------------------
//
//
//---------------------------------------------------------------------------
DWORD CreateRandomPattern(LPBLT_INFO lpBlt)
    {
    int i;
    DWORD PatternAddress;
    WORD  pattern[8*8];
    DWORD data = rand16();

    // generate the 8x8 pattern 

    for (i = 0; i < (8*8*Control.BytesPerPixel)/2 ;i++)
        {
        pattern[i] = (WORD)data;
        data = _rotl(data,1);
        }

    // for transparent fills, paste in transparent pixels

    if (lpBlt->Attribute & Transparent)
        {
        data = rand16();
        if (Control.BytesPerPixel == 2)
            {
            WORD *ptrw = (WORD*)pattern;

            // paste in randomly transparent pixels

            for (i = 0; i < 36; i++, data >>= 1, ptrw++)
                {
                if (i == 32)
                    data = lpBlt->ColorFg;
                
                if (data & 1)
                    *ptrw = (WORD)lpBlt->ColorBg;
                }
            }
        else
            {
            BYTE *ptrb = (BYTE*)pattern;

            // paste in randomly transparent pixels

            for (i = 0; i < 36; i++, data >>= 1, ptrb++)
                {
                if (i == 32)
                    data = lpBlt->ColorFg;
                
                if (data & 1)
                    *ptrb = (BYTE)lpBlt->ColorBg;
                }
            }
        }

    // Copy the pattern in the video memory. Here we place it in the
    // first 128 byte aligned address in the offscreen memory.

    PatternAddress = (gOffscreenOffset+127) & 0xffffff80L; 

    memcpy((DWORD*)(gLinBufAddr+PatternAddress),pattern,(8*8*Control.BytesPerPixel));
    return PatternAddress;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -