Pack animation sheets as tall strips

ClassicAPI's texture dimension gate lifts the two limits the sheet layout was
built around. A sheet skinnier than 16:1 drawing nothing was never a client
rule -- VanillaHelpers grew the texture recycle pool to 6x6 but left the index
stride at 5, so a 32x1024 strip collided with a 64x32 bucket and was handed
back the wrong texture. And power-of-two is no longer required, since the gate
grows the decode scratch to fit.

So a run wraps into columns only when it outgrows the scratch at 32 frames, and
a sheet is sized to its frames exactly: 20 frames is a 32x640 strip rather than
64x1024. The 128 frame budget is unchanged, and older sheets still play -- the
animator reads the column count off the sheet.
This commit is contained in:
Brues
2026-09-14 13:58:06 -05:00
parent a9297cc58b
commit ce8038ed03
2 changed files with 27 additions and 30 deletions
+5 -5
View File
@@ -21,11 +21,11 @@ local function GetCurrentFrameNum(animdata)
return math.floor((TWITCHEMOTES_T * animdata.framerate) % animdata.nFrames)
end
-- Frames run row-major across however many columns the sheet is wide. Two
-- client limits force that: no texture side may exceed 1024, and a texture
-- skinnier than 16:1 doesn't draw at all -- a 32x1024 strip renders nothing,
-- while the same frames as 64x512 render fine. So a run longer than 16 frames
-- is packed in columns rather than as one tall strip.
-- Frames run row-major across however many columns the sheet is wide, since a
-- run longer than 32 frames outgrows the 1024px decode scratch as one strip.
-- Older sheets are packed more densely than that: before ClassicAPI's texture
-- dimension gate a sheet skinnier than 16:1 drew nothing, so runs wrapped at 16
-- frames. Deriving the column count from the sheet handles either.
local function GetFrameRect(animdata, framenum)
local cols = math.floor(animdata.imageWidth / animdata.frameWidth)
if cols < 1 then cols = 1 end