📄 lcd_drv.c
字号:
/*************************************************************************/
/* */
/* Copyright (c) 1999 Accelerated Technology, Inc. */
/* */
/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the */
/* subject matter of this material. All manufacturing, reproduction, */
/* use, and sales rights pertaining to this subject matter are governed */
/* by the license agreement. The recipient of this software implicitly */
/* accepts the terms of the license. */
/* */
/*************************************************************************/
/*************************************************************************/
/* */
/* FILE NAME VERSION */
/* */
/* lcd_drv.c 2.1 */
/* */
/* COMPONENT */
/* */
/* All */
/* */
/* DESCRIPTION */
/* */
/* This file contains lcd primitve driver routines. */
/* */
/* AUTHOR */
/* */
/* Robert G. Burrill, Accelerated Technology, Inc. */
/* */
/* DATA STRUCTURES */
/* */
/* None */
/* */
/* FUNCTIONS */
/* */
/* None */
/* */
/* DEPENDENCIES */
/* */
/* None */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* BobB 5/6/98 Corrected pixel addressing and */
/* added transparent raster ops. */
/* BobB 5/15/98 Corrected address of first pixel */
/* of each line. */
/* BobB 8/20/98 Corrected address of first pixel */
/* of each line. */
/* */
/*************************************************************************/
#include "meta_wnd.h"
#include "metconst.h" /* MetaWINDOW Constant & Stucture Definitions */
#include "metports.h" /* MetaWINDOW Port & Bitmap Definitions */
#include "metaproc.h"
#include "grafdata.h"
#include "regclipv.h"
#include "blit_5.h"
/* Function mwSPLCD is a special case optimization for SetPixel, LCD
memory destination, rectangular and/or region clipping with color
translation.
*******************************************
* Only patterns 0 and 1 are handled here, *
* and only raster ops 0 and 16!!!! *
*******************************************
blitCnt is ignored; it's assumed to be 1. */
void mwSPLCD(blitRcd *setPRec)
{
void DrawRectEntryPt(blitRcd *drwPRec);
int Set_Up_Clip(blitRcd *clipBlit, rect *clipR, int blitMayOverlap,
int isLine);
int Fill_Clip_Region(blitRcd *fcRec, rect *destRect);
void nuResume(grafMap *argGRAFMAP);
rect clipR; /* Clip rect */
point *drawPt; /* Pointer to point to draw */
int blitMayOverlap = 0; /* Set false */
int isLine = 0; /* Set false */
/* set up the rectangular/region clip info */
if (Set_Up_Clip(setPRec, &clipR, blitMayOverlap, isLine)) return;
drawPt = (point *) setPRec->blitList; /* set up pointer */
dRect.Xmin = drawPt->X;
dRect.Ymin = drawPt->Y;
M_PAUSE(setPRec->blitDmap); /* lock grafMap */
/* do we need to worry about clipping at all*/
if (clipToRectFlag == 0)
{ /* no--valid coordinates are guaranteed at a higher level */
DrawRectEntryPt(setPRec); /* draw the point */
}
else
{ /* yes first check trivial reject */
if ((dRect.Xmin >= clipR.Xmin) && (dRect.Ymin >= clipR.Ymin) &&
(dRect.Xmin < clipR.Xmax) && (dRect.Ymin < clipR.Ymax))
{ /* it passes so far - do we need to worry about region clipping? */
if (clipToRegionFlag == 0)
{ /* no, draw the point */
DrawRectEntryPt(setPRec);
}
else
{ /* yes, clip to the region and draw */
dRect.Xmax = dRect.Xmin + 1;
dRect.Ymax = dRect.Ymin + 1;
FillDrawer = &DrawRectEntryPt;
Fill_Clip_Region(setPRec, &dRect);
}
}
}
nuResume(setPRec->blitDmap);
return;
}
/* Function DrawRectEntryPt performs the drawing for the pixel routine */
void DrawRectEntryPt(blitRcd *drwPRec)
{
grafMap *drwGmap;
long *rowTable;
byte *bytePtr;
short pColor;
drwGmap = drwPRec->blitDmap; /* get grafMap */
rowTable = (long *) drwGmap->mapTable[0]; /* point to row table */
rowTable = rowTable + dRect.Ymin; /* look up the starting row */
/* point to pixel */
bytePtr = (byte *) ((*rowTable) + ((dRect.Xmin & 0xfffe) << 1) +
(dRect.Xmin & 1));
if (drwPRec->blitPat == 0) /* pattern 0? */
{ /* yes, use background color */
if (drwPRec->blitRop & 0x10) return; /* done if transparent */
pColor = (short) drwPRec->blitBack;
}
else
{ /* no, use foreground color */
pColor = (short) drwPRec->blitFore;
}
*bytePtr = (byte) pColor; /* draw the pixel; data doesn't matter */
return;
}
/* Function mwGPLCD is a special case optimization for GetPixel, LCD
memory source. */
int mwGPLCD(int gblX, int gblY, grafMap *getpBmap)
{
#define egaCntlrP1 (egaCntlr + 1)
void nuResume(grafMap *argGRAFMAP);
byte *rowTablePtr;
int pixelValue;
/* check if off bitmap */
if ((gblX < 0) || (gblY < 0) || (gblX >= getpBmap->pixWidth) ||
(gblY >= getpBmap->pixHeight)) return(0);
M_PAUSE(getpBmap); /* lock grafMap */
/* look up the starting row */
rowTablePtr = (byte *) (*(getpBmap->mapTable[0] + gblY));
rowTablePtr += (((gblX & 0xfffe) << 1) + (gblX & 1)); /* byte address of pixel */
/* get the pixel's byte */
pixelValue = *rowTablePtr;
nuResume(getpBmap);
return(pixelValue);
}
/* Function mwPBMSLCD is a special case optimization for memory
to LCD, rectangular clipping with no color translation. */
void mwPBMSLCD(blitRcd *blitRec)
{
int Check_YX_Band_Blit(rect *bandRect, rect *blitRectPtr,
rect *clipR, int *rectCnt);
void DrawRectEntryBlitML(blitRcd *blitRec);
int Set_Up_Clip(blitRcd *clipBlit, rect *clipR, int blitMayOverlap,
int isLine);
int Blit_Clip_Region(blitRcd *fcRec, rect *fillRect, rect *sRect);
void nuResume(grafMap *srcBmap);
void RepDestLCD(void);
void OXADestLCD(void);
void SetDestLCD(void);
void NotDestSolidLCD(void);
void InvertDestLCD(void);
void QuickEnd(void);
rect clipR; /* Clip rect */
rect *rListPtr; /* list pointer */
int blitMayOverlap = 0; /* Set false for region clipping*/
int isLine = 0; /* Set false */
rectCnt = blitRec->blitCnt;
rListPtr = (rect *) blitRec->blitList;
srcBmap = blitRec->blitSmap;
srcPixBytes = srcBmap->pixBytes;
M_PAUSE(srcBmap); /* pause the source */
bkColr = (char) blitRec->blitBack; /* background color */
pnColr = (char) blitRec->blitFore; /* foreground color */
dstBmap = blitRec->blitDmap;
dstClass = blitRec->blitRop & 0x0f;
M_PAUSE(dstBmap);
switch (dstClass)
{ /* look up the optimization routine */
/* LCD non-transparent */
case 0: /* zREPz : src */
case 4: /* zNREPz : (NOT src) */
optPtr = &RepDestLCD;
break;
case 1: /* zORz : src OR dst */
case 2: /* zXORz : src XOR dst */
case 3: /* zNANDz : (NOT src) AND dst */
case 5: /* zNORz : (NOT src) OR dst */
case 6: /* zNXORz : (NOT src) XOR dst */
case 7: /* zANDz : src AND dst */
optPtr = &OXADestLCD;
break;
case 8: /* zCLEARz : 0's */
case 12: /* zSETz : 1's */
optPtr = &SetDestLCD;
break;
case 9: /* zORNz : src OR (NOT dst) */
case 11: /* zANDNz : src AND (NOT dst) */
case 13: /* zNORNz : (NOT src) OR (NOT dst) */
case 15: /* zNANDNz : (NOT src) AND (NOT dst) */
optPtr = &NotDestSolidLCD;
break;
case 10: /* zNOPz : dst <NOP> */
optPtr = &QuickEnd;
break;
case 14: /* zINVERTz: (NOT dst) */
optPtr = &InvertDestLCD;
break;
}
/* modify the pen color as necessary */
switch (dstClass)
{
case 3: /* zNANDz */
case 4: /* zNREPz */
case 5: /* zNORz */
case 6: /* zNXORz */
case 13: /* zNORNz */
case 15: /* zNANDNz */
pnColr = (char)-1; /* this has the effect of notting the
pen color for all operations during this call */
case 0: /* zREPz */
case 1: /* zORz */
case 2: /* zXORz */
case 7: /* zANDz */
case 9: /* zORNz */
case 10: /* zNOPz */
case 11: /* zANDNz */
pnColr = 0;
break;
case 8: /* zCLEARz */
pnColr = 0; /* sets all source bits to 0 */
break;
case 12: /* zSETz */
case 14: /* zINVERTz */
pnColr = (char)-1; /* sets all source bits to 1 */
}
/* set up clipping */
if (Set_Up_Clip(blitRec, &clipR, blitMayOverlap, isLine))
goto PB_RTN;
while (--rectCnt >= 0 )
{
sRect = *rListPtr++;
dRect = *rListPtr++;
if (clipToRectFlag != 0) /* do we need to worry about clipping */
{ /* yes, do trivial reject */
if (dRect.Xmin < clipR.Xmin)
{ /* Reset src & dst Xmin clip limit */
sRect.Xmin -= (dRect.Xmin - clipR.Xmin);
dRect.Xmin = clipR.Xmin;
}
if (dRect.Ymin < clipR.Ymin)
{ /* Reset src & dst Ymin clip limit */
sRect.Ymin -= (dRect.Ymin - clipR.Ymin);
dRect.Ymin = clipR.Ymin;
}
if (dRect.Xmax > clipR.Xmax)
{ /* Reset src & dst Xmax clip limit */
sRect.Xmax -= (dRect.Xmax - clipR.Xmax);
dRect.Xmax = clipR.Xmax;
}
if (dRect.Ymax > clipR.Ymax)
{ /* Reset src & dst Ymax clip limit */
sRect.Ymax -= (dRect.Ymax - clipR.Ymax);
dRect.Ymax = clipR.Ymax;
}
if (dRect.Ymin >= dRect.Ymax)
{ /* Check to see whether the rectangle was trivially
clipped because it was fully below the clip rect,
in which case we can discard the rest of a YX banded
blitList, or because it was fully above the clip
rect, in which case we can whiz ahead through a YX
banded blitList until we run out of rects or find a
rect that isn't fully above the clip rect. */
if (Check_YX_Band_Blit(&dRect, rListPtr, &clipR,
&rectCnt)) break;
continue;
}
if (dRect.Xmin >= dRect.Xmax) continue;
/* do we need to worry about region clipping? */
if (clipToRegionFlag != 0)
{ /* yes */
FillDrawer = &DrawRectEntryBlitML;
if (Blit_Clip_Region(blitRec, &dRect, &sRect)
== 0) break;
continue;
}
}
DrawRectEntryBlitML(blitRec); /* blit the rectangle */
}
PB_RTN:
nuResume(srcBmap);
nuResume(dstBmap);
return;
}
/* Function DrawRectEntryBlitML blits the rectangle to the screen */
void DrawRectEntryBlitML(blitRcd *blitRec)
{
lineCntM1 = dRect.Ymax - dRect.Ymin - 1;
srcBgnByte = sRect.Xmin;
dstBgnByte = ((dRect.Xmin & 0xfffe) << 1) + (dRect.Xmin & 1);
byteCntM1 = dRect.Xmax - dRect.Xmin - 1;
srcNextRow = srcPixBytes - byteCntM1 - 1;
/* BobB 5/15/98 - corrected for first pixel addressing
dstNextRow = dstBmap->pixBytes - byteCntM1 - byteCntM1 - 2;*/
dstNextRow = dstBmap->pixBytes;
dstPtr = (byte *) (*(dstBmap->mapTable[0] + dRect.Ymin))
+ dstBgnByte;
srcPtr = (byte *) (*(srcBmap->mapTable[0] + sRect.Ymin))
+ srcBgnByte;
optPtr(); /* blit the rectangle */
return;
}
/* Function NotDestSolidLCD handles LCD "not dst" by inverting the
destination first. */
void NotDestSolidLCD(void)
{
void InvertDestLCD(void);
void OXADestLCD(void);
InvertDestLCD();
OXADestLCD(); /* fill this rectangle */
return;
}
/* Function InvertDestLCD inverts the destination pixel data. */
void InvertDestLCD(void)
{
byte *lclDstPtr;
int lclLineCnt, lclByteCnt;
/* BobB 5/18/98 - added for first pixel addressing */
byte * dstPtrSave;
lclDstPtr = dstPtr; /* set up local pointers */
lclLineCnt = lineCntM1;
while (lclLineCnt-- >= 0)
{ /* for each row */
/* BobB 5/18/98 - added for first pixel addressing */
dstPtrSave = lclDstPtr;
lclByteCnt = byteCntM1;
while (lclByteCnt-- >= 0)
{ /* for each byte in the row */
*lclDstPtr = ~(*lclDstPtr);
if (((long) lclDstPtr) & 1)
{ /* advance 3 bytes */
lclDstPtr += 3;
}
else
{ /* advance only 1 byte */
lclDstPtr++;
}
}
/* BobB 5/18/98 - corrected for first pixel addressing
lclDstPtr += dstNextRow;*/ /* advance to next row */
lclDstPtr = dstPtrSave + dstNextRow;
}
return;
}
/* Function SetDestLCD sets the destination pixel data. */
void SetDestLCD(void)
{
byte *lclDstPtr;
int lclLineCnt, lclByteCnt;
/* BobB 5/18/98 - added for first pixel addressing */
byte * dstPtrSave;
lclDstPtr = dstPtr; /* set up local pointers */
lclLineCnt = lineCntM1;
while (lclLineCnt-- >= 0)
{ /* for each row */
/* BobB 5/18/98 - added for first pixel addressing */
dstPtrSave = lclDstPtr;
lclByteCnt = byteCntM1;
while (lclByteCnt-- >= 0)
{ /* for each byte in the row */
*lclDstPtr = pnColr;
if (((long) lclDstPtr) & 1)
{ /* advance 3 bytes */
lclDstPtr += 3;
}
else
{ /* advance only 1 byte */
lclDstPtr++;
}
}
/* BobB 5/18/98 - corrected for first pixel addressing
lclDstPtr += dstNextRow;*/ /* advance to next row */
lclDstPtr = dstPtrSave + dstNextRow;
}
return;
}
/* Function RepDestLCD sets the destination pixel data with the
source data. */
void RepDestLCD(void)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -