diff --git a/src/gfx/reverse.cpp b/src/gfx/reverse.cpp index 897a4690..13ee60b5 100644 --- a/src/gfx/reverse.cpp +++ b/src/gfx/reverse.cpp @@ -293,19 +293,13 @@ void reverse() { // 1. Checking those during the main loop is harmful to optimization, and // 2. It clutters the code more, and it's not in great shape to begin with for (size_t index = 0; index < mapSize; ++index) { - uint8_t attr = (*attrmap)[index]; size_t tx = index % width, ty = index / width; + uint8_t attr = (*attrmap)[index]; + uint8_t palID = attr & 0b111; - if (uint8_t palID = attr & 0b111; palID < options.basePalID) { - error( - "Attribute map references palette #%" PRIu8 - " at (%zu, %zu), but the base palette ID is #%" PRIu8, - palID, - tx, - ty, - options.basePalID - ); - } else if (palID >= palettes.size() + options.basePalID) { + // The unsigned underflow for `palOfs` is intentional, since a nonzero + // base palette ID may overflow and continue with IDs from 0. + if (uint8_t palOfs = (palID - options.basePalID) & 0b111; palOfs >= palettes.size()) { error( "Attribute map references palette #%" PRIu8 " at (%zu, %zu), but there are only %zu palette%s", @@ -535,7 +529,8 @@ void reverse() { : index; // This should have been enforced by the earlier checking. assume(tileOfs < nbTiles + options.trim); - size_t palOfs = (palmap ? (*palmap)[index] : attribute & 0b111) - options.basePalID; + size_t palOfs = + ((palmap ? (*palmap)[index] : attribute & 0b111) - options.basePalID) & 0b111; assume(palOfs < palettes.size()); // Should be ensured on data read // We do not have data for tiles trimmed with `-x`, so assume they are "blank" diff --git a/test/gfx/reverse_base_wrap.2bpp b/test/gfx/reverse_base_wrap.2bpp new file mode 100644 index 00000000..cf3e1ff4 --- /dev/null +++ b/test/gfx/reverse_base_wrap.2bpp @@ -0,0 +1 @@ +ÃðÃðÃðÃðÃðÃðÃðÃð<<<<<<<<ðÃðÃðÃðÃðÃðÃðÃðÃ<<<<<<<<ÃÌÃÌÃÌÃÌÃÌÃÌÃÌÃÌ33333333ðÃðÃðÃðÃðÃðÃðÃðÃ<<<<<<<< \ No newline at end of file diff --git a/test/gfx/reverse_base_wrap.flags b/test/gfx/reverse_base_wrap.flags new file mode 100644 index 00000000..431b5aaf --- /dev/null +++ b/test/gfx/reverse_base_wrap.flags @@ -0,0 +1,5 @@ +-b 255 +-l 3 +-t reverse_base_wrap.tilemap +-q reverse_base_wrap.palmap +-p reverse_base_wrap.pal diff --git a/test/gfx/reverse_base_wrap.pal b/test/gfx/reverse_base_wrap.pal new file mode 100644 index 00000000..17adc089 Binary files /dev/null and b/test/gfx/reverse_base_wrap.pal differ diff --git a/test/gfx/reverse_base_wrap.palmap b/test/gfx/reverse_base_wrap.palmap new file mode 100644 index 00000000..acffa6ca --- /dev/null +++ b/test/gfx/reverse_base_wrap.palmap @@ -0,0 +1,2 @@ + +  \ No newline at end of file diff --git a/test/gfx/reverse_base_wrap.tilemap b/test/gfx/reverse_base_wrap.tilemap new file mode 100644 index 00000000..4c8f6b76 Binary files /dev/null and b/test/gfx/reverse_base_wrap.tilemap differ