private bool FinalizeLayerChunkIndex(byte[] loadedBytes) { RBTilemapTMX.TMXMapDef map = null; map = layerState.map.internalState.mapDef; try { var reader = new BinaryReader(new MemoryStream(loadedBytes)); int byteSize = 0; int chunkCount = reader.ReadInt32(); byteSize += 4; var table = new Dictionary <ulong, RBTilemapTMX.ChunkDef>(); // Return empty table if there are no chunks if (chunkCount == 0) { map.layerIndexLRU.Add(mIndexPath, table, byteSize); mChunkIndex = table; return(true); } for (int i = 0; i < chunkCount; i++) { var chunkDef = new RBTilemapTMX.ChunkDef(); ulong offset = reader.ReadUInt64(); byteSize += 8; chunkDef.segmentIndex = reader.ReadUInt16(); byteSize += 2; chunkDef.segmentOffset = reader.ReadUInt16(); byteSize += 2; chunkDef.compressedLength = reader.ReadUInt16(); byteSize += 2; table[offset] = chunkDef; } map.layerIndexLRU.Add(mIndexPath, table, byteSize); mChunkIndex = table; return(true); } catch (IOException e) { Debug.Log("Failed to load layer index from file " + mIndexPath + ", " + e.ToString()); return(false); } }
private bool LoadLayerInfo() { RBTilemapTMX.TMXMapDef map = null; map = layerState.map.internalState.mapDef; 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 loaded yet!"); layerState.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.BadParam); return(false); } if (!map.infinite) { Debug.LogError("TMX map is not infinite, use LoadTMXLayer() instead"); layerState.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.BadParam); return(false); } if (!map.layers.ContainsKey(mTmxSourceLayer)) { Debug.LogError("Layer " + mTmxSourceLayer + " not found"); layerState.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotFound); return(false); } var tmxLayer = (RBTilemapTMX.TMXLayerDef)map.layers[mTmxSourceLayer]; int layerNameHash = mWorkStr.Set(mTmxSourceLayer).ToLowerInvariant().GetHashCode(); int chunkWidth = map.chunkSize.x; int chunkHeight = map.chunkSize.y; ulong part1 = (ulong)mChunkOffset.x; ulong part2 = (ulong)mChunkOffset.y; ulong offset = ((part1 << 32) & 0xFFFFFFFF00000000) | (part2 & 0xFFFFFFFF); mTupleKey = new RBTilemapTMX.RetroBlitTuple <int, ulong>(layerNameHash, offset); var decompressed = map.chunkLRU.Get(mTupleKey); if (decompressed != null) { RetroBlitInternal.RBAPI.instance.Tilemap.FinalizeLayerChunkLoad(map, mTmxSourceLayer, mDestinationLayer, mChunkOffset, mDestPos, mPackedSpriteLookup, layerState, decompressed); return(true); } // 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 (!mChunkIndex.ContainsKey(offset)) { for (int y = mDestPos.y; y < mDestPos.y + chunkHeight; y++) { for (int x = mDestPos.x; x < mDestPos.x + chunkWidth; x++) { RetroBlitInternal.RBAPI.instance.Tilemap.SpriteSet(mDestinationLayer, x, y, RB.SPRITE_EMPTY, Color.white, 0); RBTilemapTMX.Tile[] tilesArr; int tileIndex; if (RetroBlitInternal.RBAPI.instance.Tilemap.GetTileRef(mDestinationLayer, x, y, out tilesArr, out tileIndex, true)) { tilesArr[tileIndex].data = null; } } } layerState.InternalSetErrorStatus(RB.AssetStatus.Ready, RB.Result.Success); return(true); } mChunkDef = mChunkIndex[offset]; var mPath = map.realPathName + "layer_" + layerNameHash.ToString("x") + "_seg_" + mChunkDef.segmentIndex; if (mSource == RB.AssetSource.WWW || mSource == RB.AssetSource.AddressableAssets) { mPath += ".bytes"; } // Check if this is a web request if (mSource == RB.AssetSource.WWW) { mWebRequest = UnityWebRequest.Get(mPath); if (mWebRequest == null) { layerState.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NoResources); return(false); } if (mWebRequest.SendWebRequest() == null) { layerState.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NoResources); return(false); } layerState.InternalSetErrorStatus(RB.AssetStatus.Loading, RB.Result.Pending); return(true); } else if (mSource == RB.AssetSource.ResourcesAsync) { mResourceRequest = Resources.LoadAsync <TextAsset>(mPath); if (mResourceRequest == null) { layerState.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NoResources); return(false); } layerState.InternalSetErrorStatus(RB.AssetStatus.Loading, RB.Result.Pending); } #if ADDRESSABLES_PACKAGE_AVAILABLE else if (mSource == RB.AssetSource.AddressableAssets) { // Exceptions on LoadAssetAsync can't actually be caught... this might work in the future so leaving it here try { mAddressableRequest = Addressables.LoadAssetAsync <TextAsset>(mPath); } catch (UnityEngine.AddressableAssets.InvalidKeyException e) { RBUtil.Unused(e); layerState.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotFound); return(false); } catch (Exception e) { RBUtil.Unused(e); layerState.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.Undefined); return(false); } // Check for an immediate failure if (mAddressableRequest.Status == AsyncOperationStatus.Failed) { Addressables.Release(mAddressableRequest); layerState.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.Undefined); return(false); } layerState.SetErrorStatus(RB.AssetStatus.Loading, RB.Result.Pending); layerState.progress = 0; return(true); } #endif return(true); }