Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

344 lines
9.3 KiB

/*
*
* Copyright (c) Microsoft Corp. 1997
*
* All rights reserved.
*
* This file contains private, unpublished information and may not be
* copied in part or in whole without express permission of
* Microsoft Corp.
*
*/
#include "pch.cpp"
#pragma hdrstop
#include "commdrv.hpp"
#define FILLSPAN(left, right, zleft, zstep, px, result) \
do { \
int x = FXTOI(left); \
int w = FXTOI(right) - x; \
if (w > 0) { \
if ((x <= px) && (px < (x + w))) { \
int t = px - x; \
int z = zleft + t * zstep; \
*result = FXTOVAL(z >> 8); \
return TRUE; \
} \
} \
} while (0)
int ZTFill1(int xl, int dxl,
int xr, int dxr,
int zl, int dzl, int dz,
int h, int y, int px, int py, float* result)
{
while (1) {
h--;
if (y++ == py)
FILLSPAN(xl, xr, zl, dz, px, result);
if (!h) return FALSE;
xl += dxl;
xr += dxr;
zl += dzl;
}
}
int ZTFill2( int xl1, int dxl1,
int xl2, int dxl2,
int xr1, int dxr1,
int xr2, int dxr2,
int zl,
int dzl1,
int dzl2,
int dz,
int h1, int h2,
int y, int px, int py, float* result)
{
while (h1) {
h1--;
if (y++ == py)
FILLSPAN(xl1, xr1, zl, dz, px, result);
xl1 += dxl1;
xr1 += dxr1;
zl += dzl1;
}
while (1) {
h2--;
if (y++ == py)
FILLSPAN(xl2, xr2, zl, dz, px, result);
if (!h2) return FALSE;
xl2 += dxl2;
xr2 += dxr2;
zl += dzl2;
}
}
int GenPickTriangle(LPDIRECT3DDEVICEI lpDevI,
D3DTLVERTEX* base,
D3DTRIANGLE* tri,
D3DRECT* rect,
D3DVALUE* result)
{
int h1, h2, h3;
float h1s, h3s;
int y, y1, y2, y3;
D3DTLVERTEX *p1, *p2, *p3;
float xl, xr, xm, ml, ml2, mr, mr2;
float zl, zr, zm, mz, mz2, zstep;
float dx;
int px = rect->x1;
int py = rect->y1;
p1 = base + tri->v1;
p2 = base + tri->v2;
p3 = base + tri->v3;
y1 = VALTOI(p1->sy);
y2 = VALTOI(p2->sy);
y3 = VALTOI(p3->sy);
if (y1 == y2 && y2 == y3)
return FALSE;
{
int y;
D3DTLVERTEX *p;
/*
* Work out which vertex is topmost.
*/
if (y2 <= y1 && y2 <= y3) {
y = y1;
y1 = y2;
y2 = y3;
y3 = y;
p = p1;
p1 = p2;
p2 = p3;
p3 = p;
} else if (y3 <= y1 && y3 <= y2) {
y = y1;
y1 = y3;
y3 = y2;
y2 = y;
p = p1;
p1 = p3;
p3 = p2;
p2 = p;
}
}
y = y1;
if (py < y)
return FALSE;
if (py >= y2 && py >= y3)
return FALSE;
h1 = y2 - y1;
h2 = y3 - y2;
h3 = y3 - y1;
if (h1 == 0) {
xl = p1->sx;
xr = p2->sx;
dx = xr - xl;
if (dx <= 0)
return FALSE;
zl = p1->sz;
zr = p2->sz;
zstep = RLDDICheckDiv16(zr - zl, dx);
xm = p3->sx;
ml = (xm - xl) / h2;
mr = (xm - xr) / h2;
mz = ((p3->sz) - zl) / h2;
if (ZTFill1(VALTOFX(xl), VALTOFX(ml), VALTOFX(xr), VALTOFX(mr),
VALTOFX24(zl), VALTOFX24(mz), VALTOFX24(zstep), h2,
y, px, py, result)) {
return TRUE;
}
} else if (h2 == 0) {
xl = p3->sx;
xr = p2->sx;
dx = xr - xl;
if (dx <= 0)
return FALSE;
zl = p3->sz;
zr = p2->sz;
zm = p1->sz;
zstep = RLDDICheckDiv16(zr - zl, dx);
if (h1 == 1)
;
else {
xm = p1->sx;
ml = (xl - xm) / h1;
mr = (xr - xm) / h1;
mz = (zl - zm) / h1;
if (ZTFill1(VALTOFX(xm), VALTOFX(ml), VALTOFX(xm), VALTOFX(mr),
VALTOFX24(zm), VALTOFX24(mz), VALTOFX24(zstep), h1,
y, px, py, result)) {
return TRUE;
}
}
} else if (h3 == 0) {
xl = p3->sx;
xr = p1->sx;
dx = xr - xl;
if (dx <= 0)
return FALSE;
zl = p3->sz;
zr = p1->sz;
zstep = RLDDICheckDiv16(zr - zl, dx);
xm = p2->sx;
ml = (xm - xl) / h1;
mr = (xm - xr) / h1;
mz = ((p2->sz)- zl) / h1;
if (ZTFill1(VALTOFX(xl), VALTOFX(ml), VALTOFX(xr), VALTOFX(mr),
VALTOFX24(zl), VALTOFX24(mz), VALTOFX24(zstep), h1,
y, px, py, result)) {
return TRUE;
}
} else if (h1 < h3) {
float denom;
float dx1, dx2;
xl = p3->sx;
xr = p2->sx;
xm = p1->sx;
dx1 = xr - xm;
dx2 = xl - xm;
/*
* Make a stab at guessing the sign of the area for quick backface
* culling. Note that h1 and h3 are positive.
*/
if (dx1 < 0 && dx2 > 0)
return FALSE;
/*
* This uses Mul24 to get an 8 bit precision result otherwise
* we can get the wrong result for large triangles.
*/
denom = RLDDIFMul24(dx1, ITOVAL(h3)) - RLDDIFMul24(dx2, ITOVAL(h1));
if (denom <= 0)
return FALSE;
h1s = RLDDIFDiv8(ITOVAL(h1), denom);
h3s = RLDDIFDiv8(ITOVAL(h3), denom);
zl = p3->sz;
zr = p2->sz;
zm = p1->sz;
zstep = RLDDIFMul16(zr - zm, h3s) - RLDDIFMul16(zl - zm, h1s);
ml = (xl - xm) / h3;
mz = (zl - zm) / h3;
mr = (xr - xm) / h1;
mr2 = (xl - xr) / h2;
if (ZTFill2(VALTOFX(xm), VALTOFX(ml), VALTOFX(xm + h1*ml), VALTOFX(ml),
VALTOFX(xm), VALTOFX(mr), VALTOFX(xr), VALTOFX(mr2),
VALTOFX24(zm), VALTOFX24(mz), VALTOFX24(mz), VALTOFX24(zstep),
h1, h2, y, px, py, result)) {
return TRUE;
}
} else {
float denom;
float dx1, dx2;
xl = p3->sx;
xr = p2->sx;
xm = p1->sx;
dx1 = xr - xm;
dx2 = xl - xm;
/*
* Make a stab at guessing the sign of the area for quick backface
* culling. Note that h1 and h3 are positive.
*/
if (dx1 < 0 && dx2 > 0)
return FALSE;
/*
* This uses Mul24 to get an 8 bit precision result otherwise
* we can get the wrong result for large triangles.
*/
denom = RLDDIFMul24(dx1, ITOVAL(h3)) - RLDDIFMul24(dx2, ITOVAL(h1));
if (denom <= 0)
return FALSE;
h1s = RLDDIFDiv8(ITOVAL(h1), denom);
h3s = RLDDIFDiv8(ITOVAL(h3), denom);
zl = p3->sz;
zr = p2->sz;
zm = p1->sz;
zstep = RLDDIFMul16(zr - zm, h3s) - RLDDIFMul16(zl - zm, h1s);
ml = (xl - xm) / h3;
mz = (zl - zm) / h3;
mr = (xr - xm) / h1;
h2 = -h2;
ml2 = (xr - xl) / h2;
mz2 = (zr - zl) / h2;
if (ZTFill2(VALTOFX(xm), VALTOFX(ml), VALTOFX(xl), VALTOFX(ml2),
VALTOFX(xm), VALTOFX(mr), VALTOFX(xm + h3*mr), VALTOFX(mr),
VALTOFX24(zm), VALTOFX24(mz), VALTOFX24(mz2), VALTOFX24(zstep),
h3, h2, y, px, py, result)) {
return TRUE;
}
}
return FALSE;
}
HRESULT GenAddPickRecord(LPDIRECT3DDEVICEI lpDevI,
D3DOPCODE op, int offset, float result)
{
D3DI_PICKDATA* pdata = &lpDevI->pick_data;
int i;
i = pdata->pick_count++;
if (D3DRealloc((void**) &pdata->records, pdata->pick_count *
sizeof(D3DPICKRECORD))) {
return (DDERR_OUTOFMEMORY);
}
pdata->records[i].bOpcode = op;
pdata->records[i].dwOffset = offset;
pdata->records[i].dvZ = result;
return (D3D_OK);
}
HRESULT GenGetPickRecords(LPDIRECT3DDEVICEI lpDevI, D3DI_PICKDATA* pdata)
{
D3DI_PICKDATA* drv_pdata = &lpDevI->pick_data;
int picked_count;
int picked_size;
picked_count = drv_pdata->pick_count;
picked_size = picked_count * sizeof(D3DPICKRECORD);
if (pdata->records == NULL) {
pdata->pick_count = drv_pdata->pick_count;
} else {
memcpy((char*)pdata->records, (char*)drv_pdata->records, picked_size);
pdata->pick_count = drv_pdata->pick_count;
}
return (D3D_OK);
}