1
1
Fork 0
mirror of https://github.com/QB64-Phoenix-Edition/QB64pe.git synced 2024-07-01 13:50:36 +00:00
QB64-PE/internal/c/mtri3.cpp
2022-05-06 13:20:30 -04:00

244 lines
6.3 KiB
C++

mtri3_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 mtri3_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 mtri3_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 + (y * dwidth + x2)) =
src_offset[(g2ty >> 16) * swidth + (g2tx >> 16)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
// move left one position
x2--;
if (x1 > x2 | x2 < 0)
goto mtri3_donerow; // no more to do
} else {
if (no_edge_overlap) {
x2 = x2 - 1;
if (x1 > x2 | x2 < 0)
goto mtri3_donerow; // no more to do
}
}
if (loff > 0) {
// draw lhs pixel as is
if (x1 >= 0) {
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(dst_offset + (y * dwidth + x1)) =
src_offset[(ty >> 16) * swidth + (tx >> 16)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
// skip to next x location, effectively reducing steps by 1
x1++;
if (x1 > x2)
goto mtri3_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 + (y * dwidth + x1);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// bottleneck
for (x = x1; x <= x2; x++) {
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*(pixel_offset++) = src_offset[(ty >> 16) * swidth + (tx >> 16)];
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
tx += txi;
ty += tyi;
}
mtri3_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;
mtri3_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 mtri3_usegrad3;
}
}
return;