fix off-by-one in trapezoid bresenham calculation

This commit is contained in:
Jeremy Penner 2023-12-24 16:21:01 -05:00
parent 5fe4e7a96d
commit 7148e21cce

View file

@ -228,12 +228,17 @@ celDecoder.trap = (data, cel) => {
// cycle2: same thing, but for x2a (right edge) // cycle2: same thing, but for x2a (right edge)
// at the end, increments y1 and jumps back to the top of draw_line // at the end, increments y1 and jumps back to the top of draw_line
cel.width = Math.floor((Math.max(cel.x1a, cel.x1b, cel.x2a, cel.x2b) + 3) / 4) cel.width = Math.floor((Math.max(cel.x1a, cel.x1b, cel.x2a, cel.x2b) + 3) / 4)
const height = cel.height // trap.m:32 - delta_y and vcount are calculated by subtracting y2 - y1.
cel.bitmap = emptyBitmap(cel.width, height) // mix.m:253: y2 is calculated as cel_y + cel_height
// mix.m:261: y1 is calculated as cel_y + 1
// So for a one-pixel tall trapezoid, deltay is 0, because y1 == y2.
// vcount is decremented until it reaches -1, compensating for the off-by-one.
const deltay = cel.height - 1
cel.bitmap = emptyBitmap(cel.width, cel.height)
const dxa = Math.abs(cel.x1a - cel.x2a) const dxa = Math.abs(cel.x1a - cel.x2a)
const dxb = Math.abs(cel.x1b - cel.x2b) const dxb = Math.abs(cel.x1b - cel.x2b)
const countMaxA = Math.max(dxa, height) const countMaxA = Math.max(dxa, deltay)
const countMaxB = Math.max(dxb, height) const countMaxB = Math.max(dxb, deltay)
const inca = cel.x1a < cel.x2a ? 1 : -1 const inca = cel.x1a < cel.x2a ? 1 : -1
const incb = cel.x1b < cel.x2b ? 1 : -1 const incb = cel.x1b < cel.x2b ? 1 : -1
let x1aLo = Math.floor(countMaxA / 2) let x1aLo = Math.floor(countMaxA / 2)
@ -242,9 +247,9 @@ celDecoder.trap = (data, cel) => {
let y1bLo = x1bLo let y1bLo = x1bLo
let xa = cel.x1a let xa = cel.x1a
let xb = cel.x1b let xb = cel.x1b
for (let y = 0; y < height; y ++) { for (let y = 0; y < cel.height; y ++) {
let patternByte = cel.pattern let patternByte = cel.pattern
if (border && (y == 0 || y == (height - 1))) { if (border && (y == 0 || y == (cel.height - 1))) {
// top and bottom border line // top and bottom border line
patternByte = 0xaa patternByte = 0xaa
} }
@ -270,7 +275,7 @@ celDecoder.trap = (data, cel) => {
x1aLo -= countMaxA x1aLo -= countMaxA
xa += inca xa += inca
} }
y1aLo += height y1aLo += deltay
} while (y1aLo < countMaxA) } while (y1aLo < countMaxA)
y1aLo -= countMaxA y1aLo -= countMaxA
@ -281,7 +286,7 @@ celDecoder.trap = (data, cel) => {
x1bLo -= countMaxB x1bLo -= countMaxB
xb += incb xb += incb
} }
y1bLo += height y1bLo += deltay
} while (y1bLo < countMaxA) } while (y1bLo < countMaxA)
y1bLo -= countMaxA y1bLo -= countMaxA
} }