Created
February 6, 2024 23:14
-
-
Save ultraviolet-jordan/631b11b5bc568ff26657070ef33be3d9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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