Beispiel #1
0
        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");
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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));
        }
Beispiel #5
0
        public void Add(object asset, AssetKey key)
        {
            var subKey = Tuple.Create(key.Id, key.Language);

            lock (_syncRoot)
            {
                _assetCache[key.Type][subKey] = asset;
            }
        }
Beispiel #6
0
        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))
            });
Beispiel #7
0
        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));
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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
        }
Beispiel #11
0
        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);
        }
Beispiel #12
0
        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);
            }
        }
Beispiel #13
0
        public object LoadAsset(AssetKey key)
        {
            var asset = LoadAssetInternal(key);

            return(asset is Exception ? null : asset);
        }
Beispiel #14
0
 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));
            }
        }
Beispiel #16
0
 public static object Load(BinaryReader br, AssetKey key, int streamLength, AssetInfo config)
 => GetLoader(config.Format).Load(br, streamLength, key, config);