void ParseTileFlags(Tileset.Tile tile, ulong flags) { // Bit 2: Draw in background // Bit 6: Draw above player (not sure as it is in combination with bit 2 often, but it seems to work if this overrides bit 2) // Bit 8: Allow movement (0 means block movement) // Bit 16: Unknown. It has the same value as bit 8 most of the times (but not always). // Bit 23-25: Sit/sleep value // 0 -> no sitting nor sleeping // 1 -> sit and look up // 2 -> sit and look right // 3 -> sit and look down // 4 -> sit and look left // 5 -> sleep (always face down) // Bit 26: Player invisible (doors, behind towers/walls, etc) // Another possible explanation for bit 2/6 would be: // - Bit 2: Disable baseline rendering / use custom sprite ordering // - Bit 6: 0 = behind player, 1 = above player (only used if Bit 2 is set) tile.Background = (flags & 0x04) != 0; tile.BringToFront = (flags & 0x40) != 0; tile.BlockMovement = (flags & 0x0100) == 0; var sitSleepValue = (flags >> 23) & 0x07; tile.SitDirection = (sitSleepValue == 0 || sitSleepValue > 4) ? (CharacterDirection?)null : (CharacterDirection)(sitSleepValue - 1); tile.Sleep = sitSleepValue == 5; tile.Invisible = (flags & 0x04000000) != 0; }
public void Tick() { TileAnimation anim = _anim; int c = (_counter + 1) % anim.Duration; _counter = c; for (int f = 0; f < anim.Frames.Length; f++) { TileAnimation.Frame frame = anim.Frames[f]; Tileset.Tile tile = _tileset.Tiles[frame.TilesetTile]; for (int s = frame.Stops.Length - 1; s >= 0; s--) { TileAnimation.Frame.Stop stop = frame.Stops[s]; if (stop.Time <= c) { tile.AnimBitmap = anim.Sheet[stop.SheetTile]; goto bottom; } } tile.AnimBitmap = null; bottom: ; } }
public static unsafe void Render(uint *bmpAddress, int bmpWidth, int bmpHeight) { // Gather variables we need to draw everything at the right coordinates CameraObj camera = Camera; Position cameraPos = camera.Pos; int cameraPixelX = (cameraPos.X * Overworld.Block_NumPixelsX) - (bmpWidth / 2) + (Overworld.Block_NumPixelsX / 2) + camera._progressX + CameraOfsX; int cameraPixelY = (cameraPos.Y * Overworld.Block_NumPixelsY) - (bmpHeight / 2) + (Overworld.Block_NumPixelsY / 2) + camera._progressY + CameraOfsY; Map cameraMap = camera.Map; List <Obj> objs = cameraMap.Objs; int numObjs = objs.Count; int xpBX = cameraPixelX % Overworld.Block_NumPixelsX; int ypBY = cameraPixelY % Overworld.Block_NumPixelsY; int startBlockX = (cameraPixelX / Overworld.Block_NumPixelsX) - (xpBX >= 0 ? 0 : 1); int startBlockY = (cameraPixelY / Overworld.Block_NumPixelsY) - (ypBY >= 0 ? 0 : 1); int numBlocksX = (bmpWidth / Overworld.Block_NumPixelsX) + (bmpWidth % Overworld.Block_NumPixelsX == 0 ? 0 : 1); int numBlocksY = (bmpHeight / Overworld.Block_NumPixelsY) + (bmpHeight % Overworld.Block_NumPixelsY == 0 ? 0 : 1); int endBlockX = startBlockX + numBlocksX + (xpBX == 0 ? 0 : 1); int endBlockY = startBlockY + numBlocksY + (ypBY == 0 ? 0 : 1); int startPixelX = xpBX >= 0 ? -xpBX : -xpBX - Overworld.Block_NumPixelsX; int startPixelY = ypBY >= 0 ? -ypBY : -ypBY - Overworld.Block_NumPixelsY; // Loop each elevation for (byte e = 0; e < Overworld.NumElevations; e++) { // Draw blocks int curPixelX = startPixelX; int curPixelY = startPixelY; for (int blockY = startBlockY; blockY < endBlockY; blockY++) { for (int blockX = startBlockX; blockX < endBlockX; blockX++) { Map.Layout.Block block = cameraMap.GetBlock_CrossMap(blockX, blockY, out _); if (block != null) { Blockset.Block b = block.BlocksetBlock; void Draw(Blockset.Block.Tile[] subLayers, int tx, int ty) { int numSubLayers = subLayers.Length; for (int t = 0; t < numSubLayers; t++) { Blockset.Block.Tile tile = subLayers[t]; Tileset.Tile ttile = tile.TilesetTile; RenderUtils.DrawBitmap(bmpAddress, bmpWidth, bmpHeight, tx, ty, ttile.AnimBitmap ?? ttile.Bitmap, Overworld.Tile_NumPixelsX, Overworld.Tile_NumPixelsY, xFlip: tile.XFlip, yFlip: tile.YFlip); } } for (int by = 0; by < Overworld.Block_NumTilesY; by++) { Blockset.Block.Tile[][][] arrY = b.Tiles[by]; int ty = curPixelY + (by * Overworld.Tile_NumPixelsY); for (int bx = 0; bx < Overworld.Block_NumTilesX; bx++) { Draw(arrY[bx][e], curPixelX + (bx * Overworld.Tile_NumPixelsX), ty); } } } curPixelX += Overworld.Block_NumPixelsX; } curPixelX = startPixelX; curPixelY += Overworld.Block_NumPixelsY; } // Draw VisualObjs // TODO: They will overlap each other regardless of y coordinate because of the order of the list // TODO: Objs from other maps for (int i = 0; i < numObjs; i++) { Obj o = objs[i]; if (o.Pos.Elevation == e && o is VisualObj v) { v.Draw(bmpAddress, bmpWidth, bmpHeight, startBlockX, startBlockY, startPixelX, startPixelY); } } } }