brender-1997/pentprim/L_PI.C

1466 lines
28 KiB
C++
Raw Normal View History

2022-05-03 16:30:35 -05:00
/*
* Copyright (c) 1993 Argonaut Software Ltd. All rights reserved.
*
* $Id: L_PI.C 1.2 1996/10/16 13:13:50 NIKH Exp $
* $Locker: $
*
* Mesh rendering to produce edges
*/
#include "drv.h"
#include "shortcut.h"
#include "blockops.h"
#include "brassert.h"
static char rscid[] = "$Id: L_PI.C 1.2 1996/10/16 13:13:50 NIKH Exp $";
#define ABS(x) (((x)< 0)?-(x):(x))
#define SWAP(type,a,b) { type _t; _t = a; a = b; b = _t; }
#define ScalarsToRGB15(r,g,b) \
(((b) >> 19) & 0x1f | ((g) >> 14) & 0x3e0 | ((r) >> 9) & 0x7c00)
#define ScalarsToRGB16(r,g,b) \
(((b) >> 19) & 0x1f | ((g) >> 13) & 0x7c0 | ((r) >> 8) & 0xf800)
#define ScalarsToRGB24(r,g,b) \
(((b) >> 16) & 0xff | ((g) >> 8) & 0xff00 | ((r) >> 8) & 0xff0000)
#define SETUP_TEXTURE \
width = work.texture.width_p; \
height = work.texture.height; \
stride = work.texture.stride_b;
#define SETUP_LINE \
x0 = v0->comp_x[C_SX]; \
y0 = v0->comp_x[C_SY]; \
x1 = v1->comp_x[C_SX]; \
y1 = v1->comp_x[C_SY]; \
\
X0 = BrFixedToInt(x0); \
Y0 = BrFixedToInt(y0); \
X1 = BrFixedToInt(x1); \
Y1 = BrFixedToInt(y1); \
\
CLAMP_LP(X0,Y0); \
CLAMP_LP(X1,Y1); \
\
dx = X1-X0; \
dy = Y1-Y0;
/*
* Line drawers - Proper Bresenham algorithm
*/
#if PARTS & PART_8
/*
* Gouraud shaded line
*/
void BR_ASM_CALL LineRenderPII(struct brp_block *block, union brp_vertex *v0,union brp_vertex *v1)
{
br_fixed_ls dx,dy;
br_fixed_ls pm,dm,pi,di,x0,x1,y0,y1;
int error;
int count,offset,base;
int X0,Y0,X1,Y1;
char *ptr;
int dptr;
SETUP_LINE;
error = 0;
if(ABS(dx) > ABS(dy)) {
/*
* Major axis is X axis - ensure dx is +ve
*/
if(dx < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = 1+(dy>0 ? work.colour.stride_b : -work.colour.stride_b);
dy = ABS(dy);
if (dx<0)
return;
pi = v0->comp_x[C_I];
if(dx > 0) {
di = BrFixedDiv((v1->comp_x[C_I] - v0->comp_x[C_I]),BrIntToFixed(dx));
}
ptr = (char *)work.colour.base+X0+Y0*work.colour.stride_b;
count = dx;
while(count-- >= 0) {
/*
* plot pixel
*/
*ptr = (br_uint_8)BrFixedToInt(pi);
error += dy;
if (error>0) {
error -= dx;
ptr += dptr;
} else {
ptr++;
}
/*
* Update parameters
*/
pi += di;
}
} else {
/*
* Major axis is Y axis - ensure dy is +ve
*/
if(dy < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = work.colour.stride_b+(dx>0 ? 1 : -1);
dx = ABS(dx);
if (dy<0)
return;
pi = v0->comp_x[C_I];
if(dy > 0) {
di = BrFixedDiv((v1->comp_x[C_I] - v0->comp_x[C_I]),BrIntToFixed(dy));
}
ptr = (char *)work.colour.base+X0+Y0*work.colour.stride_b;
count = dy;
while(count-- >= 0) {
/*
* plot pixel
*/
*ptr = (br_uint_8)BrFixedToInt(pi);
error += dx;
if (error>0) {
error -= dy;
ptr += dptr;
} else {
ptr += work.colour.stride_b;
}
/*
* Update parameters
*/
pi += di;
}
}
}
#endif
#if PARTS & PART_8
/*
* Arbitrary size lit textured lines
*/
void BR_ASM_CALL LineRenderPITI(struct brp_block *block, union brp_vertex *v0,union brp_vertex *v1)
{
br_fixed_ls dx,dy;
br_fixed_ls pm,dm,pi,di,x0,x1,y0,y1;
br_fixed_ls pu,pv,du,dv;
int error;
int count,offset,base;
int X0,Y0,X1,Y1;
char *ptr;
int dptr;
int width,height,stride;
SETUP_LINE;
SETUP_TEXTURE;
error = 0;
if(ABS(dx) > ABS(dy)) {
/*
* Major axis is X axis - ensure dx is +ve
*/
if(dx < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = 1+(dy>0 ? work.colour.stride_b : -work.colour.stride_b);
dy = ABS(dy);
if (dx<0)
return;
pi = v0->comp_x[C_I];
pu = v0->comp_x[C_U] % BrIntToFixed(width);
if (pu<0)
pu += BrIntToFixed(width);
pv = v0->comp_x[C_V] % BrIntToFixed(height);
if (pv<0)
pv += BrIntToFixed(height);
if(dx > 0) {
di = BrFixedDiv((v1->comp_x[C_I] - v0->comp_x[C_I]),BrIntToFixed(dx));
du = BrFixedDiv((v1->comp_x[C_U] - v0->comp_x[C_U]),BrIntToFixed(dx));
dv = BrFixedDiv((v1->comp_x[C_V] - v0->comp_x[C_V]),BrIntToFixed(dx));
du = du % BrIntToFixed(width);
if (du>0)
du -= BrIntToFixed(width);
dv = dv % BrIntToFixed(height);
if (dv>0)
dv -= BrIntToFixed(height);
}
ptr = (char *)work.colour.base+X0+Y0*work.colour.stride_b;
count = dx;
while(count-- >= 0) {
/*
* plot pixel
*/
{
char texel;
texel = ((char *)work.texture.base)[(pv>>16)*stride+(pu>>16)];
*ptr = work.shade_table[((pi>>8) & 0xff00)+texel];
}
error += dy;
if (error>0) {
error -= dx;
ptr += dptr;
} else {
ptr++;
}
/*
* Update parameters
*/
pi += di;
pu += du;
if (pu<0)
pu += BrIntToFixed(width);
pv += dv;
if (pv<0)
pv += BrIntToFixed(height);
}
} else {
/*
* Major axis is Y axis - ensure dy is +ve
*/
if(dy < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = work.colour.stride_b+(dx>0 ? 1 : -1);
dx = ABS(dx);
if (dy<0)
return;
pi = v0->comp_x[C_I];
pu = v0->comp_x[C_U] % BrIntToFixed(width);
if (pu<0)
pu += BrIntToFixed(width);
pv = v0->comp_x[C_V] % BrIntToFixed(height);
if (pv<0)
pv += BrIntToFixed(height);
if(dy > 0) {
di = BrFixedDiv((v1->comp_x[C_I] - v0->comp_x[C_I]),BrIntToFixed(dy));
du = BrFixedDiv((v1->comp_x[C_U] - v0->comp_x[C_U]),BrIntToFixed(dy));
dv = BrFixedDiv((v1->comp_x[C_V] - v0->comp_x[C_V]),BrIntToFixed(dy));
du = du % BrIntToFixed(width);
if (du>0)
du -= BrIntToFixed(width);
dv = dv % BrIntToFixed(height);
if (dv>0)
dv -= BrIntToFixed(height);
}
ptr = (char *)work.colour.base+X0+Y0*work.colour.stride_b;
count = dy;
while(count-- >= 0) {
/*
* plot pixel
*/
{
char texel;
texel = ((char *)work.texture.base)[(pv>>16)*stride+(pu>>16)];
*ptr = work.shade_table[((pi>>8) & 0xff00)+texel];
}
error += dx;
if (error>0) {
error -= dy;
ptr += dptr;
} else {
ptr += work.colour.stride_b;
}
/*
* Update parameters
*/
pi += di;
pu += du;
if (pu<0)
pu += BrIntToFixed(width);
pv += dv;
if (pv<0)
pv += BrIntToFixed(height);
}
}
}
#endif
#if PARTS & PART_8
/*
* Arbitrary size textured lines
*/
void BR_ASM_CALL LineRenderPIT(struct brp_block *block, union brp_vertex *v0,union brp_vertex *v1)
{
br_fixed_ls dx,dy;
br_fixed_ls pm,dm,x0,x1,y0,y1;
br_fixed_ls pu,pv,du,dv;
int error;
int count,offset,base;
int X0,Y0,X1,Y1;
char *ptr;
int dptr;
int width,height,stride;
char texel;
SETUP_TEXTURE;
SETUP_LINE;
error = 0;
if(ABS(dx) > ABS(dy)) {
/*
* Major axis is X axis - ensure dx is +ve
*/
if(dx < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = 1+(dy>0 ? work.colour.stride_b : -work.colour.stride_b);
dy = ABS(dy);
if (dx<0)
return;
pu = v0->comp_x[C_U] % BrIntToFixed(width);
if (pu<0)
pu += BrIntToFixed(width);
pv = v0->comp_x[C_V] % BrIntToFixed(height);
if (pv<0)
pv += BrIntToFixed(height);
if(dx > 0) {
du = BrFixedDiv((v1->comp_x[C_U] - v0->comp_x[C_U]),BrIntToFixed(dx));
dv = BrFixedDiv((v1->comp_x[C_V] - v0->comp_x[C_V]),BrIntToFixed(dx));
du = du % BrIntToFixed(width);
if (du>0)
du -= BrIntToFixed(width);
dv = dv % BrIntToFixed(height);
if (dv>0)
dv -= BrIntToFixed(height);
}
ptr = (char *)work.colour.base+X0+Y0*work.colour.stride_b;
count = dx;
while(count-- >= 0) {
/*
* plot pixel
*/
texel = ((char *)work.texture.base)[(pv>>16)*stride+(pu>>16)];
*ptr = texel;
error += dy;
if (error>0) {
error -= dx;
ptr += dptr;
} else {
ptr++;
}
/*
* Update parameters
*/
pu += du;
if (pu<0)
pu += BrIntToFixed(width);
pv += dv;
if (pv<0)
pv += BrIntToFixed(height);
}
} else {
/*
* Major axis is Y axis - ensure dy is +ve
*/
if(dy < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = work.colour.stride_b+(dx>0 ? 1 : -1);
dx = ABS(dx);
if (dy<0)
return;
pu = v0->comp_x[C_U] % BrIntToFixed(width);
if (pu<0)
pu += BrIntToFixed(width);
pv = v0->comp_x[C_V] % BrIntToFixed(height);
if (pv<0)
pv += BrIntToFixed(height);
if(dy > 0) {
du = BrFixedDiv((v1->comp_x[C_U] - v0->comp_x[C_U]),BrIntToFixed(dy));
dv = BrFixedDiv((v1->comp_x[C_V] - v0->comp_x[C_V]),BrIntToFixed(dy));
du = du % BrIntToFixed(width);
if (du>0)
du -= BrIntToFixed(width);
dv = dv % BrIntToFixed(height);
if (dv>0)
dv -= BrIntToFixed(height);
}
ptr = (char *)work.colour.base+X0+Y0*work.colour.stride_b;
count = dy;
while(count-- >= 0) {
/*
* plot pixel
*/
texel = ((char *)work.texture.base)[(pv>>16)*stride+(pu>>16)];
*ptr = texel;
error += dx;
if (error>0) {
error -= dy;
ptr += dptr;
} else {
ptr += work.colour.stride_b;
}
/*
* Update parameters
*/
pu += du;
if (pu<0)
pu += BrIntToFixed(width);
pv += dv;
if (pv<0)
pv += BrIntToFixed(height);
}
}
}
#endif
#if PARTS & PART_24
/*
* 24 bit textured lines
*/
void BR_ASM_CALL LineRenderPIT_RGB_888(struct brp_block *block, union brp_vertex *v0,union brp_vertex *v1)
{
br_fixed_ls dx,dy;
br_fixed_ls pm,dm,x0,x1,y0,y1;
br_fixed_ls pu,pv,du,dv;
int error;
int count,offset,base;
int X0,Y0,X1,Y1;
char *ptr;
int dptr;
int width,height,stride;
SETUP_TEXTURE;
SETUP_LINE;
error = 0;
if(ABS(dx) > ABS(dy)) {
/*
* Major axis is X axis - ensure dx is +ve
*/
if(dx < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = 3+(dy>0 ? work.colour.stride_b : -work.colour.stride_b);
dy = ABS(dy);
if (dx<0)
return;
pu = v0->comp_x[C_U] % BrIntToFixed(width);
if (pu<0)
pu += BrIntToFixed(width);
pv = v0->comp_x[C_V] % BrIntToFixed(height);
if (pv<0)
pv += BrIntToFixed(height);
if(dx > 0) {
du = BrFixedDiv((v1->comp_x[C_U] - v0->comp_x[C_U]),BrIntToFixed(dx));
dv = BrFixedDiv((v1->comp_x[C_V] - v0->comp_x[C_V]),BrIntToFixed(dx));
du = du % BrIntToFixed(width);
if (du>0)
du -= BrIntToFixed(width);
dv = dv % BrIntToFixed(height);
if (dv>0)
dv -= BrIntToFixed(height);
}
ptr = (char *)work.colour.base+3*X0+Y0*work.colour.stride_b;
count = dx;
while(count-- >= 0) {
/*
* plot pixel
*/
{
char *texel;
texel = (char *)work.texture.base+(pv>>16)*stride+3*(pu>>16);
if (texel[0] || texel[1] || texel[2]) {
ptr[0] = texel[0];
ptr[1] = texel[1];
ptr[2] = texel[2];
}
}
error += dy;
if (error>0) {
error -= dx;
ptr += dptr;
} else {
ptr += 3;
}
/*
* Update parameters
*/
pu += du;
if (pu<0)
pu += BrIntToFixed(width);
pv += dv;
if (pv<0)
pv += BrIntToFixed(height);
}
} else {
/*
* Major axis is Y axis - ensure dy is +ve
*/
if(dy < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = work.colour.stride_b+(dx>0 ? 3 : -3);
dx = ABS(dx);
if (dy<0)
return;
pu = v0->comp_x[C_U] % BrIntToFixed(width);
if (pu<0)
pu += BrIntToFixed(width);
pv = v0->comp_x[C_V] % BrIntToFixed(height);
if (pv<0)
pv += BrIntToFixed(height);
if(dy > 0) {
du = BrFixedDiv((v1->comp_x[C_U] - v0->comp_x[C_U]),BrIntToFixed(dy));
dv = BrFixedDiv((v1->comp_x[C_V] - v0->comp_x[C_V]),BrIntToFixed(dy));
du = du % BrIntToFixed(width);
if (du>0)
du -= BrIntToFixed(width);
dv = dv % BrIntToFixed(height);
if (dv>0)
dv -= BrIntToFixed(height);
}
ptr = (char *)work.colour.base+X0*3+Y0*work.colour.stride_b;
count = dy;
while(count-- >= 0) {
/*
* plot pixel
*/
{
char *texel;
texel = (char *)work.texture.base+(pv>>16)*stride+3*(pu>>16);
if (texel[0] || texel[1] || texel[2]) {
ptr[0] = texel[0];
ptr[1] = texel[1];
ptr[2] = texel[2];
}
}
error += dx;
if (error>0) {
error -= dy;
ptr += dptr;
} else {
ptr += work.colour.stride_b;
}
/*
* Update parameters
*/
pu += du;
if (pu<0)
pu += BrIntToFixed(width);
pv += dv;
if (pv<0)
pv += BrIntToFixed(height);
}
}
}
#endif
#if PARTS & PART_24
/*
* Gouraud shaded 24-bit lines
*/
void BR_ASM_CALL LineRenderPII_RGB_888(struct brp_block *block, union brp_vertex *v0,union brp_vertex *v1)
{
br_fixed_ls dx,dy;
br_fixed_ls pm,dm,x0,x1,y0,y1;
br_fixed_ls pr,pg,pb,dr,dg,db;
int error;
int count,offset,base;
int X0,Y0,X1,Y1;
char *ptr;
int dptr;
SETUP_LINE;
error = 0;
if(ABS(dx) > ABS(dy)) {
/*
* Major axis is X axis - ensure dx is +ve
*/
if(dx < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = 3+(dy>0 ? work.colour.stride_b : -work.colour.stride_b);
dy = ABS(dy);
if (dx<0)
return;
pr = v0->comp_x[C_R];
pg = v0->comp_x[C_G];
pb = v0->comp_x[C_B];
if(dx > 0) {
dr = BrFixedDiv((v1->comp_x[C_R] - v0->comp_x[C_R]),BrIntToFixed(dx));
dg = BrFixedDiv((v1->comp_x[C_G] - v0->comp_x[C_G]),BrIntToFixed(dx));
db = BrFixedDiv((v1->comp_x[C_B] - v0->comp_x[C_B]),BrIntToFixed(dx));
}
ptr = (char *)work.colour.base+3*X0+Y0*work.colour.stride_b;
count = dx;
while(count-- >= 0) {
/*
* plot pixel
*/
ptr[0] = pb >> 16;
ptr[1] = pg >> 16;
ptr[2] = pr >> 16;
error += dy;
if (error>0) {
error -= dx;
ptr += dptr;
} else {
ptr += 3;
}
/*
* Update parameters
*/
pr += dr;
pg += dg;
pb += db;
}
} else {
/*
* Major axis is Y axis - ensure dy is +ve
*/
if(dy < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = work.colour.stride_b+(dx>0 ? 3 : -3);
dx = ABS(dx);
if (dy<0)
return;
pr = v0->comp_x[C_R];
pg = v0->comp_x[C_G];
pb = v0->comp_x[C_B];
if(dy > 0) {
dr = BrFixedDiv((v1->comp_x[C_R] - v0->comp_x[C_R]),BrIntToFixed(dy));
dg = BrFixedDiv((v1->comp_x[C_G] - v0->comp_x[C_G]),BrIntToFixed(dy));
db = BrFixedDiv((v1->comp_x[C_B] - v0->comp_x[C_B]),BrIntToFixed(dy));
}
ptr = (char *)work.colour.base+X0*3+Y0*work.colour.stride_b;
count = dy;
while(count-- >= 0) {
/*
* plot pixel
*/
ptr[0] = pb >> 16;
ptr[1] = pg >> 16;
ptr[2] = pr >> 16;
error += dx;
if (error>0) {
error -= dy;
ptr += dptr;
} else {
ptr += work.colour.stride_b;
}
/*
* Update parameters
*/
pr += dr;
pg += dg;
pb += db;
}
}
}
#endif
#if PARTS & PART_15
/*
* 15 bit textured lines
*/
void BR_ASM_CALL LineRenderPIT_RGB_555(struct brp_block *block, union brp_vertex *v0,union brp_vertex *v1)
{
br_fixed_ls dx,dy;
br_fixed_ls pm,dm,x0,x1,y0,y1;
br_fixed_ls pu,pv,du,dv;
int error;
int count,offset,base;
int X0,Y0,X1,Y1;
char *ptr;
int dptr;
int width,height,stride;
SETUP_TEXTURE;
SETUP_LINE;
error = 0;
if(ABS(dx) > ABS(dy)) {
/*
* Major axis is X axis - ensure dx is +ve
*/
if(dx < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = 2+(dy>0 ? work.colour.stride_b : -work.colour.stride_b);
dy = ABS(dy);
if (dx<0)
return;
pu = v0->comp_x[C_U] % BrIntToFixed(width);
if (pu<0)
pu += BrIntToFixed(width);
pv = v0->comp_x[C_V] % BrIntToFixed(height);
if (pv<0)
pv += BrIntToFixed(height);
if(dx > 0) {
du = BrFixedDiv((v1->comp_x[C_U] - v0->comp_x[C_U]),BrIntToFixed(dx));
dv = BrFixedDiv((v1->comp_x[C_V] - v0->comp_x[C_V]),BrIntToFixed(dx));
du = du % BrIntToFixed(width);
if (du>0)
du -= BrIntToFixed(width);
dv = dv % BrIntToFixed(height);
if (dv>0)
dv -= BrIntToFixed(height);
}
ptr = (char *)work.colour.base+2*X0+Y0*work.colour.stride_b;
count = dx;
while(count-- >= 0) {
/*
* plot pixel
*/
{
unsigned short texel;
texel = *(unsigned short *)((char *)work.texture.base+(pv>>16)*stride+2*(pu>>16));
if (texel)
*(short *)ptr = texel;
}
error += dy;
if (error>0) {
error -= dx;
ptr += dptr;
} else {
ptr += 2;
}
/*
* Update parameters
*/
pu += du;
if (pu<0)
pu += BrIntToFixed(width);
pv += dv;
if (pv<0)
pv += BrIntToFixed(height);
}
} else {
/*
* Major axis is Y axis - ensure dy is +ve
*/
if(dy < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = work.colour.stride_b+(dx>0 ? 2 : -2);
dx = ABS(dx);
if (dy<0)
return;
pu = v0->comp_x[C_U] % BrIntToFixed(width);
if (pu<0)
pu += BrIntToFixed(width);
pv = v0->comp_x[C_V] % BrIntToFixed(height);
if (pv<0)
pv += BrIntToFixed(height);
if(dy > 0) {
du = BrFixedDiv((v1->comp_x[C_U] - v0->comp_x[C_U]),BrIntToFixed(dy));
dv = BrFixedDiv((v1->comp_x[C_V] - v0->comp_x[C_V]),BrIntToFixed(dy));
du = du % BrIntToFixed(width);
if (du>0)
du -= BrIntToFixed(width);
dv = dv % BrIntToFixed(height);
if (dv>0)
dv -= BrIntToFixed(height);
}
ptr = (char *)work.colour.base+X0*2+Y0*work.colour.stride_b;
count = dy;
while(count-- >= 0) {
/*
* plot pixel
*/
{
unsigned short texel;
texel = *(unsigned short *)((char *)work.texture.base+(pv>>16)*stride+2*(pu>>16));
if (texel)
*(unsigned short *)ptr = texel;
}
error += dx;
if (error>0) {
error -= dy;
ptr += dptr;
} else {
ptr += work.colour.stride_b;
}
/*
* Update parameters
*/
pu += du;
if (pu<0)
pu += BrIntToFixed(width);
pv += dv;
if (pv<0)
pv += BrIntToFixed(height);
}
}
}
#endif
#if PARTS & PART_15
/*
* Gouraud shaded 15-bit lines
*/
void BR_ASM_CALL LineRenderPII_RGB_555(struct brp_block *block, union brp_vertex *v0,union brp_vertex *v1)
{
br_fixed_ls dx,dy;
br_fixed_ls pm,dm,x0,x1,y0,y1;
br_fixed_ls pr,pg,pb,dr,dg,db;
int error;
int count,offset,base;
int X0,Y0,X1,Y1;
char *ptr;
int dptr;
SETUP_LINE;
error = 0;
if(ABS(dx) > ABS(dy)) {
/*
* Major axis is X axis - ensure dx is +ve
*/
if(dx < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = 2+(dy>0 ? work.colour.stride_b : -work.colour.stride_b);
dy = ABS(dy);
if (dx<0)
return;
pr = v0->comp_x[C_R];
pg = v0->comp_x[C_G];
pb = v0->comp_x[C_B];
if(dx > 0) {
dr = BrFixedDiv((v1->comp_x[C_R] - v0->comp_x[C_R]),BrIntToFixed(dx));
dg = BrFixedDiv((v1->comp_x[C_G] - v0->comp_x[C_G]),BrIntToFixed(dx));
db = BrFixedDiv((v1->comp_x[C_B] - v0->comp_x[C_B]),BrIntToFixed(dx));
}
ptr = (char *)work.colour.base+2*X0+Y0*work.colour.stride_b;
count = dx;
while(count-- >= 0) {
/*
* plot pixel
*/
*(unsigned short *)ptr = ScalarsToRGB15(pr,pg,pb);
error += dy;
if (error>0) {
error -= dx;
ptr += dptr;
} else {
ptr += 2;
}
/*
* Update parameters
*/
pr += dr;
pg += dg;
pb += db;
}
} else {
/*
* Major axis is Y axis - ensure dy is +ve
*/
if(dy < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = work.colour.stride_b+(dx>0 ? 2 : -2);
dx = ABS(dx);
if (dy<0)
return;
pr = v0->comp_x[C_R];
pg = v0->comp_x[C_G];
pb = v0->comp_x[C_B];
if(dy > 0) {
dr = BrFixedDiv((v1->comp_x[C_R] - v0->comp_x[C_R]),BrIntToFixed(dy));
dg = BrFixedDiv((v1->comp_x[C_G] - v0->comp_x[C_G]),BrIntToFixed(dy));
db = BrFixedDiv((v1->comp_x[C_B] - v0->comp_x[C_B]),BrIntToFixed(dy));
}
ptr = (char *)work.colour.base+X0*2+Y0*work.colour.stride_b;
count = dy;
while(count-- >= 0) {
/*
* plot pixel
*/
*(unsigned short *)ptr = ScalarsToRGB15(pr,pg,pb);
error += dx;
if (error>0) {
error -= dy;
ptr += dptr;
} else {
ptr += work.colour.stride_b;
}
/*
* Update parameters
*/
pr += dr;
pg += dg;
pb += db;
}
}
}
#endif
#if PARTS & PART_16
/*
* 16 bit textured lines
*/
void BR_ASM_CALL LineRenderPIT_RGB_565(struct brp_block *block, union brp_vertex *v0,union brp_vertex *v1)
{
br_fixed_ls dx,dy;
br_fixed_ls pm,dm,x0,x1,y0,y1;
br_fixed_ls pu,pv,du,dv;
int error;
int count,offset,base;
int X0,Y0,X1,Y1;
char *ptr;
int dptr;
int width,height,stride;
SETUP_TEXTURE;
SETUP_LINE;
error = 0;
if(ABS(dx) > ABS(dy)) {
/*
* Major axis is X axis - ensure dx is +ve
*/
if(dx < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = 2+(dy>0 ? work.colour.stride_b : -work.colour.stride_b);
dy = ABS(dy);
if (dx<0)
return;
pu = v0->comp_x[C_U] % BrIntToFixed(width);
if (pu<0)
pu += BrIntToFixed(width);
pv = v0->comp_x[C_V] % BrIntToFixed(height);
if (pv<0)
pv += BrIntToFixed(height);
if(dx > 0) {
du = BrFixedDiv((v1->comp_x[C_U] - v0->comp_x[C_U]),BrIntToFixed(dx));
dv = BrFixedDiv((v1->comp_x[C_V] - v0->comp_x[C_V]),BrIntToFixed(dx));
du = du % BrIntToFixed(width);
if (du>0)
du -= BrIntToFixed(width);
dv = dv % BrIntToFixed(height);
if (dv>0)
dv -= BrIntToFixed(height);
}
ptr = (char *)work.colour.base+2*X0+Y0*work.colour.stride_b;
count = dx;
while(count-- >= 0) {
/*
* plot pixel
*/
{
unsigned short texel;
texel = *(unsigned short *)((char *)work.texture.base+(pv>>16)*stride+2*(pu>>16));
if (texel)
*(short *)ptr = texel;
}
error += dy;
if (error>0) {
error -= dx;
ptr += dptr;
} else {
ptr += 2;
}
/*
* Update parameters
*/
pu += du;
if (pu<0)
pu += BrIntToFixed(width);
pv += dv;
if (pv<0)
pv += BrIntToFixed(height);
}
} else {
/*
* Major axis is Y axis - ensure dy is +ve
*/
if(dy < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = work.colour.stride_b+(dx>0 ? 2 : -2);
dx = ABS(dx);
if (dy<0)
return;
pu = v0->comp_x[C_U] % BrIntToFixed(width);
if (pu<0)
pu += BrIntToFixed(width);
pv = v0->comp_x[C_V] % BrIntToFixed(height);
if (pv<0)
pv += BrIntToFixed(height);
if(dy > 0) {
du = BrFixedDiv((v1->comp_x[C_U] - v0->comp_x[C_U]),BrIntToFixed(dy));
dv = BrFixedDiv((v1->comp_x[C_V] - v0->comp_x[C_V]),BrIntToFixed(dy));
du = du % BrIntToFixed(width);
if (du>0)
du -= BrIntToFixed(width);
dv = dv % BrIntToFixed(height);
if (dv>0)
dv -= BrIntToFixed(height);
}
ptr = (char *)work.colour.base+X0*2+Y0*work.colour.stride_b;
count = dy;
while(count-- >= 0) {
/*
* plot pixel
*/
{
unsigned short texel;
texel = *(unsigned short *)((char *)work.texture.base+(pv>>16)*stride+2*(pu>>16));
if (texel)
*(unsigned short *)ptr = texel;
}
error += dx;
if (error>0) {
error -= dy;
ptr += dptr;
} else {
ptr += work.colour.stride_b;
}
/*
* Update parameters
*/
pu += du;
if (pu<0)
pu += BrIntToFixed(width);
pv += dv;
if (pv<0)
pv += BrIntToFixed(height);
}
}
}
#endif
#if PARTS & PART_16
/*
* Gouraud shaded 16-bit lines
*/
void BR_ASM_CALL LineRenderPII_RGB_565(struct brp_block *block, union brp_vertex *v0,union brp_vertex *v1)
{
br_fixed_ls dx,dy;
br_fixed_ls pm,dm,x0,x1,y0,y1;
br_fixed_ls pr,pg,pb,dr,dg,db;
int error;
int count,offset,base;
int X0,Y0,X1,Y1;
char *ptr;
int dptr;
SETUP_LINE;
error = 0;
if(ABS(dx) > ABS(dy)) {
/*
* Major axis is X axis - ensure dx is +ve
*/
if(dx < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = 2+(dy>0 ? work.colour.stride_b : -work.colour.stride_b);
dy = ABS(dy);
if (dx<0)
return;
pr = v0->comp_x[C_R];
pg = v0->comp_x[C_G];
pb = v0->comp_x[C_B];
if(dx > 0) {
dr = BrFixedDiv((v1->comp_x[C_R] - v0->comp_x[C_R]),BrIntToFixed(dx));
dg = BrFixedDiv((v1->comp_x[C_G] - v0->comp_x[C_G]),BrIntToFixed(dx));
db = BrFixedDiv((v1->comp_x[C_B] - v0->comp_x[C_B]),BrIntToFixed(dx));
}
ptr = (char *)work.colour.base+2*X0+Y0*work.colour.stride_b;
count = dx;
while(count-- >= 0) {
/*
* plot pixel
*/
*(unsigned short *)ptr = ScalarsToRGB16(pr,pg,pb);
error += dy;
if (error>0) {
error -= dx;
ptr += dptr;
} else {
ptr += 2;
}
/*
* Update parameters
*/
pr += dr;
pg += dg;
pb += db;
}
} else {
/*
* Major axis is Y axis - ensure dy is +ve
*/
if(dy < 0) {
SWAP(union brp_vertex *,v0,v1);
SWAP(int,X0,X1);
SWAP(int,Y0,Y1);
dx = -dx;
dy = -dy;
}
dptr = work.colour.stride_b+(dx>0 ? 2 : -2);
dx = ABS(dx);
if (dy<0)
return;
pr = v0->comp_x[C_R];
pg = v0->comp_x[C_G];
pb = v0->comp_x[C_B];
if(dy > 0) {
dr = BrFixedDiv((v1->comp_x[C_R] - v0->comp_x[C_R]),BrIntToFixed(dy));
dg = BrFixedDiv((v1->comp_x[C_G] - v0->comp_x[C_G]),BrIntToFixed(dy));
db = BrFixedDiv((v1->comp_x[C_B] - v0->comp_x[C_B]),BrIntToFixed(dy));
}
ptr = (char *)work.colour.base+X0*2+Y0*work.colour.stride_b;
count = dy;
while(count-- >= 0) {
/*
* plot pixel
*/
*(unsigned short *)ptr = ScalarsToRGB16(pr,pg,pb);
error += dx;
if (error>0) {
error -= dy;
ptr += dptr;
} else {
ptr += work.colour.stride_b;
}
/*
* Update parameters
*/
pr += dr;
pg += dg;
pb += db;
}
}
}
#endif