ref: 779c8c9368d234da7d17bdf708e9bbd7fee9d803
parent: e855b6f6222d4e5fab0fd203cf348d1c1ad04d90
author: ISSOtm <eldredhabert0@gmail.com>
date: Fri Mar 11 21:06:03 EST 2022
Implement `-m` Though none of the code involved has been tested in any capacity yet, lol
--- a/src/gfx/convert.cpp
+++ b/src/gfx/convert.cpp
@@ -674,14 +674,43 @@
VHFLIP,
};
MatchType tryMatching(TileData const &other) const {
- if (std::equal(_data.begin(), _data.end(), other._data.begin()))
+ // Check for strict equality first, as that can typically be optimized, and it allows
+ // hoisting the mirroring check out of the loop
+ if (_data == other._data) {
return MatchType::EXACT;
+ }
- if (options.allowMirroring) {
- // TODO
+ if (!options.allowMirroring) {
+ return MatchType::NOPE;
}
- return MatchType::NOPE;
+ // Check if we have horizontal mirroring, which scans the array forward again
+ if (std::equal(_data.begin(), _data.end(), other._data.begin(),
+ [](uint8_t lhs, uint8_t rhs) { return lhs == flip(rhs); })) {
+ return MatchType::HFLIP;
+ }
+
+ // Check if we have vertical or vertical+horizontal mirroring, for which we have to read
+ // bitplane *pairs* backwards
+ bool hasVFlip = true, hasVHFlip = true;
+ for (uint8_t i = 0; i < _data.size(); ++i) {
+ // Flip the bottom bit to get the corresponding row's bitplane 0/1
+ // (This works because the array size is even)
+ uint8_t lhs = _data[i], rhs = other._data[(15 - i) ^ 1];
+ if (lhs != rhs) {
+ hasVFlip = false;
+ }
+ if (lhs != flip(rhs)) {
+ hasVHFlip = false;
+ }
+ if (!hasVFlip && !hasVHFlip) {
+ return MatchType::NOPE; // If both have been eliminated, all hope is lost!
+ }
+ }
+
+ // If we have both (i.e. we have symmetry), default to vflip only
+ assert(hasVFlip || hasVHFlip);
+ return hasVFlip ? MatchType::VFLIP : MatchType::VHFLIP;
}
friend bool operator==(TileData const &lhs, TileData const &rhs) {
return lhs.tryMatching(rhs) != MatchType::NOPE;
@@ -745,7 +774,6 @@
iter->xFlip = matchType == TileData::HFLIP || matchType == TileData::VHFLIP;
iter->yFlip = matchType == TileData::VFLIP || matchType == TileData::VHFLIP;
- assert(tileID < 1 << 10);
iter->tileID = tileID;
++iter;