예제 #1
0
        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;
        }
예제 #2
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:
                ;
            }
        }
예제 #3
0
        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);
                    }
                }
            }
        }