From 837f5529871100699cbd4439406f27f5e8ff40e2 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Tue, 7 Oct 2025 16:20:24 -0400 Subject: [PATCH] Fix bank increment never happening due to unsigned overflow --- src/gfx/process.cpp | 17 ++++++++++------- test/gfx/unoptimized-full.2bpp | Bin 0 -> 8192 bytes test/gfx/unoptimized-full.attrmap | Bin 0 -> 512 bytes test/gfx/unoptimized-full.flags | 1 + test/gfx/unoptimized-full.pal | Bin 0 -> 8 bytes test/gfx/unoptimized-full.png | Bin 0 -> 3762 bytes test/gfx/unoptimized-full.tilemap | Bin 0 -> 512 bytes 7 files changed, 11 insertions(+), 7 deletions(-) create mode 100644 test/gfx/unoptimized-full.2bpp create mode 100644 test/gfx/unoptimized-full.attrmap create mode 100644 test/gfx/unoptimized-full.flags create mode 100644 test/gfx/unoptimized-full.pal create mode 100644 test/gfx/unoptimized-full.png create mode 100644 test/gfx/unoptimized-full.tilemap diff --git a/src/gfx/process.cpp b/src/gfx/process.cpp index 29b94565..17b7c66f 100644 --- a/src/gfx/process.cpp +++ b/src/gfx/process.cpp @@ -695,12 +695,6 @@ static void outputUnoptimizedMaps( uint8_t tileID = 0; uint8_t bank = 0; for (AttrmapEntry const &attr : attrmap) { - if (tileID == options.maxNbTiles[bank]) { - assume(bank == 0); - bank = 1; - tileID = 0; - } - if (tilemapOutput.has_value()) { (*tilemapOutput) ->sputc((attr.isBackgroundTile() ? 0 : tileID) + options.baseTileIDs[bank]); @@ -714,8 +708,17 @@ static void outputUnoptimizedMaps( } // Background tiles are skipped in the tile data, so they should be skipped in the maps too. - if (!attr.isBackgroundTile()) { + if (attr.isBackgroundTile()) { + continue; + } + + // Compare with `maxNbTiles` *before* incrementing, due to unsigned overflow! + if (tileID + 1 < options.maxNbTiles[bank]) { ++tileID; + } else { + assume(bank == 0); + bank = 1; + tileID = 0; } } } diff --git a/test/gfx/unoptimized-full.2bpp b/test/gfx/unoptimized-full.2bpp new file mode 100644 index 0000000000000000000000000000000000000000..8e1d54fe07f56dedf7723adcd666995034a417b0 GIT binary patch literal 8192 zcmY+IO==@i5`_CK#tR`D9m05Fgwdgd7eX{XgwUcWj1JLw(HNsc7%hYly26Y<$HYWb zH4PPtm-#X)^ZkTxxAEt>-G2T0&-cIUb^r4i-)_6z;V=wSyxSRHF5`GO>~>#YvcKJi z0c>7)9D{d1PsU^4y!?6m=|p&k!{y@m#_{cK9Isbl_+c2w(G$v0ScJ4-d}gczk*Sn-^X#gCBmLjK{ut`SbYq zcfwn(od4(Na{2tcTslAar>Eu8`NQ*=*Zdtn@jX2`|J!Xozg)Ik&v(7v-=9t|FUGgq z-QDfB*-Y_zZG5@R=eOH>?R;*x*$ix6IR5eX_0{9CZ(jave>xH0>#Os>Ugz`cb-Q(b z@aOY(>-^!#$Gqn6_=#_`ndZ-&?jQ2Mzc*I?*oYVAn+Pj^ax%}@@R~pVm4A$#;i5sy}OgW z_KNVr@vpt2$7A2T{MrA0Pkf8TeD3&I+w=MF-@@?c^L&1PAD(>7YyOU(ynf5ukzpT-QQZvy?>H__IKsq`#=7}YySAxUeV*pw|Q{vm4EO5rXBE`+-v**>*h{8(y~Y5BK%eR+Z(EYCbd;cevUO(WhPvzh18UNumcl;~= z9#6i_gJZA!d;ODpuYc`-S^vssnt#Vne6#=W|Etyb{an7ku=?xynd{%_WV~8&|2vtqtj^oG2I3AC}pP&2v`}=-xd_3-U$KxmruE0dJhh(2FYNm3{O8Qo_t5#@_kYfN&P?&T z5Ad6?&i}s8Gd8?z<6q~0kB4iX_t@+F@B2UJfA04>|NH*W`5#{Mcl^Bf{a@o>U#IyS zE0)b>iq~sn=f7V2`zU|&&Oeyk*WZuFEC2Ay-`M$Yw~kNw|M?^A{9j(e6O(!8Z-2&{ zjpwIZ*kOPD{LuQJKL~JM=?*PkSm!hR<)VH?|7bk@6`u2t{l3WIlh(6% z?i%5_Yj}Oz-uhpdyN}j?aO|ajwf^CC_tE+WOaE&9oA>&cKj!cFg{S%J{w4e9f7x>v z!^Zss*8L1#`RhKH`NGRK{;{?G(|EY%d5^vF*Zq(2%3t?Cu=1DwGfzzEe`4?Wg`GcZ zlkw;c>|6hXwU(tHf~9Z3tTp0A|BGj>h1cE@|M(;SjK{ut`Exw2|M9Q2FMR`U{coOp z&_9W%<0n4pA9$UA`Tni{#nX%Z{lKY@)=t--UJI|@i+`PeJ)Yig9vpk^|6PB2KlRoA z-}UD_3$OV*e&U<`-2an*_UG3B$-nnc^3VRR{Chvge|XIw|H{9|lW+6j*en0u|H(i5 zyYlb-pZvpX{*Iscr2m!Q{O57Mwf+}RFQ&HP3te zv%WP#wo5h=W+ilo{pdQ?tj*QzJKd~#ZN8z`+-v**>*h{8(y~Y4`=-^ z|8ULo9((EEu0OR+ec{jNuD|lh{zp6=zp(c|=B9?;-&_AD|6V`Dmi4Lpdp+YnyylL7 z<=^AUw|Q{vm4B~)a?ko!{=NQ{&ouvzpZK!=TmO@9>wj?T|6u8RaO;2Z-1ow_{aMef4QLl#dF(>ed~Yt=jZ5uaO;2bd;#>o{1MOj9RI@TfB4q_;MV`*(Q?v%!P0l& z*8k!e8(y~3cec0w7lvz|_t>}oXS}q(^c}eMzj^C_`Ip{DPc}yXfm{EBTmOrX{tuSE z2eq`X}{~{xNR-&v@!@{SR*aZ+`rK(EsvJJl(&-uD|X-oVgm` z`X77iU-QDbpX>bZ`#~;S4{a^am`}Y@%r0`^gY=5qyNnl R6Z&8NmB0NtfAl~6e*t_A34j0q literal 0 HcmV?d00001 diff --git a/test/gfx/unoptimized-full.attrmap b/test/gfx/unoptimized-full.attrmap new file mode 100644 index 0000000000000000000000000000000000000000..fe8b860f9bb4e7bc712f7cdaede6820f578ea536 GIT binary patch literal 512 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 Cd!tAI literal 0 HcmV?d00001 diff --git a/test/gfx/unoptimized-full.tilemap b/test/gfx/unoptimized-full.tilemap new file mode 100644 index 0000000000000000000000000000000000000000..553a99f955221f149c3a4ee0df0b19c117d744bf GIT binary patch literal 512 zcmZQzWMXDvWn<^yMC+6cQE@6%&_`l#-T_m6KOcR8m$^Ra4i{)Y8_`)zddH zG%_|ZH8Z!cw6eCbwX=6{baHlab#wRd^z!!c_45x13RUz zF>}`JIdkXDU$Ah|;w4L$Enl&6)#^2C*R9{Mant54TeofBv2)k%J$v`