1094 lines
29 KiB
C
1094 lines
29 KiB
C
/******************************************************************************\
|
|
*
|
|
* $Workfile: stripmm.c $
|
|
*
|
|
* Do what you can with no line support.
|
|
*
|
|
* I implemented the horizontal and vertical strip functions using
|
|
* solid fills, and removed the usage of diagonal strips. With a little
|
|
* effort you could implement diagonal strips by doing solid fills while
|
|
* playing with lDelta. This is probably not worth the trouble.
|
|
*
|
|
* Copyright (c) 1992-1997 Microsoft Corporation
|
|
* Copyright (c) 1996-1997 Cirrus Logic, Inc.,
|
|
*
|
|
* $Log: S:/projects/drivers/ntsrc/display/STRIPMM.C_V $
|
|
*
|
|
* Rev 1.2 10 Jan 1997 15:40:18 PLCHU
|
|
*
|
|
*
|
|
* Rev 1.1 Oct 10 1996 15:39:22 unknown
|
|
*
|
|
*
|
|
* Rev 1.1 12 Aug 1996 16:55:04 frido
|
|
* Removed unaccessed local variables.
|
|
*
|
|
* chu01 : 01-02-97 5480 BitBLT enhancement
|
|
* chu02 : 01-09-97 Macro redefinition
|
|
*
|
|
\******************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
|
|
#define count COMMAND_TOTAL_PACKETS
|
|
|
|
#define MM_DRAW_HORZ_STRIP(xy, cx, lDelta, cBpp)\
|
|
{\
|
|
ULONG ulDstAddr;\
|
|
\
|
|
ulDstAddr = xy;\
|
|
\
|
|
CP_MM_WAIT_FOR_BLT_COMPLETE(ppdev, pjBase);\
|
|
CP_MM_XCNT(ppdev, pjBase, (PELS_TO_BYTES(cx) - 1));\
|
|
CP_MM_YCNT(ppdev, pjBase, 0);\
|
|
CP_MM_DST_ADDR(ppdev, pjBase, ulDstAddr);\
|
|
CP_MM_START_BLT(ppdev, pjBase);\
|
|
}
|
|
|
|
#define MM_DRAW_VERT_STRIP(xy, cy, lDelta, cBpp)\
|
|
{\
|
|
ULONG ulDstAddr;\
|
|
\
|
|
ulDstAddr = xy;\
|
|
\
|
|
CP_MM_WAIT_FOR_BLT_COMPLETE(ppdev, pjBase);\
|
|
CP_MM_XCNT(ppdev, pjBase, (cBpp - 1));\
|
|
CP_MM_YCNT(ppdev, pjBase, (cy - 1));\
|
|
CP_MM_DST_ADDR(ppdev, pjBase, ulDstAddr);\
|
|
CP_MM_START_BLT(ppdev, pjBase);\
|
|
}
|
|
|
|
#define MM_DRAW_VERT_STRIP_FLIPPED(xy, cy, lDelta, cBpp)\
|
|
{\
|
|
ULONG ulDstAddr;\
|
|
\
|
|
ulDstAddr = xy - ((cy - 1) * lDelta);\
|
|
\
|
|
CP_MM_WAIT_FOR_BLT_COMPLETE(ppdev, pjBase);\
|
|
CP_MM_XCNT(ppdev, pjBase, (cBpp - 1));\
|
|
CP_MM_YCNT(ppdev, pjBase, (cy - 1));\
|
|
CP_MM_DST_ADDR(ppdev, pjBase, ulDstAddr);\
|
|
CP_MM_START_BLT(ppdev, pjBase);\
|
|
}
|
|
|
|
// chu01, chu02
|
|
#define MM_DRAW_HORZ_STRIP80(x, y, cx)\
|
|
{\
|
|
CP_MM_WAIT_FOR_BLT_COMPLETE(ppdev, pjBase);\
|
|
CP_MM_BLT_EXT_MODE(ppdev, pjBase, ENABLE_XY_POSITION);\
|
|
CP_MM_XCNT(ppdev, pjBase, (cx - 1));\
|
|
CP_MM_YCNT(ppdev, pjBase, 0);\
|
|
CP_MM_DST_ADDR(ppdev, pjBase, 0);\
|
|
CP_MM_DST_Y(ppdev, pjBase, y);\
|
|
CP_MM_DST_X(ppdev, pjBase, x);\
|
|
}
|
|
|
|
#define MM_DRAW_VERT_STRIP80(x, y, cy)\
|
|
{\
|
|
CP_MM_WAIT_FOR_BLT_COMPLETE(ppdev, pjBase);\
|
|
CP_MM_BLT_EXT_MODE(ppdev, pjBase, ENABLE_XY_POSITION);\
|
|
CP_MM_XCNT(ppdev, pjBase, 0);\
|
|
CP_MM_YCNT(ppdev, pjBase, (cy - 1));\
|
|
CP_MM_DST_ADDR(ppdev, pjBase, 0);\
|
|
CP_MM_DST_Y(ppdev, pjBase, y);\
|
|
CP_MM_DST_X(ppdev, pjBase, x);\
|
|
}
|
|
|
|
#define MM_DRAW_VERT_STRIP_FLIPPED80(x, y, cy)\
|
|
{\
|
|
CP_MM_WAIT_FOR_BLT_COMPLETE(ppdev, pjBase);\
|
|
CP_MM_BLT_EXT_MODE(ppdev, pjBase, ENABLE_XY_POSITION);\
|
|
CP_MM_XCNT(ppdev, pjBase, 0);\
|
|
CP_MM_YCNT(ppdev, pjBase, (cy - 1));\
|
|
CP_MM_DST_ADDR(ppdev, pjBase, 0);\
|
|
CP_MM_DST_Y(ppdev, pjBase, ((y - cy) + 1));\
|
|
CP_MM_DST_X(ppdev, pjBase, x);\
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID vMmSolidHorizontal
|
|
*
|
|
* Draws left-to-right x-major near-horizontal lines using solid fills.
|
|
*
|
|
* Assumes fgRop, BgRop, and Color are already set correctly.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID vMmSolidHorizontal(
|
|
PDEV* ppdev,
|
|
STRIP* pStrip,
|
|
LINESTATE* pLineState)
|
|
{
|
|
BYTE* pjBase = ppdev->pjBase;
|
|
LONG cBpp = ppdev->cBpp;
|
|
LONG lDelta = ppdev->lDelta;
|
|
LONG cStrips = pStrip->cStrips;
|
|
PLONG pStrips = pStrip->alStrips;
|
|
LONG x = pStrip->ptlStart.x;
|
|
LONG y = pStrip->ptlStart.y;
|
|
LONG xy = PELS_TO_BYTES(x) + (lDelta * y);
|
|
LONG yInc = 1;
|
|
LONG i;
|
|
|
|
DISPDBG((2, "vMmSolidHorizontal"));
|
|
|
|
if (!(pStrip->flFlips & FL_FLIP_V))
|
|
{
|
|
//
|
|
// Horizontal strips ->
|
|
// ->
|
|
//
|
|
|
|
for (i = 0; i < cStrips; i++)
|
|
{
|
|
MM_DRAW_HORZ_STRIP(xy, *pStrips, lDelta, cBpp);
|
|
x += *pStrips;
|
|
xy += PELS_TO_BYTES(*pStrips); // x+
|
|
xy += lDelta; // y+
|
|
pStrips++;
|
|
}
|
|
y += cStrips;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// ->
|
|
// Horizontal strips ->
|
|
//
|
|
|
|
for (i = 0; i < cStrips; i++)
|
|
{
|
|
MM_DRAW_HORZ_STRIP(xy, *pStrips, lDelta, cBpp);
|
|
x += *pStrips;
|
|
xy += PELS_TO_BYTES(*pStrips); // x+
|
|
xy -= lDelta; // y+
|
|
pStrips++;
|
|
}
|
|
y -= cStrips;
|
|
}
|
|
|
|
pStrip->ptlStart.x = x;
|
|
pStrip->ptlStart.y = y;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID vMmSolidVertical
|
|
*
|
|
* Draws left-to-right y-major near-vertical lines using solid fills.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID vMmSolidVertical(
|
|
PDEV* ppdev,
|
|
STRIP* pStrip,
|
|
LINESTATE* pLineState)
|
|
{
|
|
BYTE* pjBase = ppdev->pjBase;
|
|
LONG cBpp = ppdev->cBpp;
|
|
LONG lDelta = ppdev->lDelta;
|
|
LONG cStrips = pStrip->cStrips;
|
|
PLONG pStrips = pStrip->alStrips;
|
|
LONG x = pStrip->ptlStart.x;
|
|
LONG y = pStrip->ptlStart.y;
|
|
LONG xy = PELS_TO_BYTES(x) + (lDelta * y);
|
|
LONG i;
|
|
|
|
DISPDBG((2, "vMmSolidVertical"));
|
|
|
|
if (!(pStrip->flFlips & FL_FLIP_V))
|
|
{
|
|
//
|
|
// |
|
|
// Vertical strips v
|
|
// |
|
|
// v
|
|
//
|
|
|
|
for (i = 0; i < cStrips; i++)
|
|
{
|
|
MM_DRAW_VERT_STRIP(xy, *pStrips, lDelta, cBpp);
|
|
y += *pStrips;
|
|
xy += cBpp; // x+
|
|
xy += (*pStrips * lDelta); // y+
|
|
pStrips++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// ^
|
|
// Vertical strips |
|
|
// ^
|
|
// |
|
|
//
|
|
|
|
for (i = 0; i < cStrips; i++)
|
|
{
|
|
MM_DRAW_VERT_STRIP_FLIPPED(xy, *pStrips, lDelta, cBpp);
|
|
y -= *pStrips;
|
|
xy += cBpp; // x+
|
|
xy -= (*pStrips * lDelta); // y-
|
|
pStrips++;
|
|
}
|
|
}
|
|
x += cStrips;
|
|
|
|
pStrip->ptlStart.x = x;
|
|
pStrip->ptlStart.y = y;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID vMmStyledHorizontal
|
|
*
|
|
* Takes the list of strips that define the pixels that would be lit for
|
|
* a solid line, and breaks them into styling chunks according to the
|
|
* styling information that is passed in.
|
|
*
|
|
* This particular routine handles x-major lines that run left-to-right,
|
|
* and are comprised of horizontal strips. It draws the dashes using
|
|
* short-stroke vectors.
|
|
*
|
|
* The performance of this routine could be improved significantly if
|
|
* anyone cared enough about styled lines improve it.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID vMmStyledHorizontal(
|
|
PDEV* ppdev,
|
|
STRIP* pstrip,
|
|
LINESTATE* pls)
|
|
{
|
|
BYTE* pjBase = ppdev->pjBase;
|
|
LONG cBpp = ppdev->cBpp;
|
|
LONG lDelta = ppdev->lDelta;
|
|
LONG x = pstrip->ptlStart.x; // x position of start of first strip
|
|
LONG y = pstrip->ptlStart.y; // y position of start of first strip
|
|
LONG xy = PELS_TO_BYTES(x) + (lDelta * y);
|
|
LONG* plStrip = pstrip->alStrips; // Points to current strip
|
|
LONG cStrips = pstrip->cStrips; // Total number of strips we'll do
|
|
LONG dy;
|
|
LONG dylDelta;
|
|
LONG cStyle;
|
|
LONG cStrip;
|
|
LONG cThis;
|
|
ULONG bIsGap;
|
|
|
|
DISPDBG((2, "vMmStyledHorizontal"));
|
|
|
|
if (pstrip->flFlips & FL_FLIP_V)
|
|
{
|
|
// The minor direction of the line is 90 degrees, and the major
|
|
// direction is 0 (it's a left-to-right x-major line going up):
|
|
|
|
dy = -1;
|
|
dylDelta = -lDelta;
|
|
}
|
|
else
|
|
{
|
|
// The minor direction of the line is 270 degrees, and the major
|
|
// direction is 0 (it's a left-to-right x-major line going down):
|
|
|
|
dy = 1;
|
|
dylDelta = lDelta;
|
|
}
|
|
|
|
cStrip = *plStrip; // Number of pels in first strip
|
|
|
|
cStyle = pls->spRemaining; // Number of pels in first 'gap' or 'dash'
|
|
bIsGap = pls->ulStyleMask; // Tells whether in a 'gap' or a 'dash'
|
|
|
|
// ulStyleMask is non-zero if we're in the middle of a 'gap',
|
|
// and zero if we're in the middle of a 'dash':
|
|
|
|
if (bIsGap)
|
|
goto SkipAGap;
|
|
else
|
|
goto OutputADash;
|
|
|
|
PrepareToSkipAGap:
|
|
|
|
// Advance in the style-state array, so that we can find the next
|
|
// 'dot' that we'll have to display:
|
|
|
|
bIsGap = ~bIsGap;
|
|
pls->psp++;
|
|
if (pls->psp > pls->pspEnd)
|
|
pls->psp = pls->pspStart;
|
|
|
|
cStyle = *pls->psp;
|
|
|
|
// If 'cStrip' is zero, we also need a new strip:
|
|
|
|
if (cStrip != 0)
|
|
goto SkipAGap;
|
|
|
|
// Here, we're in the middle of a 'gap' where we don't have to
|
|
// display anything. We simply cycle through all the strips
|
|
// we can, keeping track of the current position, until we run
|
|
// out of 'gap':
|
|
|
|
while (TRUE)
|
|
{
|
|
// Each time we loop, we move to a new scan and need a new strip:
|
|
|
|
y += dy;
|
|
xy += dylDelta;
|
|
|
|
plStrip++;
|
|
cStrips--;
|
|
if (cStrips == 0)
|
|
goto AllDone;
|
|
|
|
cStrip = *plStrip;
|
|
|
|
SkipAGap:
|
|
|
|
cThis = min(cStrip, cStyle);
|
|
cStyle -= cThis;
|
|
cStrip -= cThis;
|
|
|
|
x += cThis;
|
|
xy += PELS_TO_BYTES(cThis);
|
|
|
|
if (cStyle == 0)
|
|
goto PrepareToOutputADash;
|
|
}
|
|
|
|
PrepareToOutputADash:
|
|
|
|
// Advance in the style-state array, so that we can find the next
|
|
// 'dot' that we'll have to display:
|
|
|
|
bIsGap = ~bIsGap;
|
|
pls->psp++;
|
|
if (pls->psp > pls->pspEnd)
|
|
pls->psp = pls->pspStart;
|
|
|
|
cStyle = *pls->psp;
|
|
|
|
// If 'cStrip' is zero, we also need a new strip.
|
|
|
|
if (cStrip != 0)
|
|
{
|
|
// There's more to be done in the current strip:
|
|
|
|
goto OutputADash;
|
|
}
|
|
|
|
// We've finished with the current strip:
|
|
|
|
while (TRUE)
|
|
{
|
|
// Each time we loop, we move to a new scan and need a new strip:
|
|
|
|
y += dy;
|
|
xy += dylDelta;
|
|
|
|
plStrip++;
|
|
cStrips--;
|
|
if (cStrips == 0)
|
|
goto AllDone;
|
|
|
|
cStrip = *plStrip;
|
|
|
|
OutputADash:
|
|
|
|
cThis = min(cStrip, cStyle);
|
|
cStyle -= cThis;
|
|
cStrip -= cThis;
|
|
|
|
MM_DRAW_HORZ_STRIP(xy, cThis, lDelta, cBpp);
|
|
|
|
x += cThis;
|
|
xy += PELS_TO_BYTES(cThis); // x+
|
|
|
|
if (cStyle == 0)
|
|
goto PrepareToSkipAGap;
|
|
}
|
|
|
|
AllDone:
|
|
|
|
// Update our state variables so that the next line can continue
|
|
// where we left off:
|
|
|
|
pls->spRemaining = cStyle;
|
|
pls->ulStyleMask = bIsGap;
|
|
pstrip->ptlStart.x = x;
|
|
pstrip->ptlStart.y = y;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID vMmStyledVertical
|
|
*
|
|
* Takes the list of strips that define the pixels that would be lit for
|
|
* a solid line, and breaks them into styling chunks according to the
|
|
* styling information that is passed in.
|
|
*
|
|
* This particular routine handles y-major lines that run left-to-right,
|
|
* and are comprised of vertical strips. It draws the dashes using
|
|
* short-stroke vectors.
|
|
*
|
|
* The performance of this routine could be improved significantly if
|
|
* anyone cared enough about styled lines improve it.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID vMmStyledVertical(
|
|
PDEV* ppdev,
|
|
STRIP* pstrip,
|
|
LINESTATE* pls)
|
|
{
|
|
BYTE* pjBase = ppdev->pjBase;
|
|
LONG cBpp = ppdev->cBpp;
|
|
LONG lDelta = ppdev->lDelta;
|
|
LONG x = pstrip->ptlStart.x; // x position of start of first strip
|
|
LONG y = pstrip->ptlStart.y; // y position of start of first strip
|
|
LONG xy = PELS_TO_BYTES(x) + (lDelta * y);
|
|
LONG* plStrip = pstrip->alStrips; // Points to current strip
|
|
LONG cStrips = pstrip->cStrips; // Total number of strips we'll do
|
|
LONG dy;
|
|
LONG dylDelta;
|
|
LONG cStyle;
|
|
LONG cStrip;
|
|
LONG cThis;
|
|
ULONG bIsGap;
|
|
|
|
DISPDBG((2, "vMmStyledVertical")) ;
|
|
|
|
if (pstrip->flFlips & FL_FLIP_V)
|
|
{
|
|
// The minor direction of the line is 0 degrees, and the major
|
|
// direction is 90 (it's a left-to-right y-major line going up):
|
|
|
|
dy = -1;
|
|
dylDelta = -lDelta;
|
|
}
|
|
else
|
|
{
|
|
// The minor direction of the line is 0 degrees, and the major
|
|
// direction is 270 (it's a left-to-right y-major line going down):
|
|
|
|
dy = 1;
|
|
dylDelta = lDelta;
|
|
}
|
|
|
|
cStrip = *plStrip; // Number of pels in first strip
|
|
|
|
cStyle = pls->spRemaining; // Number of pels in first 'gap' or 'dash'
|
|
bIsGap = pls->ulStyleMask; // Tells whether in a 'gap' or a 'dash'
|
|
|
|
// ulStyleMask is non-zero if we're in the middle of a 'gap',
|
|
// and zero if we're in the middle of a 'dash':
|
|
|
|
if (bIsGap)
|
|
goto SkipAGap;
|
|
else
|
|
goto OutputADash;
|
|
|
|
PrepareToSkipAGap:
|
|
|
|
// Advance in the style-state array, so that we can find the next
|
|
// 'dot' that we'll have to display:
|
|
|
|
bIsGap = ~bIsGap;
|
|
pls->psp++;
|
|
if (pls->psp > pls->pspEnd)
|
|
pls->psp = pls->pspStart;
|
|
|
|
cStyle = *pls->psp;
|
|
|
|
// If 'cStrip' is zero, we also need a new strip:
|
|
|
|
if (cStrip != 0)
|
|
goto SkipAGap;
|
|
|
|
// Here, we're in the middle of a 'gap' where we don't have to
|
|
// display anything. We simply cycle through all the strips
|
|
// we can, keeping track of the current position, until we run
|
|
// out of 'gap':
|
|
|
|
while (TRUE)
|
|
{
|
|
// Each time we loop, we move to a new column and need a new strip:
|
|
|
|
xy += cBpp;
|
|
x++;
|
|
|
|
plStrip++;
|
|
cStrips--;
|
|
if (cStrips == 0)
|
|
goto AllDone;
|
|
|
|
cStrip = *plStrip;
|
|
|
|
SkipAGap:
|
|
|
|
cThis = min(cStrip, cStyle);
|
|
cStyle -= cThis;
|
|
cStrip -= cThis;
|
|
|
|
if (dy > 0)
|
|
{
|
|
y += cThis;
|
|
xy += (cThis * lDelta);
|
|
}
|
|
else
|
|
{
|
|
y -= cThis;
|
|
xy -= (cThis * lDelta);
|
|
}
|
|
|
|
if (cStyle == 0)
|
|
goto PrepareToOutputADash;
|
|
}
|
|
|
|
PrepareToOutputADash:
|
|
|
|
// Advance in the style-state array, so that we can find the next
|
|
// 'dot' that we'll have to display:
|
|
|
|
bIsGap = ~bIsGap;
|
|
pls->psp++;
|
|
if (pls->psp > pls->pspEnd)
|
|
pls->psp = pls->pspStart;
|
|
|
|
cStyle = *pls->psp;
|
|
|
|
// If 'cStrip' is zero, we also need a new strip.
|
|
|
|
if (cStrip != 0)
|
|
{
|
|
// There's more to be done in the current strip:
|
|
|
|
goto OutputADash;
|
|
}
|
|
|
|
// We've finished with the current strip:
|
|
|
|
while (TRUE)
|
|
{
|
|
// Each time we loop, we move to a new column and need a new strip:
|
|
|
|
xy += cBpp;
|
|
x++;
|
|
|
|
plStrip++;
|
|
cStrips--;
|
|
if (cStrips == 0)
|
|
goto AllDone;
|
|
|
|
cStrip = *plStrip;
|
|
|
|
OutputADash:
|
|
|
|
cThis = min(cStrip, cStyle);
|
|
cStyle -= cThis;
|
|
cStrip -= cThis;
|
|
|
|
if (dy <= 0)
|
|
{
|
|
MM_DRAW_VERT_STRIP_FLIPPED(xy, cThis, lDelta, cBpp);
|
|
y -= cThis; // y-
|
|
xy -= (cThis * lDelta); // y-
|
|
}
|
|
else
|
|
{
|
|
MM_DRAW_VERT_STRIP(xy, cThis, lDelta, cBpp);
|
|
y += cThis; // y+
|
|
xy += (cThis * lDelta); // y+
|
|
}
|
|
|
|
|
|
if (cStyle == 0)
|
|
goto PrepareToSkipAGap;
|
|
}
|
|
|
|
AllDone:
|
|
|
|
// Update our state variables so that the next line can continue
|
|
// where we left off:
|
|
|
|
pls->spRemaining = cStyle;
|
|
pls->ulStyleMask = bIsGap;
|
|
pstrip->ptlStart.x = x;
|
|
pstrip->ptlStart.y = y;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID vInvalidStrip
|
|
*
|
|
* Put this in the function table for entries that shouldn't get hit.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID vInvalidStrip(
|
|
PDEV* ppdev, // unused
|
|
STRIP* pStrip, // unused
|
|
LINESTATE* pLineState) // unused
|
|
{
|
|
|
|
RIP("vInvalidStrip called");
|
|
return;
|
|
}
|
|
|
|
// chu01
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* B i t B L T E n h a n c e m e n t F o r C L - G D 5 4 8 0
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID vMmSolidHorizontal80(
|
|
PDEV* ppdev,
|
|
STRIP* pStrip,
|
|
LINESTATE* pLineState)
|
|
{
|
|
BYTE* pjBase = ppdev->pjBase ;
|
|
LONG cBpp = ppdev->cBpp ;
|
|
LONG lDelta = ppdev->lDelta ;
|
|
LONG cStrips = pStrip->cStrips ;
|
|
PLONG pStrips = pStrip->alStrips ; // cx for each stroke
|
|
LONG x = pStrip->ptlStart.x ; // X-position
|
|
LONG y = pStrip->ptlStart.y ; // Y-position
|
|
LONG yOrg = y ;
|
|
LONG yInc = 1 ;
|
|
LONG x0, y0, cx ;
|
|
|
|
ULONG ulDstOffset = 0 ;
|
|
ULONG_PTR* ulCLStart ;
|
|
ULONG ulWidthHeight ;
|
|
|
|
LONG i = 0 ;
|
|
BYTE MM1B ;
|
|
|
|
DISPDBG((2, "vMmSolidHorizontal80")) ;
|
|
|
|
if (!(pStrip->flFlips & FL_FLIP_V))
|
|
{
|
|
//
|
|
// Horizontal strips -> 1.
|
|
// -> 2.
|
|
//
|
|
if (cStrips != 1)
|
|
{
|
|
MM1B = ENABLE_COMMAND_LIST | ENABLE_XY_POSITION | SRC_CPU_DATA ;
|
|
CP_MM_BLT_EXT_MODE(ppdev, pjBase, MM1B) ;
|
|
Loop_H1:
|
|
ulCLStart = ppdev->pCommandList ;
|
|
ulDstOffset = (ULONG)(((ULONG_PTR)ulCLStart
|
|
- (ULONG_PTR)ppdev->pjScreen) << 14) ;
|
|
CP_MM_CL_SWITCH(ppdev) ;
|
|
|
|
// First strip
|
|
x0 = x ;
|
|
y0 = y ;
|
|
cx = *pStrips ;
|
|
i++ ;
|
|
|
|
// Next strip
|
|
y++ ;
|
|
x += cx ;
|
|
pStrips++ ;
|
|
|
|
while (TRUE)
|
|
{
|
|
// GR20, GR21, GR22, GR23
|
|
ulWidthHeight = PACKXY_FAST((*pStrips - 1), 0) ;
|
|
ulWidthHeight |= COMMAND_NOSRC_NOTHING ;
|
|
|
|
// GR40, GR41, GR42, GR43
|
|
*(ulCLStart + 1) = PACKXY_FAST(x, y) ;
|
|
|
|
// GR2C, GR2D, GR2E
|
|
*(ulCLStart + 2) = 0 ;
|
|
|
|
i++ ;
|
|
|
|
if ((i == cStrips) || ((i % count) == 0))
|
|
{
|
|
// Last Command
|
|
ulWidthHeight |= COMMAND_LAST_PACKET ;
|
|
*ulCLStart = ulWidthHeight ;
|
|
break ;
|
|
}
|
|
*ulCLStart = ulWidthHeight ;
|
|
|
|
// Next strip
|
|
y++ ;
|
|
x += *pStrips ;
|
|
pStrips++ ;
|
|
ulCLStart += 4 ;
|
|
}
|
|
|
|
CP_MM_WAIT_FOR_BLT_COMPLETE(ppdev, pjBase) ;
|
|
CP_MM_XCNT(ppdev, pjBase, (cx - 1)) ;
|
|
CP_MM_YCNT(ppdev, pjBase, 0) ;
|
|
CP_MM_DST_ADDR(ppdev, pjBase, ulDstOffset) ;
|
|
CP_MM_DST_Y(ppdev, pjBase, y0) ;
|
|
CP_MM_DST_X(ppdev, pjBase, x0) ;
|
|
|
|
if (i == cStrips)
|
|
x += *pStrips ;
|
|
else if ((i % count) == 0)
|
|
{
|
|
//
|
|
// Resume a new command list
|
|
//
|
|
y++ ;
|
|
cx = *pStrips ;
|
|
x += cx ;
|
|
pStrips++ ;
|
|
if (i != (cStrips - 1))
|
|
{
|
|
goto Loop_H1 ;
|
|
}
|
|
else
|
|
{
|
|
MM_DRAW_HORZ_STRIP80(x, y, *pStrips) ;
|
|
x += *pStrips ;
|
|
pStrips++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MM_DRAW_HORZ_STRIP80(x, y, *pStrips) ;
|
|
x += *pStrips ;
|
|
pStrips++;
|
|
}
|
|
yOrg += cStrips;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// -> 2.
|
|
// Horizontal strips -> 1.
|
|
//
|
|
if (cStrips != 1)
|
|
{
|
|
MM1B = ENABLE_COMMAND_LIST | ENABLE_XY_POSITION | SRC_CPU_DATA ;
|
|
CP_MM_BLT_EXT_MODE(ppdev, pjBase, MM1B) ;
|
|
Loop_H2:
|
|
ulCLStart = ppdev->pCommandList;
|
|
ulDstOffset = (ULONG)(((ULONG_PTR)ulCLStart
|
|
- (ULONG_PTR)ppdev->pjScreen) << 14) ;
|
|
CP_MM_CL_SWITCH(ppdev) ;
|
|
|
|
// First strip
|
|
x0 = x ;
|
|
y0 = y ;
|
|
cx = *pStrips ;
|
|
i++ ;
|
|
|
|
// Next strip
|
|
y-- ;
|
|
x += cx ;
|
|
pStrips++ ;
|
|
|
|
while (TRUE)
|
|
{
|
|
// GR20, GR21, GR22, GR23
|
|
ulWidthHeight = PACKXY_FAST((*pStrips - 1), 0) ;
|
|
ulWidthHeight |= COMMAND_NOSRC_NOTHING ;
|
|
|
|
// GR40, GR41, GR42, GR43
|
|
*(ulCLStart + 1) = PACKXY_FAST(x, y) ;
|
|
|
|
// GR2C, GR2D, GR2E
|
|
*(ulCLStart + 2) = 0 ;
|
|
|
|
i++ ;
|
|
|
|
if ((i == cStrips) || ((i % count) == 0))
|
|
{
|
|
// Last Command
|
|
ulWidthHeight |= COMMAND_LAST_PACKET ;
|
|
*ulCLStart = ulWidthHeight ;
|
|
break ;
|
|
}
|
|
*ulCLStart = ulWidthHeight ;
|
|
|
|
// Next strip
|
|
y-- ;
|
|
x += *pStrips ;
|
|
pStrips++ ;
|
|
ulCLStart += 4 ;
|
|
}
|
|
|
|
CP_MM_WAIT_FOR_BLT_COMPLETE(ppdev, pjBase) ;
|
|
CP_MM_XCNT(ppdev, pjBase, (cx - 1)) ;
|
|
CP_MM_YCNT(ppdev, pjBase, 0) ;
|
|
CP_MM_DST_ADDR(ppdev, pjBase, ulDstOffset) ;
|
|
CP_MM_DST_Y(ppdev, pjBase, y0) ;
|
|
CP_MM_DST_X(ppdev, pjBase, x0) ;
|
|
|
|
if (i == cStrips)
|
|
x += *pStrips ;
|
|
else if ((i % count) == 0)
|
|
{
|
|
//
|
|
// Resume a new command list
|
|
//
|
|
y-- ;
|
|
cx = *pStrips ;
|
|
x += cx ;
|
|
pStrips++ ;
|
|
if (i != (cStrips - 1))
|
|
{
|
|
goto Loop_H2 ;
|
|
}
|
|
else
|
|
{
|
|
MM_DRAW_HORZ_STRIP80(x, y, *pStrips) ;
|
|
x += *pStrips ;
|
|
pStrips++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MM_DRAW_HORZ_STRIP80(x, y, *pStrips) ;
|
|
x += *pStrips ;
|
|
pStrips++;
|
|
}
|
|
yOrg -= cStrips;
|
|
}
|
|
|
|
pStrip->ptlStart.x = x ;
|
|
pStrip->ptlStart.y = yOrg ;
|
|
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VOID vMmSolidVertical80
|
|
*
|
|
* Draws left-to-right y-major near-vertical lines using solid fills.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID vMmSolidVertical80(
|
|
PDEV* ppdev,
|
|
STRIP* pStrip,
|
|
LINESTATE* pLineState)
|
|
{
|
|
BYTE* pjBase = ppdev->pjBase ;
|
|
LONG cBpp = ppdev->cBpp ;
|
|
LONG lDelta = ppdev->lDelta ;
|
|
LONG cStrips = pStrip->cStrips ;
|
|
PLONG pStrips = pStrip->alStrips ;
|
|
LONG x = pStrip->ptlStart.x ;
|
|
LONG y = pStrip->ptlStart.y ;
|
|
LONG xOrg = x ;
|
|
LONG x0, y0, cy ;
|
|
|
|
ULONG ulDstOffset = 0 ;
|
|
ULONG_PTR* ulCLStart ;
|
|
ULONG ulWidthHeight ;
|
|
|
|
LONG i = 0 ;
|
|
BYTE MM1B ;
|
|
|
|
DISPDBG((2, "vMmSolidVertical80")) ;
|
|
|
|
if (!(pStrip->flFlips & FL_FLIP_V))
|
|
{
|
|
//
|
|
// | 1.
|
|
// Vertical strips v
|
|
// | 2.
|
|
// v
|
|
//
|
|
if (cStrips != 1)
|
|
{
|
|
MM1B = ENABLE_COMMAND_LIST | ENABLE_XY_POSITION | SRC_CPU_DATA ;
|
|
CP_MM_BLT_EXT_MODE(ppdev, pjBase, MM1B) ;
|
|
Loop_V1:
|
|
ulCLStart = ppdev->pCommandList ;
|
|
ulDstOffset = (ULONG)(((ULONG_PTR)ulCLStart
|
|
- (ULONG_PTR)ppdev->pjScreen) << 14) ;
|
|
CP_MM_CL_SWITCH(ppdev) ;
|
|
|
|
// First strip
|
|
x0 = x ;
|
|
y0 = y ;
|
|
cy = *pStrips ;
|
|
i++ ;
|
|
|
|
// Next strip
|
|
x++ ;
|
|
y += cy ;
|
|
pStrips++ ;
|
|
|
|
while (TRUE)
|
|
{
|
|
// GR20, GR21, GR22, GR23
|
|
ulWidthHeight = PACKXY_FAST(0, (*pStrips - 1)) ;
|
|
ulWidthHeight |= COMMAND_NOSRC_NOTHING ;
|
|
|
|
// GR40, GR41, GR42, GR43
|
|
*(ulCLStart + 1) = PACKXY_FAST(x, y) ;
|
|
|
|
// GR2C, GR2D, GR2E
|
|
*(ulCLStart + 2) = 0 ;
|
|
|
|
i++ ;
|
|
|
|
if ((i == cStrips) || ((i % count) == 0))
|
|
{
|
|
// Last Command
|
|
ulWidthHeight |= COMMAND_LAST_PACKET ;
|
|
*ulCLStart = ulWidthHeight ;
|
|
break ;
|
|
}
|
|
*ulCLStart = ulWidthHeight ;
|
|
|
|
// Next strip
|
|
x++ ;
|
|
y += *pStrips ;
|
|
pStrips++ ;
|
|
ulCLStart += 4 ;
|
|
}
|
|
CP_MM_WAIT_FOR_BLT_COMPLETE(ppdev, pjBase) ;
|
|
CP_MM_XCNT(ppdev, pjBase, 0) ;
|
|
CP_MM_YCNT(ppdev, pjBase, (cy - 1)) ;
|
|
CP_MM_DST_ADDR(ppdev, pjBase, ulDstOffset) ;
|
|
CP_MM_DST_Y(ppdev, pjBase, y0) ;
|
|
CP_MM_DST_X(ppdev, pjBase, x0) ;
|
|
|
|
if (i == cStrips)
|
|
y += *pStrips ;
|
|
else if ((i % count) == 0)
|
|
{
|
|
//
|
|
// Resume a new command list
|
|
//
|
|
x++ ;
|
|
cy = *pStrips ;
|
|
y += cy ;
|
|
pStrips++ ;
|
|
if (i != (cStrips - 1))
|
|
{
|
|
goto Loop_V1 ;
|
|
}
|
|
else
|
|
{
|
|
MM_DRAW_VERT_STRIP80(x, y, *pStrips) ;
|
|
y += *pStrips ;
|
|
pStrips++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MM_DRAW_VERT_STRIP80(x, y, *pStrips) ;
|
|
y += *pStrips ;
|
|
pStrips++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// ^
|
|
// Vertical strips | 2.
|
|
// ^
|
|
// | 1.
|
|
//
|
|
|
|
if (cStrips != 1)
|
|
{
|
|
MM1B = ENABLE_COMMAND_LIST | ENABLE_XY_POSITION | SRC_CPU_DATA ;
|
|
CP_MM_BLT_EXT_MODE(ppdev, pjBase, MM1B) ;
|
|
Loop_V2:
|
|
ulCLStart = ppdev->pCommandList ;
|
|
ulDstOffset = (ULONG)(((ULONG_PTR)ulCLStart
|
|
- (ULONG_PTR)ppdev->pjScreen) << 14) ;
|
|
CP_MM_CL_SWITCH(ppdev) ;
|
|
|
|
// First strip
|
|
x0 = x ;
|
|
cy = *pStrips ;
|
|
y -= (cy - 1) ;
|
|
y0 = y ;
|
|
|
|
i++ ;
|
|
pStrips++ ;
|
|
|
|
// Next strip
|
|
x++ ;
|
|
y -= *pStrips ;
|
|
|
|
while (TRUE)
|
|
{
|
|
// GR20, GR21, GR22, GR23
|
|
ulWidthHeight = PACKXY_FAST(0, (*pStrips - 1)) ;
|
|
ulWidthHeight |= COMMAND_NOSRC_NOTHING ;
|
|
|
|
// GR40, GR41, GR42, GR43
|
|
*(ulCLStart + 1) = PACKXY_FAST(x, y) ;
|
|
|
|
// GR2C, GR2D, GR2E
|
|
*(ulCLStart + 2) = 0 ;
|
|
|
|
i++ ;
|
|
|
|
if ((i == cStrips) || ((i % count) == 0))
|
|
{
|
|
// Last Command
|
|
ulWidthHeight |= COMMAND_LAST_PACKET ;
|
|
*ulCLStart = ulWidthHeight ;
|
|
break ;
|
|
}
|
|
*ulCLStart = ulWidthHeight ;
|
|
|
|
// Next strip
|
|
x++ ;
|
|
pStrips++ ;
|
|
y -= *pStrips ;
|
|
|
|
ulCLStart += 4 ;
|
|
}
|
|
|
|
CP_MM_WAIT_FOR_BLT_COMPLETE(ppdev, pjBase) ;
|
|
CP_MM_XCNT(ppdev, pjBase, 0) ;
|
|
CP_MM_YCNT(ppdev, pjBase, (cy - 1)) ;
|
|
CP_MM_DST_ADDR(ppdev, pjBase, ulDstOffset) ;
|
|
CP_MM_DST_Y(ppdev, pjBase, y0) ;
|
|
CP_MM_DST_X(ppdev, pjBase, x0);
|
|
|
|
if (i == cStrips)
|
|
y -= *pStrips ;
|
|
else if ((i % count) == 0)
|
|
{
|
|
//
|
|
// Resume a new command list
|
|
//
|
|
x++ ;
|
|
y-- ;
|
|
pStrips++ ;
|
|
|
|
if (i != (cStrips - 1))
|
|
{
|
|
goto Loop_V2 ;
|
|
}
|
|
else
|
|
{
|
|
MM_DRAW_VERT_STRIP80(x, y, *pStrips) ;
|
|
y -= *pStrips ;
|
|
pStrips++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MM_DRAW_VERT_STRIP_FLIPPED80(x, y, *pStrips) ;
|
|
y -= *pStrips ;
|
|
pStrips++;
|
|
}
|
|
}
|
|
|
|
xOrg += cStrips ;
|
|
pStrip->ptlStart.x = xOrg ;
|
|
pStrip->ptlStart.y = y ;
|
|
|
|
}
|