Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | 4x 4x 4x 4x 5x 5x 5x 5x 5x 3x 3x 5x 90x 2880x 2880x 2880x 2880x 2880x 2880x 2880x 2880x 2880x 2880x 2880x 2880x 2880x 3525x 2880x 2675x 2675x 205x 205x 205x 5x | import {
TILE_SIZE,
TILE_COLOR_PROP_FLIP_VERTICAL,
TILE_COLOR_PROP_FLIP_HORIZONTAL,
} from "consts";
import {
IndexedImage,
sliceIndexedImage,
indexedImageTo2bppTileData,
flipIndexedImageX,
flipIndexedImageY,
} from "shared/lib/tiles/indexedImage";
import { TileLookup, hashTileData } from "shared/lib/tiles/tileData";
interface AutoFlipResult {
tileData: Uint8Array[];
tileAttrs: number[];
tilesetData: Uint8Array[];
}
export const autoFlipTiles = ({
indexedImage,
tileColors,
commonTileData,
}: {
indexedImage: IndexedImage;
tileColors: readonly number[];
commonTileData: Uint8Array[];
}): AutoFlipResult => {
const xTiles = Math.floor(indexedImage.width / TILE_SIZE);
const yTiles = Math.floor(indexedImage.height / TILE_SIZE);
const newTileData: Uint8Array[] = [];
const newTileColors = [...tileColors];
const tileLookup: TileLookup = commonTileData.reduce((memo, tileData) => {
memo[hashTileData(tileData)] = tileData;
return memo;
}, {} as TileLookup);
for (let tyi = 0; tyi < yTiles; tyi++) {
for (let txi = 0; txi < xTiles; txi++) {
const index = tyi * xTiles + txi;
const attr = tileColors[index];
const clearedAttr =
attr &
~(TILE_COLOR_PROP_FLIP_VERTICAL | TILE_COLOR_PROP_FLIP_HORIZONTAL);
const slicedTile = sliceIndexedImage(
indexedImage,
txi * TILE_SIZE,
tyi * TILE_SIZE,
TILE_SIZE,
TILE_SIZE,
);
const origData = indexedImageTo2bppTileData(slicedTile);
const origHash = hashTileData(origData);
const slicedTileFlipX = flipIndexedImageX(slicedTile);
const slicedTileFlipY = flipIndexedImageY(slicedTile);
const slicedTileFlipXY = flipIndexedImageX(slicedTileFlipY);
const flipX = indexedImageTo2bppTileData(slicedTileFlipX);
const flipY = indexedImageTo2bppTileData(slicedTileFlipY);
const flipXY = indexedImageTo2bppTileData(slicedTileFlipXY);
const variants = [
{ data: origData, hash: origHash, mask: 0 },
{
data: flipX,
hash: hashTileData(flipX),
mask: TILE_COLOR_PROP_FLIP_HORIZONTAL,
},
{
data: flipY,
hash: hashTileData(flipY),
mask: TILE_COLOR_PROP_FLIP_VERTICAL,
},
{
data: flipXY,
hash: hashTileData(flipXY),
mask: TILE_COLOR_PROP_FLIP_HORIZONTAL | TILE_COLOR_PROP_FLIP_VERTICAL,
},
];
// Check if any variant already exists
const matched = variants.find((v) => tileLookup[v.hash]);
if (matched) {
// If we found a match, use it and set flip attributes
newTileData.push(matched.data);
newTileColors[index] = clearedAttr | matched.mask;
} else {
// Otherwise, add the original
tileLookup[origHash] = origData;
newTileColors[index] = clearedAttr;
newTileData.push(origData);
}
}
}
return {
tileData: newTileData,
tileAttrs: newTileColors,
tilesetData: [...commonTileData, ...newTileData],
};
};
|