Skip to content

Instantly share code, notes, and snippets.

@ultraviolet-jordan
Created February 6, 2024 23:14
Show Gist options
  • Save ultraviolet-jordan/631b11b5bc568ff26657070ef33be3d9 to your computer and use it in GitHub Desktop.
Save ultraviolet-jordan/631b11b5bc568ff26657070ef33be3d9 to your computer and use it in GitHub Desktop.
export function fillTexturedTriangle(
xA: i32,
xB: i32,
xC: i32,
yA: i32,
yB: i32,
yC: i32,
shadeA: i32,
shadeB: i32,
shadeC: i32,
originX: i32,
originY: i32,
originZ: i32,
txB: i32,
txC: i32,
tyB: i32,
tyC: i32,
tzB: i32,
tzC: i32,
texels: Int32Array,
lineOffset: Int32Array,
pixels: Int32Array,
bottom: i32,
centerX: i32,
centerY: i32,
width2d: i32,
clipX: bool,
boundX: i32,
lowMemory: bool,
opaque: bool,
reciprocal15: Int32Array
): Int32Array {
const verticalX: i32 = originX - txB;
const verticalY: i32 = originY - tyB;
const verticalZ: i32 = originZ - tzB;
const horizontalX: i32 = txC - originX;
const horizontalY: i32 = tyC - originY;
const horizontalZ: i32 = tzC - originZ;
let u: i32 = (horizontalX * originY - horizontalY * originX) << 14;
const uStride: i32 = (horizontalY * originZ - horizontalZ * originY) << 8;
const uStepVertical: i32 = (horizontalZ * originX - horizontalX * originZ) << 5;
let v: i32 = (verticalX * originY - verticalY * originX) << 14;
const vStride: i32 = (verticalY * originZ - verticalZ * originY) << 8;
const vStepVertical: i32 = (verticalZ * originX - verticalX * originZ) << 5;
let w: i32 = (verticalY * horizontalX - verticalX * horizontalY) << 14;
const wStride: i32 = (verticalZ * horizontalY - verticalY * horizontalZ) << 8;
const wStepVertical: i32 = (verticalX * horizontalZ - verticalZ * horizontalX) << 5;
let xStepAB: i32 = 0;
let shadeStepAB: i32 = 0;
if (yB !== yA) {
xStepAB = (((xB - xA) << 16) / (yB - yA)) | 0;
shadeStepAB = (((shadeB - shadeA) << 16) / (yB - yA)) | 0;
}
let xStepBC: i32 = 0;
let shadeStepBC: i32 = 0;
if (yC !== yB) {
xStepBC = (((xC - xB) << 16) / (yC - yB)) | 0;
shadeStepBC = (((shadeC - shadeB) << 16) / (yC - yB)) | 0;
}
let xStepAC: i32 = 0;
let shadeStepAC: i32 = 0;
if (yC !== yA) {
xStepAC = (((xA - xC) << 16) / (yA - yC)) | 0;
shadeStepAC = (((shadeA - shadeC) << 16) / (yA - yC)) | 0;
}
if (yA <= yB && yA <= yC) {
if (yA < bottom) {
if (yB > bottom) {
yB = bottom;
}
if (yC > bottom) {
yC = bottom;
}
if (yB < yC) {
xC = xA <<= 0x10;
shadeC = shadeA <<= 0x10;
if (yA < 0) {
xC -= xStepAC * yA;
xA -= xStepAB * yA;
shadeC -= shadeStepAC * yA;
shadeA -= shadeStepAB * yA;
yA = 0;
}
xB <<= 0x10;
shadeB <<= 0x10;
if (yB < 0) {
xB -= xStepBC * yB;
shadeB -= shadeStepBC * yB;
yB = 0;
}
const dy: i32 = yA - centerY;
u += uStepVertical * dy;
v += vStepVertical * dy;
w += wStepVertical * dy;
u |= 0;
v |= 0;
w |= 0;
if ((yA !== yB && xStepAC < xStepAB) || (yA === yB && xStepAC > xStepBC)) {
yC -= yB;
yB -= yA;
yA = lineOffset[yA];
// eslint-disable-next-line no-constant-condition
while (true) {
yB--;
if (yB < 0) {
// eslint-disable-next-line no-constant-condition
while (true) {
yC--;
if (yC < 0) {
return pixels;
}
drawTexturedScanline(xC >> 16, xB >> 16, pixels, yA, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeC >> 8, shadeB >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xC += xStepAC;
xB += xStepBC;
shadeC += shadeStepAC;
shadeB += shadeStepBC;
yA += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
drawTexturedScanline(xC >> 16, xA >> 16, pixels, yA, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeC >> 8, shadeA >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xC += xStepAC;
xA += xStepAB;
shadeC += shadeStepAC;
shadeA += shadeStepAB;
yA += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
} else {
yC -= yB;
yB -= yA;
yA = lineOffset[yA];
// eslint-disable-next-line no-constant-condition
while (true) {
yB--;
if (yB < 0) {
// eslint-disable-next-line no-constant-condition
while (true) {
yC--;
if (yC < 0) {
return pixels;
}
drawTexturedScanline(xB >> 16, xC >> 16, pixels, yA, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeB >> 8, shadeC >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xC += xStepAC;
xB += xStepBC;
shadeC += shadeStepAC;
shadeB += shadeStepBC;
yA += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
drawTexturedScanline(xA >> 16, xC >> 16, pixels, yA, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeA >> 8, shadeC >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xC += xStepAC;
xA += xStepAB;
shadeC += shadeStepAC;
shadeA += shadeStepAB;
yA += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
} else {
xB = xA <<= 0x10;
shadeB = shadeA <<= 0x10;
if (yA < 0) {
xB -= xStepAC * yA;
xA -= xStepAB * yA;
shadeB -= shadeStepAC * yA;
shadeA -= shadeStepAB * yA;
yA = 0;
}
xC <<= 0x10;
shadeC <<= 0x10;
if (yC < 0) {
xC -= xStepBC * yC;
shadeC -= shadeStepBC * yC;
yC = 0;
}
const dy: i32 = yA - centerY;
u += uStepVertical * dy;
v += vStepVertical * dy;
w += wStepVertical * dy;
u |= 0;
v |= 0;
w |= 0;
if ((yA === yC || xStepAC >= xStepAB) && (yA !== yC || xStepBC <= xStepAB)) {
yB -= yC;
yC -= yA;
yA = lineOffset[yA];
// eslint-disable-next-line no-constant-condition
while (true) {
yC--;
if (yC < 0) {
// eslint-disable-next-line no-constant-condition
while (true) {
yB--;
if (yB < 0) {
return pixels;
}
drawTexturedScanline(xA >> 16, xC >> 16, pixels, yA, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeA >> 8, shadeC >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xC += xStepBC;
xA += xStepAB;
shadeC += shadeStepBC;
shadeA += shadeStepAB;
yA += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
drawTexturedScanline(xA >> 16, xB >> 16, pixels, yA, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeA >> 8, shadeB >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xB += xStepAC;
xA += xStepAB;
shadeB += shadeStepAC;
shadeA += shadeStepAB;
yA += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
} else {
yB -= yC;
yC -= yA;
yA = lineOffset[yA];
// eslint-disable-next-line no-constant-condition
while (true) {
yC--;
if (yC < 0) {
// eslint-disable-next-line no-constant-condition
while (true) {
yB--;
if (yB < 0) {
return pixels;
}
drawTexturedScanline(xC >> 16, xA >> 16, pixels, yA, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeC >> 8, shadeA >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xC += xStepBC;
xA += xStepAB;
shadeC += shadeStepBC;
shadeA += shadeStepAB;
yA += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
drawTexturedScanline(xB >> 16, xA >> 16, pixels, yA, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeB >> 8, shadeA >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xB += xStepAC;
xA += xStepAB;
shadeB += shadeStepAC;
shadeA += shadeStepAB;
yA += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
}
}
} else if (yB <= yC) {
if (yB < bottom) {
if (yC > bottom) {
yC = bottom;
}
if (yA > bottom) {
yA = bottom;
}
if (yC < yA) {
xA = xB <<= 0x10;
shadeA = shadeB <<= 0x10;
if (yB < 0) {
xA -= xStepAB * yB;
xB -= xStepBC * yB;
shadeA -= shadeStepAB * yB;
shadeB -= shadeStepBC * yB;
yB = 0;
}
xC <<= 0x10;
shadeC <<= 0x10;
if (yC < 0) {
xC -= xStepAC * yC;
shadeC -= shadeStepAC * yC;
yC = 0;
}
const dy: i32 = yB - centerY;
u += uStepVertical * dy;
v += vStepVertical * dy;
w += wStepVertical * dy;
u |= 0;
v |= 0;
w |= 0;
if ((yB !== yC && xStepAB < xStepBC) || (yB === yC && xStepAB > xStepAC)) {
yA -= yC;
yC -= yB;
yB = lineOffset[yB];
// eslint-disable-next-line no-constant-condition
while (true) {
yC--;
if (yC < 0) {
// eslint-disable-next-line no-constant-condition
while (true) {
yA--;
if (yA < 0) {
return pixels;
}
drawTexturedScanline(xA >> 16, xC >> 16, pixels, yB, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeA >> 8, shadeC >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xA += xStepAB;
xC += xStepAC;
shadeA += shadeStepAB;
shadeC += shadeStepAC;
yB += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
drawTexturedScanline(xA >> 16, xB >> 16, pixels, yB, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeA >> 8, shadeB >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xA += xStepAB;
xB += xStepBC;
shadeA += shadeStepAB;
shadeB += shadeStepBC;
yB += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
} else {
yA -= yC;
yC -= yB;
yB = lineOffset[yB];
// eslint-disable-next-line no-constant-condition
while (true) {
yC--;
if (yC < 0) {
// eslint-disable-next-line no-constant-condition
while (true) {
yA--;
if (yA < 0) {
return pixels;
}
drawTexturedScanline(xC >> 16, xA >> 16, pixels, yB, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeC >> 8, shadeA >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xA += xStepAB;
xC += xStepAC;
shadeA += shadeStepAB;
shadeC += shadeStepAC;
yB += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
drawTexturedScanline(xB >> 16, xA >> 16, pixels, yB, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeB >> 8, shadeA >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xA += xStepAB;
xB += xStepBC;
shadeA += shadeStepAB;
shadeB += shadeStepBC;
yB += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
} else {
xC = xB <<= 0x10;
shadeC = shadeB <<= 0x10;
if (yB < 0) {
xC -= xStepAB * yB;
xB -= xStepBC * yB;
shadeC -= shadeStepAB * yB;
shadeB -= shadeStepBC * yB;
yB = 0;
}
xA <<= 0x10;
shadeA <<= 0x10;
if (yA < 0) {
xA -= xStepAC * yA;
shadeA -= shadeStepAC * yA;
yA = 0;
}
const dy: i32 = yB - centerY;
u += uStepVertical * dy;
v += vStepVertical * dy;
w += wStepVertical * dy;
u |= 0;
v |= 0;
w |= 0;
yC -= yA;
yA -= yB;
yB = lineOffset[yB];
if (xStepAB < xStepBC) {
// eslint-disable-next-line no-constant-condition
while (true) {
yA--;
if (yA < 0) {
// eslint-disable-next-line no-constant-condition
while (true) {
yC--;
if (yC < 0) {
return pixels;
}
drawTexturedScanline(xA >> 16, xB >> 16, pixels, yB, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeA >> 8, shadeB >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xA += xStepAC;
xB += xStepBC;
shadeA += shadeStepAC;
shadeB += shadeStepBC;
yB += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
drawTexturedScanline(xC >> 16, xB >> 16, pixels, yB, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeC >> 8, shadeB >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xC += xStepAB;
xB += xStepBC;
shadeC += shadeStepAB;
shadeB += shadeStepBC;
yB += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
} else {
// eslint-disable-next-line no-constant-condition
while (true) {
yA--;
if (yA < 0) {
// eslint-disable-next-line no-constant-condition
while (true) {
yC--;
if (yC < 0) {
return pixels;
}
drawTexturedScanline(xB >> 16, xA >> 16, pixels, yB, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeB >> 8, shadeA >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xA += xStepAC;
xB += xStepBC;
shadeA += shadeStepAC;
shadeB += shadeStepBC;
yB += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
drawTexturedScanline(xB >> 16, xC >> 16, pixels, yB, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeB >> 8, shadeC >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xC += xStepAB;
xB += xStepBC;
shadeC += shadeStepAB;
shadeB += shadeStepBC;
yB += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
}
}
} else if (yC < bottom) {
if (yA > bottom) {
yA = bottom;
}
if (yB > bottom) {
yB = bottom;
}
if (yA < yB) {
xB = xC <<= 0x10;
shadeB = shadeC <<= 0x10;
if (yC < 0) {
xB -= xStepBC * yC;
xC -= xStepAC * yC;
shadeB -= shadeStepBC * yC;
shadeC -= shadeStepAC * yC;
yC = 0;
}
xA <<= 0x10;
shadeA <<= 0x10;
if (yA < 0) {
xA -= xStepAB * yA;
shadeA -= shadeStepAB * yA;
yA = 0;
}
const dy: i32 = yC - centerY;
u += uStepVertical * dy;
v += vStepVertical * dy;
w += wStepVertical * dy;
u |= 0;
v |= 0;
w |= 0;
yB -= yA;
yA -= yC;
yC = lineOffset[yC];
if (xStepBC < xStepAC) {
// eslint-disable-next-line no-constant-condition
while (true) {
yA--;
if (yA < 0) {
// eslint-disable-next-line no-constant-condition
while (true) {
yB--;
if (yB < 0) {
return pixels;
}
drawTexturedScanline(xB >> 16, xA >> 16, pixels, yC, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeB >> 8, shadeA >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xB += xStepBC;
xA += xStepAB;
shadeB += shadeStepBC;
shadeA += shadeStepAB;
yC += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
drawTexturedScanline(xB >> 16, xC >> 16, pixels, yC, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeB >> 8, shadeC >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xB += xStepBC;
xC += xStepAC;
shadeB += shadeStepBC;
shadeC += shadeStepAC;
yC += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
} else {
// eslint-disable-next-line no-constant-condition
while (true) {
yA--;
if (yA < 0) {
// eslint-disable-next-line no-constant-condition
while (true) {
yB--;
if (yB < 0) {
return pixels;
}
drawTexturedScanline(xA >> 16, xB >> 16, pixels, yC, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeA >> 8, shadeB >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xB += xStepBC;
xA += xStepAB;
shadeB += shadeStepBC;
shadeA += shadeStepAB;
yC += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
drawTexturedScanline(xC >> 16, xB >> 16, pixels, yC, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeC >> 8, shadeB >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xB += xStepBC;
xC += xStepAC;
shadeB += shadeStepBC;
shadeC += shadeStepAC;
yC += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
} else {
xA = xC <<= 0x10;
shadeA = shadeC <<= 0x10;
if (yC < 0) {
xA -= xStepBC * yC;
xC -= xStepAC * yC;
shadeA -= shadeStepBC * yC;
shadeC -= shadeStepAC * yC;
yC = 0;
}
xB <<= 0x10;
shadeB <<= 0x10;
if (yB < 0) {
xB -= xStepAB * yB;
shadeB -= shadeStepAB * yB;
yB = 0;
}
const dy: i32 = yC - centerY;
u += uStepVertical * dy;
v += vStepVertical * dy;
w += wStepVertical * dy;
u |= 0;
v |= 0;
w |= 0;
yA -= yB;
yB -= yC;
yC = lineOffset[yC];
if (xStepBC < xStepAC) {
// eslint-disable-next-line no-constant-condition
while (true) {
yB--;
if (yB < 0) {
// eslint-disable-next-line no-constant-condition
while (true) {
yA--;
if (yA < 0) {
return pixels;
}
drawTexturedScanline(xB >> 16, xC >> 16, pixels, yC, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeB >> 8, shadeC >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xB += xStepAB;
xC += xStepAC;
shadeB += shadeStepAB;
shadeC += shadeStepAC;
yC += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
drawTexturedScanline(xA >> 16, xC >> 16, pixels, yC, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeA >> 8, shadeC >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xA += xStepBC;
xC += xStepAC;
shadeA += shadeStepBC;
shadeC += shadeStepAC;
yC += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
} else {
// eslint-disable-next-line no-constant-condition
while (true) {
yB--;
if (yB < 0) {
// eslint-disable-next-line no-constant-condition
while (true) {
yA--;
if (yA < 0) {
return pixels;
}
drawTexturedScanline(xC >> 16, xB >> 16, pixels, yC, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeC >> 8, shadeB >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xB += xStepAB;
xC += xStepAC;
shadeB += shadeStepAB;
shadeC += shadeStepAC;
yC += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
drawTexturedScanline(xC >> 16, xA >> 16, pixels, yC, texels, 0, 0, u, v, w, uStride, vStride, wStride, shadeC >> 8, shadeA >> 8, clipX, boundX, centerX, lowMemory, opaque, reciprocal15);
xA += xStepBC;
xC += xStepAC;
shadeA += shadeStepBC;
shadeC += shadeStepAC;
yC += width2d;
u += uStepVertical;
v += vStepVertical;
w += wStepVertical;
u |= 0;
v |= 0;
w |= 0;
}
}
}
}
return pixels;
}
function drawTexturedScanline(
xA: i32,
xB: i32,
dst: Int32Array,
offset: i32,
texels: Int32Array,
curU: i32,
curV: i32,
u: i32,
v: i32,
w: i32,
uStride: i32,
vStride: i32,
wStride: i32,
shadeA: i32,
shadeB: i32,
clipX: bool,
boundX: i32,
centerX: i32,
lowMemory: bool,
opaque: bool,
reciprocal15: Int32Array
): void {
if (xA >= xB) {
return;
}
let shadeStrides: i32;
let strides: i32;
if (clipX) {
shadeStrides = ((shadeB - shadeA) / (xB - xA)) | 0;
if (xB > boundX) {
xB = boundX;
}
if (xA < 0) {
shadeA -= xA * shadeStrides;
xA = 0;
}
if (xA >= xB) {
return;
}
strides = (xB - xA) >> 3;
shadeStrides <<= 0xc;
} else {
if (xB - xA > 7) {
strides = (xB - xA) >> 3;
shadeStrides = ((shadeB - shadeA) * reciprocal15[strides]) >> 6;
} else {
strides = 0;
shadeStrides = 0;
}
}
shadeA <<= 0x9;
offset += xA;
let nextU: i32;
let nextV: i32;
let curW: i32;
let dx: i32;
let stepU: i32;
let stepV: i32;
let shadeShift: i32;
if (lowMemory) {
nextU = 0;
nextV = 0;
dx = xA - centerX;
u = u + (uStride >> 3) * dx;
v = v + (vStride >> 3) * dx;
w = w + (wStride >> 3) * dx;
u |= 0;
v |= 0;
w |= 0;
curW = w >> 12;
if (curW !== 0) {
curU = (u / curW) | 0;
curV = (v / curW) | 0;
if (curU < 0) {
curU = 0;
} else if (curU > 4032) {
curU = 4032;
}
}
u = u + uStride;
v = v + vStride;
w = w + wStride;
u |= 0;
v |= 0;
w |= 0;
curW = w >> 12;
if (curW !== 0) {
nextU = (u / curW) | 0;
nextV = (v / curW) | 0;
if (nextU < 7) {
nextU = 7;
} else if (nextU > 4032) {
nextU = 4032;
}
}
stepU = (nextU - curU) >> 3;
stepV = (nextV - curV) >> 3;
curU += (shadeA >> 3) & 0xc0000;
shadeShift = shadeA >> 23;
if (opaque) {
while (strides-- > 0) {
dst[offset++] = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift;
curU += stepU;
curV += stepV;
dst[offset++] = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift;
curU += stepU;
curV += stepV;
dst[offset++] = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift;
curU += stepU;
curV += stepV;
dst[offset++] = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift;
curU += stepU;
curV += stepV;
dst[offset++] = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift;
curU += stepU;
curV += stepV;
dst[offset++] = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift;
curU += stepU;
curV += stepV;
dst[offset++] = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift;
curU += stepU;
curV += stepV;
dst[offset++] = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift;
curU = nextU;
curV = nextV;
u += uStride;
v += vStride;
w += wStride;
curW = w >> 12;
if (curW !== 0) {
nextU = (u / curW) | 0;
nextV = (v / curW) | 0;
if (nextU < 7) {
nextU = 7;
} else if (nextU > 4032) {
nextU = 4032;
}
}
stepU = (nextU - curU) >> 3;
stepV = (nextV - curV) >> 3;
shadeA += shadeStrides;
curU += (shadeA >> 3) & 0xc0000;
shadeShift = shadeA >> 23;
}
strides = (xB - xA) & 0x7;
while (strides-- > 0) {
dst[offset++] = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift;
curU += stepU;
curV += stepV;
}
} else {
while (strides-- > 0) {
let rgb: i32;
if ((rgb = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset = offset + 1;
curU += stepU;
curV += stepV;
if ((rgb = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset++;
curU += stepU;
curV += stepV;
if ((rgb = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset++;
curU += stepU;
curV += stepV;
if ((rgb = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset++;
curU += stepU;
curV += stepV;
if ((rgb = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset++;
curU += stepU;
curV += stepV;
if ((rgb = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset++;
curU += stepU;
curV += stepV;
if ((rgb = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset++;
curU += stepU;
curV += stepV;
if ((rgb = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset = offset + 1;
curU = nextU;
curV = nextV;
u += uStride;
v += vStride;
w += wStride;
u |= 0;
v |= 0;
w |= 0;
curW = w >> 12;
if (curW !== 0) {
nextU = (u / curW) | 0;
nextV = (v / curW) | 0;
if (nextU < 7) {
nextU = 7;
} else if (nextU > 4032) {
nextU = 4032;
}
}
stepU = (nextU - curU) >> 3;
stepV = (nextV - curV) >> 3;
shadeA += shadeStrides;
curU += (shadeA >> 3) & 0xc0000;
shadeShift = shadeA >> 23;
}
strides = (xB - xA) & 0x7;
while (strides-- > 0) {
let rgb: i32;
if ((rgb = texels[(curV & 0xfc0) + (curU >> 6)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset++;
curU += stepU;
curV += stepV;
}
}
return;
}
nextU = 0;
nextV = 0;
dx = xA - centerX;
u = u + (uStride >> 3) * dx;
v = v + (vStride >> 3) * dx;
w = w + (wStride >> 3) * dx;
u |= 0;
v |= 0;
w |= 0;
curW = w >> 14;
if (curW !== 0) {
curU = (u / curW) | 0;
curV = (v / curW) | 0;
if (curU < 0) {
curU = 0;
} else if (curU > 16256) {
curU = 16256;
}
}
u = u + uStride;
v = v + vStride;
w = w + wStride;
u |= 0;
v |= 0;
w |= 0;
curW = w >> 14;
if (curW !== 0) {
nextU = (u / curW) | 0;
nextV = (v / curW) | 0;
if (nextU < 7) {
nextU = 7;
} else if (nextU > 16256) {
nextU = 16256;
}
}
stepU = (nextU - curU) >> 3;
stepV = (nextV - curV) >> 3;
curU += shadeA & 0x600000;
shadeShift = shadeA >> 23;
if (opaque) {
while (strides-- > 0) {
dst[offset++] = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift;
curU += stepU;
curV += stepV;
dst[offset++] = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift;
curU += stepU;
curV += stepV;
dst[offset++] = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift;
curU += stepU;
curV += stepV;
dst[offset++] = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift;
curU += stepU;
curV += stepV;
dst[offset++] = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift;
curU += stepU;
curV += stepV;
dst[offset++] = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift;
curU += stepU;
curV += stepV;
dst[offset++] = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift;
curU += stepU;
curV += stepV;
dst[offset++] = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift;
curU = nextU;
curV = nextV;
u += uStride;
v += vStride;
w += wStride;
u |= 0;
v |= 0;
w |= 0;
curW = w >> 14;
if (curW !== 0) {
nextU = (u / curW) | 0;
nextV = (v / curW) | 0;
if (nextU < 7) {
nextU = 7;
} else if (nextU > 16256) {
nextU = 16256;
}
}
stepU = (nextU - curU) >> 3;
stepV = (nextV - curV) >> 3;
shadeA += shadeStrides;
curU += shadeA & 0x600000;
shadeShift = shadeA >> 23;
}
strides = (xB - xA) & 0x7;
while (strides-- > 0) {
dst[offset++] = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift;
curU += stepU;
curV += stepV;
}
return;
}
while (strides-- > 0) {
let rgb: i32;
if ((rgb = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset = offset + 1;
curU += stepU;
curV += stepV;
if ((rgb = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset++;
curU += stepU;
curV += stepV;
if ((rgb = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset++;
curU += stepU;
curV += stepV;
if ((rgb = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset++;
curU += stepU;
curV += stepV;
if ((rgb = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset++;
curU += stepU;
curV += stepV;
if ((rgb = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset++;
curU += stepU;
curV += stepV;
if ((rgb = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset++;
curU += stepU;
curV += stepV;
if ((rgb = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset++;
curU = nextU;
curV = nextV;
u += uStride;
v += vStride;
w += wStride;
u |= 0;
v |= 0;
w |= 0;
curW = w >> 14;
if (curW !== 0) {
nextU = (u / curW) | 0;
nextV = (v / curW) | 0;
if (nextU < 7) {
nextU = 7;
} else if (nextU > 16256) {
nextU = 16256;
}
}
stepU = (nextU - curU) >> 3;
stepV = (nextV - curV) >> 3;
shadeA += shadeStrides;
curU += shadeA & 0x600000;
shadeShift = shadeA >> 23;
}
strides = (xB - xA) & 0x7;
while (strides-- > 0) {
let rgb: i32;
if ((rgb = texels[(curV & 0x3f80) + (curU >> 7)] >>> shadeShift) !== 0) {
dst[offset] = rgb;
}
offset++;
curU += stepU;
curV += stepV;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment