public object LoadAsset(AssetKey key, string name, Func <AssetKey, string, object> loaderFunc) { if (key.Type == AssetType.CoreSpriteConfig) { var settings = Resolve <ISettings>(); return(CoreSpriteConfig.Load(settings.BasePath)); } var generalConfig = (GeneralConfig)loaderFunc(new AssetKey(AssetType.GeneralConfig), "GeneralConfig"); var coreSpriteConfig = (CoreSpriteConfig)loaderFunc(new AssetKey(AssetType.CoreSpriteConfig), "CoreSpriteConfig"); var exePath = Path.Combine(generalConfig.BasePath, generalConfig.ExePath); if (key.Type == AssetType.CoreGraphics) { return(CoreSpriteLoader.Load((CoreSpriteId)key.Id, exePath, coreSpriteConfig)); } if (key.Type == AssetType.CoreGraphicsMetadata) { return(CoreSpriteLoader.GetConfig((CoreSpriteId)key.Id, exePath, coreSpriteConfig, out _)); } throw new InvalidOperationException("CoreSpriteLocator called with an invalid type"); }
public object Get(AssetKey key) { var subKey = Tuple.Create(key.Id, key.Language); lock (_syncRoot) { if (_assetCache.TryGetValue(key.Type, out var typeCache)) { if (typeCache.TryGetValue(subKey, out var cachedAsset)) { return(cachedAsset); } } else { _assetCache[key.Type] = new Dictionary <Tuple <int, GameLanguage>, object>(); } // Check old cache if (_oldAssetCache.TryGetValue(key.Type, out var oldTypeCache) && oldTypeCache.TryGetValue(subKey, out var oldCachedAsset)) { if (!(oldCachedAsset is Exception)) { _assetCache[key.Type][subKey] = oldCachedAsset; return(oldCachedAsset); } } } return(null); }
public object Process(ICoreFactory factory, AssetKey key, object asset, Func <AssetKey, object> loaderFunc) { switch (asset) { case CharacterSheet sheet: ResolveItemProxies(sheet.Inventory, loaderFunc); break; case Inventory x: ResolveItemProxies(x, loaderFunc); break; case SavedGame save: foreach (var sheet in save.PartyMembers.Values) { ResolveItemProxies(sheet.Inventory, loaderFunc); } foreach (var inv in save.Chests.Values) { ResolveItemProxies(inv, loaderFunc); } foreach (var inv in save.Merchants.Values) { ResolveItemProxies(inv, loaderFunc); } break; default: throw new InvalidOperationException($"Unexpected asset type in inventory post processor: {asset}"); } return(asset); }
public object LoadAsset(AssetKey key, string name, Func <AssetKey, object> loaderFunc) { var regular = (ITexture)loaderFunc(new AssetKey(AssetType.Font)); var bold = (ITexture)loaderFunc(new AssetKey(AssetType.Font, (int)FontId.BoldFont)); return(FontLoader.Load(_factory, (MetaFontId)key.Id, regular, bold)); }
public void Add(object asset, AssetKey key) { var subKey = Tuple.Create(key.Id, key.Language); lock (_syncRoot) { _assetCache[key.Type][subKey] = asset; } }
public object LoadAsset(AssetKey key, string name, Func <AssetKey, string, object> loaderFunc) { var settings = Resolve <ISettings>(); return(key.Type switch { AssetType.AssetConfig => BasicAssetConfig.Load(settings.BasePath), AssetType.GeneralConfig => GeneralConfig.Load(settings.BasePath), _ => throw new ArgumentOutOfRangeException(nameof(key)) });
public object LoadAsset(AssetKey key, string name, Func <AssetKey, object> loaderFunc) { var generalConfig = (IGeneralConfig)loaderFunc(new AssetKey(AssetType.GeneralConfig)); var filename = Path.Combine(generalConfig.BasePath, generalConfig.SavePath, $"SAVE.{key.Id:D3}"); var loader = AssetLoaderRegistry.GetLoader <SavedGame>(FileFormat.SavedGame); using var stream = File.Open(filename, FileMode.Open); using var br = new BinaryReader(stream); return(loader.Serdes( null, new AlbionReader(br, stream.Length), key, null)); }
public object LoadAsset(AssetKey key, string name, Func <AssetKey, object> loaderFunc) { if (key.Type != AssetType.SoundBank) { throw new InvalidOperationException($"Called SoundBankLocator with unexpected asset type {key.Type}"); } var config = (IGeneralConfig)loaderFunc(new AssetKey(AssetType.GeneralConfig)); var oplPath = Path.Combine(config.BasePath, config.ExePath, "DRIVERS", "ALBISND.OPL"); GlobalTimbreLibrary oplFile = ReadOpl(oplPath); WoplFile wopl = new WoplFile(oplFile); byte[] bankData = GetRawWoplBytes(wopl); return(bankData); }
public object LoadAssetCached(AssetKey key) { object asset = _assetCache.Get(key); if (asset is Exception) // If it failed to load once then stop trying (at least until an asset:reload / cycle) { return(null); } if (asset != null) { return(asset); } asset = LoadAssetInternal(key); _assetCache.Add(asset, key); return(asset is Exception ? null : asset); }
public object LoadAsset(AssetKey key, string name, Func <AssetKey, object> loaderFunc) { Load(); if (!_strings.TryGetValue((UAlbionStringId)key.Id, out var languages)) { Raise(new LogEvent(LogEvent.Level.Error, $"No strings found for {(UAlbionStringId)key.Id}")); return($"MISSING!{(UAlbionStringId)key.Id}"); } if (languages.TryGetValue(key.Language, out var s)) { return(s); } Raise(new LogEvent(LogEvent.Level.Warning, $"Missing translation for {(UAlbionStringId)key.Id} in {key.Language}")); return(languages[GameLanguage.English]); // Default }
public object LoadAssetCached <T>(AssetType type, T enumId, GameLanguage language = GameLanguage.English) { int id = Convert.ToInt32(enumId); var key = new AssetKey(type, id, language); object asset = _assetCache.Get(key); if (asset is Exception) // If it failed to load once then stop trying (at least until an asset:reload / cycle) { return(null); } if (asset != null) { return(asset); } var name = typeof(T) == typeof(int) ? $"{type}.{AssetNameResolver.GetName(type, (int)(object)enumId)}" : $"{type}.{enumId}"; try { IAssetLocator locator = GetLocator(key.Type); asset = locator.LoadAsset(key, name, (x, y) => LoadAssetCached(x.Type, x.Id, x.Language)); if (asset != null && PostProcessors.TryGetValue(asset.GetType(), out var processor)) { asset = processor.Process(name, asset); } } catch (Exception e) { Raise(new LogEvent(LogEvent.Level.Error, $"Could not load asset {name}: {e}")); asset = e; } _assetCache.Add(asset, key); return(asset is Exception ? null : asset); }
object LoadAssetInternal(AssetKey key) { var name = $"{key.Type}.{key.Id}"; try { ICoreFactory factory = Resolve <ICoreFactory>(); IAssetLocator locator = GetLocator(key.Type); var asset = locator.LoadAsset(key, name, LoadAssetCached); if (asset != null && _postProcessors.TryGetValue(asset.GetType(), out var processor)) { asset = processor.Process(factory, key, asset, LoadAssetCached); } return(asset); } catch (Exception e) { Raise(new LogEvent(LogEvent.Level.Error, $"Could not load asset {name}: {e}")); return(e); } }
public object LoadAsset(AssetKey key) { var asset = LoadAssetInternal(key); return(asset is Exception ? null : asset); }
public XldKey(AssetKey key) { Type = key.Type; Number = key.Id / 100; Language = key.Language; }
public object Process(ICoreFactory factory, AssetKey key, object asset, Func <AssetKey, object> loaderFunc) { var sprite = (AlbionSprite)asset; SubImage[] subImages; byte[] pixelData; if (key.Type == AssetType.Font || sprite.UniformFrames && sprite.Frames.Count >= 256) { const int buffer = 1; // For things like tilemaps etc we repack into a texture atlas with buffer pixels. int srcTileWidth = sprite.Width; int srcTileHeight = sprite.Height / sprite.Frames.Count; int destTileWidth = srcTileWidth + buffer * 2; int destTileHeight = srcTileHeight + buffer * 2; var(width, height) = GetAtlasSize(destTileWidth, destTileHeight, sprite.Frames.Count); pixelData = new byte[width * height]; subImages = new SubImage[sprite.Frames.Count]; int curX = 0; int curY = 0; for (int n = 0; n < sprite.Frames.Count; n++) { for (int j = 0; j < destTileHeight; j++) { for (int i = 0; i < destTileWidth; i++) { var sourceX = Math.Clamp(i - buffer, 0, srcTileWidth - buffer); var sourceY = Math.Clamp(j - buffer, 0, srcTileHeight - buffer) + n * srcTileHeight; var destX = curX + i; var destY = curY + j; pixelData[destY * width + destX] = sprite.PixelData[sourceX + sourceY * srcTileWidth]; } } subImages[n] = new SubImage( new Vector2(curX + buffer, curY + buffer), new Vector2(sprite.Frames[n].Width, sprite.Frames[n].Height), new Vector2(width, height), 0); curX += destTileWidth; if (curX + destTileWidth > width) { curX = 0; curY += destTileHeight; } } return(factory.CreateEightBitTexture( sprite.Name, (uint)width, (uint)height, 1, 1, pixelData, subImages)); } /* * else if (sprite.UniformFrames) // For reasonably sized uniform sprites use layers to simplify mip mapping / tiling etc * { * int tileWidth = sprite.Width; * int tileHeight = sprite.Height / sprite.Frames.Count; * pixelData = sprite.PixelData; * subImages = sprite.Frames * .Select((x, i) => new EightBitTexture.SubImage(0, 0, x.Width, x.Height, i)) * .ToArray(); * * return new EightBitTexture( * sprite.Name, * (uint)tileWidth, * (uint)tileHeight, * 1, * (uint)subImages.Length, * pixelData, subImages); * }*/ else // For non-uniforms just use the on-disk packing { pixelData = sprite.PixelData; subImages = sprite.Frames .Select(x => new SubImage( new Vector2(x.X, x.Y), new Vector2(x.Width, x.Height), new Vector2(sprite.Width, sprite.Height), 0)) .ToArray(); return(factory.CreateEightBitTexture( sprite.Name, (uint)sprite.Width, (uint)sprite.Height, 1, 1, pixelData, subImages)); } }
public static object Load(BinaryReader br, AssetKey key, int streamLength, AssetInfo config) => GetLoader(config.Format).Load(br, streamLength, key, config);