1
1
Fork 0
mirror of https://github.com/QB64Official/qb64.git synced 2024-09-16 05:03:52 +00:00
qb64/internal/c/mtri3s.cpp
SMcNeill 6e01fc8dce Altered string compare routines (<,<=,>,>=) so they don't give false results with CHR$(0).
Added new _STRCMP and _STRICMP commands for quick string comparisons.
Cleaned up QB64 to finish removing the QUI (quick user insert) code and folders.
Altered UCASE and LCASE routines to be faster in some situations for us.
2014-09-22 08:19:03 -04:00

200 lines
5.7 KiB
C++

mtri3s_usegrad3:;
if(final == 1){
if(no_edge_overlap) y2 = y2 - 1;
}
//not on screen?
if(y1 >= dheight){
return;
}
if(y2 < 0){
if(final) return;
//jump to y2's position
//note; original point locations are referenced because they are unmodified & represent the true distance of the run
y = y2 - y1;
p1 = g1->p1; p2 = g1->p2;
d = g1->y2 - g1->y1;
if(d){
i64 = p2->tx - p1->tx;
g1->tx += i64 * y / d;
i64 = p2->ty - p1->ty;
g1->ty += i64 * y / d;
i64 = p2->x - p1->x;
g1->x += i64 * y / d;
p1 = g2->p1; p2 = g2->p2;
}
d = g2->y2 - g2->y1;
if(d){
i64 = p2->tx - p1->tx;
g2->tx += i64 * y / d;
i64 = p2->ty - p1->ty;
g2->ty += i64 * y / d;
i64 = p2->x - p1->x;
g2->x += i64 * y / d;
}
goto mtri3s_final;
}
//clip top
if(y1 < 0){
//note; original point locations are referenced because they are unmodified & represent the true distance of the run
y = -y1;
p1 = g1->p1; p2 = g1->p2;
d = g1->y2 - g1->y1;
if(d){
i64 = p2->tx - p1->tx;
g1->tx += i64 * y / d;
i64 = p2->ty - p1->ty;
g1->ty += i64 * y / d;
i64 = p2->x - p1->x;
g1->x += i64 * y / d;
p1 = g2->p1; p2 = g2->p2;
}
d = g2->y2 - g2->y1;
if(d){
i64 = p2->tx - p1->tx;
g2->tx += i64 * y / d;
i64 = p2->ty - p1->ty;
g2->ty += i64 * y / d;
i64 = p2->x - p1->x;
g2->x += i64 * y / d;
}
y1 = 0;
}
if(y2 >= dheight){ //clip bottom
y2 = dheight - 1;
}
//move indexed variable values into direct variables for faster referencing within 2nd bottleneck
g1x = g1->x; g2x = g2->x;
g1tx = g1->tx; g2tx = g2->tx;
g1ty = g1->ty; g2ty = g2->ty;
g1xi = g1->xi; g2xi = g2->xi;
g1txi = g1->txi; g2txi = g2->txi;
g1tyi = g1->tyi; g2tyi = g2->tyi;
//2nd bottleneck
for(y=y1;y<=y2;y++){
if(g1x < 0) x1 = (g1x - 65535) / 65536;else x1 = g1x / 65536; //int-style rounding of fixed-point value
if(g2x < 0) x2 = (g2x - 65535) / 65536;else x2 = g2x / 65536;
if(x1 >= dwidth | x2 < 0) goto mtri3s_donerow; //crop if(entirely offscreen
tx = g1tx; ty = g1ty;
//calculate gradients if they might be required
if(x1 != x2){
d = g2x - g1x;
i64 = g2tx - g1tx; txi = (i64 << 16) / d;
i64 = g2ty - g1ty; tyi = (i64 << 16) / d;
}else{
txi = 0; tyi = 0;
}
//calculate pixel offsets from ideals
loff = ((g1x & 65535) - 32768); //note; works for positive & negative values
roff = ((g2x & 65535) - 32768);
if(roff < 0){ //not enough of rhs pixel exists to use
if(x2 < dwidth & no_edge_overlap == 0){ //onscreen check
//draw rhs pixel as is
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset+(x2*dheight+y))=src_offset[(g2ty>>16)*swidth+(g2tx>>16)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
//move left one position
x2--;
if(x1 > x2 | x2 < 0) goto mtri3s_donerow; //no more to do
}else{
if(no_edge_overlap){
x2 = x2 - 1;
if(x1 > x2 | x2 < 0) goto mtri3s_donerow; //no more to do
}
}
if(loff > 0){
//draw lhs pixel as is
if(x1 >= 0){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset+(x1*dheight+y))=src_offset[(ty>>16)*swidth+(tx>>16)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
//skip to next x location, effectively reducing steps by 1
x1++;
if(x1 > x2) goto mtri3s_donerow;
loff = -(65536 - loff); //adjust alignment to jump to next ideal offset
}
//align to loff
i64 = -loff;
tx += (i64 * txi) / 65536;
ty += (i64 * tyi) / 65536;
if(x1 < 0){ //clip left
d = g2x - g1x;
i64 = g2tx - g1tx;
tx += ((i64 << 16) * -x1) / d;
i64 = g2ty - g1ty;
ty += ((i64 << 16) * -x1) / d;
if(x1 < 0) x1 = 0;
}
if(x2 >= dwidth){
x2 = dwidth - 1; //clip right
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
pixel_offset=dst_offset+(x1*dheight+y);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//bottleneck
for(x=x1;x<=x2;x++){
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*pixel_offset=src_offset[(ty>>16)*swidth+(tx>>16)];
pixel_offset+=dheight;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi;
ty += tyi;
}
mtri3s_donerow:;
if(y != y2){
g1x += g1xi; g1tx += g1txi; g1ty += g1tyi;
g2x += g2xi; g2tx += g2txi; g2ty += g2tyi;
}
}
if(final == 0){
//update indexed variable values with direct variable values which have changed & may be required
g1->x = g1x; g2->x = g2x;
g1->tx = g1tx; g2->tx = g2tx;
g1->ty = g1ty; g2->ty = g2ty;
mtri3s_final:;
if(y2 < dheight - 1){ //no point continuing if(offscreen!
if(g1->y2 < g2->y2) g1 = g3;else g2 = g3;
//avoid doing the same row twice
y1 = g3->y1 + 1;
y2 = g3->y2;
g1->x += g1->xi; g1->tx += g1->txi; g1->ty += g1->tyi;
g2->x += g2->xi; g2->tx += g2->txi; g2->ty += g2->tyi;
final = 1;
goto mtri3s_usegrad3;
}
}
return;