示例#1
0
 /// <summary>
 /// Equality check
 /// </summary>
 /// <param name="tuple">Other tuple</param>
 /// <returns>True if equal</returns>
 public bool Equals(RetroBlitTuple <FT, ST> tuple)
 {
     return(tuple.First.Equals(First) && tuple.Second.Equals(Second));
 }
示例#2
0
        /// <summary>
        /// Load a single layer chunk
        /// </summary>
        /// <param name="tmx">Map definition</param>
        /// <param name="tmxSourceLayer">Name of source layer</param>
        /// <param name="destinationLayer">RetroBlit destination layer</param>
        /// <param name="chunkOffset">Chunk offset</param>
        /// <param name="destPos">Destination position</param>
        /// <param name="packedSpriteLookup">Lookup table for translating TMX tile indexes to packed sprites</param>
        /// <returns>True if successful</returns>
        public bool LoadTMXLayerChunk(TMXMap tmx, string tmxSourceLayer, int destinationLayer, Vector2i chunkOffset, Vector2i destPos, PackedSpriteID[] packedSpriteLookup)
        {
            TMXMapDef map = null;

            if (!(tmx is RetroBlitInternal.RetroBlitTilemap.TMXMapDef))
            {
                Debug.LogError("Can't load TMX layer, invalid map object!");
                return(false);
            }

            map = (TMXMapDef)tmx;

            if (map == null || map.realPathName == null || map.realPathName.Length == 0 || map.layers == null)
            {
                Debug.LogError("Can't load TMX layer, invalid map, or map not open yet!");
                return(false);
            }

            if (!map.infinite)
            {
                Debug.LogError("TMX map is not infinite, use LoadTMXLayer() instead");
                return(false);
            }

            if (!map.layers.ContainsKey(tmxSourceLayer))
            {
                Debug.LogError("Layer " + tmxSourceLayer + " not found");
                return(false);
            }

            int chunkWidth  = map.chunkSize.x;
            int chunkHeight = map.chunkSize.y;

            var tmxLayer = (TMXLayerDef)map.layers[tmxSourceLayer];

            ulong part1  = (ulong)chunkOffset.x;
            ulong part2  = (ulong)chunkOffset.y;
            ulong offset = ((part1 << 32) & 0xFFFFFFFF00000000) | (part2 & 0xFFFFFFFF);

            int layerNameHash = mWorkStr.Set(tmxSourceLayer).ToLowerInvariant().GetHashCode();
            var tupleKey      = new RetroBlitTuple <int, ulong>(layerNameHash, offset);

            var decompressed = map.mChunkLRU.Get(tupleKey);

            if (decompressed == null)
            {
                var chunkTable = GetLayerIndexTable(map, layerNameHash);

                if (chunkTable == null)
                {
                    Debug.LogError("TMX could not load chunk index table for layer " + tmxSourceLayer);
                    return(false);
                }

                // If the chunk can't be found then fail silently and wipe the chunk area. This will also
                // release the chunk geometry on next draw because it will not have any vertices
                if (!chunkTable.ContainsKey(offset))
                {
                    for (int y = destPos.y; y < destPos.y + chunkHeight; y++)
                    {
                        for (int x = destPos.x; x < destPos.x + chunkWidth; x++)
                        {
                            mRetroBlitAPI.Tilemap.SpriteSet(destinationLayer, x, y, RB.SPRITE_EMPTY, Color.white, 0);

                            Tile[] tilesArr;
                            int    tileIndex;
                            if (GetTileRef(destinationLayer, x, y, out tilesArr, out tileIndex, true))
                            {
                                tilesArr[tileIndex].data = null;
                            }
                        }
                    }

                    return(true);
                }

                var chunkDef = chunkTable[offset];

                var chunkFileName = map.realPathName + "layer_" + layerNameHash.ToString("x") + "_seg_" + chunkDef.segmentIndex;

                var chunkFile = Resources.Load <TextAsset>(chunkFileName);

                if (chunkFile == null)
                {
                    Debug.LogError("Can't find TMX file when loading TMX layer!");
                    return(false);
                }

                var chunkBytes = chunkFile.bytes;

                decompressed = RetroBlitDeflate.Decompress(chunkBytes, chunkDef.segmentOffset, chunkDef.compressedLength);
                if (decompressed == null || decompressed.Length <= 0)
                {
                    Debug.LogError("Could not decompress tile data for layer " + tmxSourceLayer);
                    return(false);
                }

                map.mChunkLRU.Add(tupleKey, decompressed, decompressed.Length);
            }

            var tileDataReader = new BinaryReader(new MemoryStream(decompressed));

            if (tileDataReader == null)
            {
                Debug.LogError("Could not read tile data for layer " + tmxSourceLayer);
                return(false);
            }

            Color32 color = Color.white;

            int sx = 0;
            int sy = 0;

            int dx = destPos.x;
            int dy = destPos.y;

            while (tileDataReader.PeekChar() >= 0)
            {
                // Skip tsxIndex, don't need it for now
                tileDataReader.ReadByte();

                byte flags  = tileDataReader.ReadByte();
                int  tileId = tileDataReader.ReadInt32();

                if (packedSpriteLookup != null)
                {
                    if (packedSpriteLookup != null)
                    {
                        if (tileId < packedSpriteLookup.Length && tileId >= 0)
                        {
                            tileId = packedSpriteLookup[tileId].id;
                            flags |= RetroBlitInternal.RetroBlitTilemap.SPRITEPACK;
                        }
                    }
                }

                SpriteSet(destinationLayer, dx, dy, tileId, color, flags);
                dx++;
                sx++;

                if (sx >= chunkWidth)
                {
                    sx = 0;
                    dx = destPos.x;
                    sy++;
                    dy++;
                }

                if (sy >= chunkHeight)
                {
                    break;
                }
            }

            return(true);
        }