diff --git a/src/coilsnake/fts_interpreter.py b/src/coilsnake/fts_interpreter.py index 41f67fc..1e40596 100644 --- a/src/coilsnake/fts_interpreter.py +++ b/src/coilsnake/fts_interpreter.py @@ -208,6 +208,21 @@ def __init__(self, tile): self.metadata.append(int(self.tile[i] + self.tile[i+1] + self.tile[i+2] + self.tile[i+3], 16)) self.collision.append(int(self.tile[i+4] + self.tile[i+5], 16)) + @staticmethod + def _createErrorMinitile(): + img = Image.new("RGBA", (8, 8)) + # Make a red + light-green checkerboard to indicate an error. + c1 = (255, 0, 0, 255) + c2 = (0, 255, 160, 255) + for y in range(8): + for x in range(8): + c = c2 if (x ^ y) & 0b100 else c1 + img.putpixel((x, y), c) + return img + + # Make one instance of this minitile once, and reuse it in each + _ERROR_MINITILE = _createErrorMinitile() + def getMetadata(self, id): """Return the SNES metadata of a given minitile placement in a tile""" return self.metadata[id] @@ -221,11 +236,7 @@ def getMinitileID(self, id): def getMinitileSubpalette(self, id): """Get subpalette from placement metadata""" metadata = self.getMetadata(id) - # TODO Verify that this fix for metadata avoidance causing backwards indexing in non-vanilla projects is correct - # See DM with Gabbi about the issue (causing bright green tiles in EBBR) subPal = (((metadata & 0x1C00) >> 10)-2) - if subPal < 0: - return 0 return subPal # minitile subpalette is bits 10-12 (bit 13 - priority flag - is irrelevant and never set in fts files). Subtract 2 because the first two are reserved for other things in the game, and we are indexing from 0 def getMinitileHorizontalFlip(self, id): @@ -271,7 +282,10 @@ def toImage(self, palette: Palette, fts: FullTileset, fgOnly=False, bgOnly=False x = 0 y = 0 for id, subpalette, hflip, vflip, collision in self.getMinitileDataList(): - if fgOnly: + if subpalette < 0: + # This tile has an invalid subpalette. Display an error checkerboard pattern to indicate to the user that they should replace it. + minitile = self._ERROR_MINITILE + elif fgOnly: minitile = fts.minitiles[id].ForegroundToImage(palette.subpalettes[subpalette]) elif bgOnly: minitile = fts.minitiles[id].BackgroundToImage(palette.subpalettes[subpalette]) diff --git a/src/tileeditor/arrangement_editor.py b/src/tileeditor/arrangement_editor.py index d539938..d8d54f8 100644 --- a/src/tileeditor/arrangement_editor.py +++ b/src/tileeditor/arrangement_editor.py @@ -85,5 +85,8 @@ def pickMinitile(self, pos: QPoint, nosubpal: bool=False): if not nosubpal: subpalette = self.currentTile.getMinitileSubpalette(index) + if subpalette < 0: + # The tile has an invalid subpalette. For "pick" purposes, fall back to subpalette 0. + subpalette = 0 self.state.tileEditor.paletteView.setSubpaletteIndex(subpalette) self.state.tileEditor.onSubpaletteSelect() \ No newline at end of file