📄 sdk7a404_peg_lcd_driver.cpp
字号:
/*--------------------------------------------------------------------------*
* $Workfile: sdk7a404_peg_lcd_driver.cpp $
* $Revision: 1.1 $
* $Author: WellsK $
* $Date: Oct 28 2003 11:16:00 $
*
* LCD display driver for the Logic PD SDK7A404 EVB
*
* Revision History:
* $Log: //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/csps/lh7a404/bsps/sdk7a404/ports/peg/sdk7a404_peg_lcd_driver.cpp-arc $
*
* Rev 1.1 Oct 28 2003 11:16:00 WellsK
* Updated to use common LCD drivers.
*
* Rev 1.0 Sep 25 2003 09:29:16 WellsK
* Initial revision.
*
*--------------------------------------------------------------------------*/
#include "peg.hpp"
#include "stdlib.h"
#include "string.h"
#include "abl_arm922t_cp15_driver.h"
#include "lh7a404_gpio_driver.h"
#include "sdk7a404_cpld_driver.h"
#include "lh7a404_clcdc_driver.h"
/*--------------------------------------------------------------------------*/
// Driver configuration
/*--------------------------------------------------------------------------*/
// Normally, the video memory is allocated in an area of memory that is
// uncached or located seperately from program data. If the following line
// is left un-commented, a static memory buffer will automatically be
// created and used in cached memory. This may cause some minor problems
// with display artifacts as the cache temporarily holds pixel data.
//#define STATIC_VBUF
// If a static memory buffer isn't used, the virtual address of the video
// memory buffer should be placed here.
#define VBUF_ADDR 0xC1C00000 // Logical address of frame buffer 1
// To enable double buffer support, enable the following define. Double
// buffer support will improve display update performance and may reduce
// visible flicker and draw effects on the display by drawing to an off
// screen buffer and then blitting the image to the display. Using double
// buffering will have a slight performance impact on the system due to the
// extra blit operation and will use more memry than a non double buffered
// system.
//#define DOUBLE_BUFFER
// Default 256 color palette
extern UCHAR DefPalette256[];
/*--------------------------------------------------------------------------*/
// Allocate screen buffer as normal data. The screen buffer should be
// asligned on a 32 byte boundary.
/*--------------------------------------------------------------------------*/
#define VIDEOBUFF_SIZE (PEG_VIRTUAL_XSIZE * PEG_VIRTUAL_YSIZE)
#define ACTVID_OFFS 0
#if defined(STATIC_VBUF)
#if defined(DOUBLE_BUFFER)
/* If double buffering is enabled, the frame buffer memory is allocated
'twice', one buffer is visisble and one is the working buffer */
__align (32) COLORVAL gbVMemory[VIDEOBUFF_SIZE * 2];
#undef ACTVID_OFFS
#define ACTVID_OFFS VIDEOBUFF_SIZE
#else
__align (32) COLORVAL gbVMemory[VIDEOBUFF_SIZE];
#endif
#endif
/*--------------------------------------------------------------------------*/
void SDK7A400_LCD::BeginDraw(PegThing *pThing)
{
// Suppress warning
(void)pThing;
LOCK_PEG
if (!mwDrawNesting)
{
#ifdef PEG_MOUSE_SUPPORT
if (miInvalidCount)
{
if (mInvalid.Overlap(mCapture.Pos()))
{
HidePointer();
mbPointerHidden = TRUE;
}
}
#endif
}
mwDrawNesting++;
}
/*--------------------------------------------------------------------------*/
void SDK7A400_LCD::EndDraw()
{
mwDrawNesting--;
if (!mwDrawNesting)
{
#ifdef PEG_MOUSE_SUPPORT
if (mbPointerHidden)
{
SetPointer(mLastPointerPos);
mbPointerHidden = FALSE;
}
#endif
#if defined(DOUBLE_BUFFER)
MemoryToScreen();
#endif
while(miInvalidCount > 0)
{
miInvalidCount--;
UNLOCK_PEG
}
}
UNLOCK_PEG
}
/*--------------------------------------------------------------------------*/
void SDK7A400_LCD::BeginDraw(PegThing *Caller, PegBitmap *pMap)
{
// Suppress warning for unused variable
(void)Caller;
if (mbVirtualDraw)
{
return;
}
LOCK_PEG
mpSaveScanPointers = mpScanPointers;
if (pMap->wHeight && pMap->wWidth && pMap->pStart)
{
mpScanPointers = new COLORVAL PEGFAR *[pMap->wHeight];
COLORVAL PEGFAR *CurrentPtr = (COLORVAL PEGFAR *) pMap->pStart;
for (SIGNED iLoop = 0; iLoop < pMap->wHeight; iLoop++)
{
mpScanPointers[iLoop] = CurrentPtr;
CurrentPtr += pMap->wWidth;
}
mVirtualRect.Set(0, 0, pMap->wWidth - 1, pMap->wHeight - 1);
mbVirtualDraw = TRUE;
}
}
/*--------------------------------------------------------------------------*/
void SDK7A400_LCD::EndDraw(PegBitmap *pMap)
{
// Suppress warning for unused variable
(void)pMap;
if (mbVirtualDraw)
{
mbVirtualDraw = FALSE;
delete [] mpScanPointers;
mpScanPointers = mpSaveScanPointers;
UNLOCK_PEG
}
}
/*--------------------------------------------------------------------------*/
void SDK7A400_LCD::SetPointerType(UCHAR bType)
{
#ifdef PEG_MOUSE_SUPPORT
if (bType < NUM_POINTER_TYPES)
{
LOCK_PEG
HidePointer();
mpCurPointer = mpPointers[bType].Bitmap;
miCurXOffset = mpPointers[bType].xOffset;
miCurYOffset = mpPointers[bType].yOffset;
SetPointer(mLastPointerPos);
UNLOCK_PEG
}
#else
// Suppress warning for unused variable
(void)bType;
#endif
}
/*--------------------------------------------------------------------------*/
void SDK7A400_LCD::HidePointer(void)
{
#ifdef PEG_MOUSE_SUPPORT
PegThing *pt = NULL;
PegPresentationManager *pp = pt->Presentation();
Restore(pp, &mCapture, TRUE);
mCapture.SetValid(FALSE);
#endif
}
/*--------------------------------------------------------------------------*/
void SDK7A400_LCD::SetPointer(PegPoint Where)
{
#ifdef PEG_MOUSE_SUPPORT
LOCK_PEG
HidePointer();
mLastPointerPos = Where;
PegThing *pt = NULL;
PegPresentationManager *pp = pt->Presentation();
Where.x -= miCurXOffset;
Where.y -= miCurYOffset;
PegRect MouseRect;
MouseRect.wLeft = Where.x;
MouseRect.wTop = Where.y;
MouseRect.wBottom = MouseRect.wTop + mpCurPointer->wHeight - 1;
MouseRect.wRight = MouseRect.wLeft + mpCurPointer->wWidth - 1;
Capture(&mCapture, MouseRect);
Bitmap(pp, Where, mpCurPointer, TRUE);
UNLOCK_PEG
#else
// Suppress warning for unused variable
(void)Where;
#endif
}
/*--------------------------------------------------------------------------*/
void SDK7A400_LCD::Capture(PegCapture *Info, PegRect &Rect)
{
PegBitmap *pMap = Info->Bitmap();
if (Rect.wLeft < 0)
{
Rect.wLeft = 0;
}
if (Rect.wTop < 0)
{
Rect.wTop = 0;
}
Info->SetPos(Rect);
LONG Size = pMap->wWidth * pMap->wHeight * sizeof (COLORVAL);
Info->Realloc(Size);
COLORVAL *GetStart = mpScanPointers[Rect.wTop] + Rect.wLeft;
// make room for the memory bitmap:
pMap->uFlags = 0; // raw format
pMap->uBitsPix = sizeof (COLORVAL) * 8; // 8 or 16 bits per pixel
// fill in the image with our captured info:
COLORVAL *Put = (COLORVAL *) pMap->pStart;
for (WORD wLine = 0; wLine < pMap->wHeight; wLine++)
{
COLORVAL *Get = GetStart;
for (WORD wLoop = 0; wLoop < pMap->wWidth; wLoop++)
{
*Put++ = *Get++;
}
GetStart += mwHRes;
}
Info->SetValid(TRUE);
}
/*--------------------------------------------------------------------------*/
void SDK7A400_LCD::SetPalette(SIGNED iFirst, SIGNED iCount, const UCHAR *pGet)
{
// Convert the 8-bit color palette to a 16-bit color palette for use
// with the bitmap draw functions
COLORVAL *pPut = mcHiPalette;
COLORVAL c;
pPut += iFirst;
while(iCount--)
{
c = (*pGet++ & 0xF8) << (10-3); // 5 bits red
c = c | ((*pGet++ & 0xF8) << 5-3); // 5 bits green
c = c | ((*pGet++ & 0xF8) >> 3); // 5 bits blue
*pPut++ = c; // save the Hi-c equiv
}
}
/*--------------------------------------------------------------------------*/
UCHAR *SDK7A400_LCD::GetPalette(DWORD *pPutSize)
{
*pPutSize = mdNumColors;
return NULL;
}
/*--------------------------------------------------------------------------*/
void SDK7A400_LCD::ResetPalette(void)
{
SetPalette(0, 232, DefPalette256);
}
/*--------------------------------------------------------------------------*/
void SDK7A400_LCD::DrawTextView(PegPoint Put, const PEGCHAR *Text,
PegColor &Color, PegFont *pFont, SIGNED iLen, PegRect &View)
{
#ifdef PEG_UNICODE
PEGCHAR PEGFAR *pCurrentChar = (PEGCHAR PEGFAR *) Text;
PegFont *pFontStart = pFont;
#else
UCHAR PEGFAR *pCurrentChar = (UCHAR PEGFAR *) Text;
#endif
UCHAR PEGFAR *pGetData;
UCHAR PEGFAR *pGetDataBase;
WORD wIndex;
WORD wBitOffset;
SIGNED wXpos = Put.x;
WORD cVal = *pCurrentChar++;
SIGNED iCharWidth;
#ifdef DO_OUTLINE_TEXT
if (IS_OUTLINE(pFont))
{
DrawOutlineText(Put, Text, Color, pFont, iLen, View);
return;
}
#endif
while(cVal && wXpos <= View.wRight)
{
if (iLen == 0)
{
return;
}
iLen--;
#ifdef PEG_UNICODE
pFont = pFontStart;
while(Font)
{
if (cVal >= pFont->wFirstChar &&
cVal <= pFont->wLastChar)
{
break;
}
pFont = pFont->pNext;
}
if (!pFont) // this font doesn't contain this glyph?
{
cVal = *pCurrentChar++; // just skip to next char
continue;
}
wIndex = cVal - (WORD) pFont->wFirstChar;
if (IS_VARWIDTH(pFont))
{
wBitOffset = pFont->pOffsets[wIndex];
iCharWidth = pFont->pOffsets[wIndex+1] - wBitOffset;
}
else
{
iCharWidth = (SIGNED) pFont->pOffsets;
wBitOffset = iCharWidth * wIndex;
}
#else
wIndex = cVal - (WORD) pFont->wFirstChar;
wBitOffset = pFont->pOffsets[wIndex];
iCharWidth = pFont->pOffsets[wIndex+1] - wBitOffset;
#endif
if (wXpos + iCharWidth > View.wRight)
{
iCharWidth = View.wRight - wXpos + 1;
}
WORD ByteOffset = wBitOffset / 8;
pGetDataBase = pFont->pData + ByteOffset;
pGetDataBase += (View.wTop - Put.y) * pFont->wBytesPerLine;
for (SIGNED ScanRow = View.wTop; ScanRow <= View.wBottom; ScanRow++)
{
pGetData = pGetDataBase;
UCHAR InMask = 0x80 >> (wBitOffset & 7);
WORD wBitsOutput = 0;
UCHAR cData;
#ifdef PEG_UNICODE
if (ScanRow - Put.y < pFont->uHeight)
{
cData = *pGetData++;
}
else
{
cData = 0;
}
#else
cData = *pGetData++;
#endif
COLORVAL *Put = mpScanPointers[ScanRow] + wXpos;
while(wBitsOutput < iCharWidth)
{
if (!InMask)
{
InMask = 0x80;
// read a byte:
#ifdef PEG_UNICODE
if (ScanRow - Put.y < pFont->uHeight)
{
cData = *pGetData++;
}
else
{
cData = 0;
}
#else
cData = *pGetData++;
#endif
}
if (wXpos >= View.wLeft)
{
if (cData & InMask) // is this bit a 1?
{
*Put = Color.uForeground;
}
else
{
if (Color.uFlags & CF_FILL)
{
*Put = Color.uBackground;
}
}
}
InMask >>= 1;
wXpos++;
Put++;
wBitsOutput++;
if (wXpos > View.wRight)
{
break;
}
}
pGetDataBase += pFont->wBytesPerLine;
wXpos -= iCharWidth;
}
wXpos += iCharWidth;
cVal = *pCurrentChar++;
}
}
/*--------------------------------------------------------------------------*/
void SDK7A400_LCD::LineView(SIGNED xStart, SIGNED yStart,
SIGNED xEnd, SIGNED yEnd, PegRect &View, PegColor Color,
SIGNED iWidth)
{
if (yStart == yEnd)
{
HorizontalLine(View.wLeft, View.wRight, View.wTop, Color.uForeground, iWidth);
return;
}
if (xStart == xEnd)
{
VerticalLine(View.wTop, View.wBottom, View.wLeft, Color.uForeground, iWidth);
return;
}
SIGNED dx = abs(xEnd - xStart);
SIGNED dy = abs(yEnd - yStart);
if (((dx >= dy && (xStart > xEnd)) ||
((dy > dx) && yStart > yEnd)))
{
PEGSWAP(xEnd, xStart);
PEGSWAP(yEnd, yStart);
}
SIGNED y_sign = ((int) yEnd - (int) yStart) / dy;
SIGNED x_sign = ((int) xEnd - (int) xStart) / dx;
SIGNED decision;
SIGNED wCurx, wCury, wNextx, wNexty, wpy, wpx;
if (dx >= dy)
{
for (wCurx = xStart, wCury = yStart, wNextx = xEnd,
wNexty = yEnd, decision = (dx >> 1);
wCurx <= wNextx; wCurx++, wNextx--, decision += dy)
{
if (decision >= dx)
{
decision -= dx;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -