@@ -5,6 +5,7 @@ package pi
55
66import (
77 "fmt"
8+ "github.com/elgopher/pi/pimath"
89)
910
1011// DrawSprite draws the given sprite at (dx, dy) on the current draw target.
@@ -72,31 +73,45 @@ func Stretch(sprite Sprite, dx, dy, dw, dh int) {
7273 targetStride := drawTarget .width - int (dst .W )
7374 srcSource := sprite .Source
7475
75- if sprite .FlipY {
76- src .Y += float64 (dh - 1 ) * stepY
77- stepY *= - 1
78- }
76+ stepXAbs := src .W / dst .W
77+ stepYAbs := src .H / dst .H
7978
79+ // start sampling from half-step offsets
8080 if sprite .FlipX {
81- src .X += float64 (dw - 1 ) * stepX
82- stepX *= - 1
81+ src .X += src .W - stepXAbs / 2
82+ stepXAbs = - stepXAbs
83+ } else {
84+ src .X += stepXAbs / 2
8385 }
8486
85- srcX , srcY := src .X , src .Y
87+ if sprite .FlipY {
88+ src .Y += src .H - stepYAbs / 2
89+ stepYAbs = - stepYAbs
90+ } else {
91+ src .Y += stepYAbs / 2
92+ }
93+
94+ srcY := src .Y
95+
96+ srcMaxX := int (src .X + src .W )
97+ srcMaxY := int (src .Y + src .H )
8698
8799 for line := 0.0 ; line < dst .H ; line ++ {
88- srcLineIdx := int (srcY ) * srcSource .width // multiplication, but only once per line, so it's not a performance problem
100+ syIndex := pimath .Clamp (int (srcY ), 0 , srcMaxY - 1 )
101+ srcLineIdx := syIndex * srcSource .width
102+
103+ srcX := src .X
104+ for cell := 0 ; cell < int (dst .W ); cell ++ {
105+ sxIndex := pimath .Clamp (int (srcX ), 0 , srcMaxX - 1 )
89106
90- for cell := 0.0 ; cell < dst .W ; cell ++ {
91- sourceColor := srcSource .data [srcLineIdx + int (srcX )] & ReadMask
107+ sourceColor := srcSource .data [srcLineIdx + sxIndex ] & ReadMask
92108 targetColor := drawTarget .data [targetIdx ] & TargetMask
93109 drawTarget .data [targetIdx ] =
94110 ColorTables [(sourceColor | targetColor )>> 6 ][sourceColor & (MaxColors - 1 )][targetColor & (MaxColors - 1 )]
95- srcX += stepX
111+ srcX += stepXAbs
96112 targetIdx ++
97113 }
98- srcX = src .X
99- srcY += stepY
114+ srcY += stepYAbs
100115 targetIdx += targetStride
101116 }
102117}
0 commit comments