public ContentManager(
            FileSystem fileSystem,
            GraphicsDevice graphicsDevice,
            GraphicsDevice2D graphicsDevice2D,
            SageGame sageGame)
        {
            _fileSystem = fileSystem;

            GraphicsDevice   = graphicsDevice;
            GraphicsDevice2D = graphicsDevice2D;

            SageGame = sageGame;

            IniDataContext = new IniDataContext(fileSystem);

            _contentLoaders = new Dictionary <Type, ContentLoader>
            {
                { typeof(Model), AddDisposable(new ModelLoader()) },
                { typeof(Scene), AddDisposable(new MapLoader()) },
                { typeof(Texture), AddDisposable(new TextureLoader(graphicsDevice)) },
                { typeof(WndTopLevelWindow), AddDisposable(new WindowLoader(this)) },
                { typeof(ShapeComponent), AddDisposable(new ShapeLoader(this)) }
            };

            _cachedObjects = new Dictionary <string, object>();

            EffectLibrary = AddDisposable(new EffectLibrary(graphicsDevice));

            TranslationManager = new TranslationManager(fileSystem);

            _cachedTextFormats = new Dictionary <TextFormatKey, TextFormat>();
        }
        public ContentManager(
            Game game,
            FileSystem fileSystem,
            GraphicsDevice graphicsDevice,
            SageGame sageGame)
        {
            using (GameTrace.TraceDurationEvent("ContentManager()"))
            {
                _game       = game;
                _fileSystem = fileSystem;

                GraphicsDevice = graphicsDevice;

                SageGame = sageGame;

                Language = LanguageUtility.ReadCurrentLanguage(game.Definition, fileSystem.RootDirectory);

                IniDataContext = new IniDataContext();

                SubsystemLoader = Content.SubsystemLoader.Create(game.Definition, _fileSystem, game, this);

                switch (sageGame)
                {
                // Only load these INI files for a subset of games, because we can't parse them for others yet.
                case SageGame.CncGenerals:
                case SageGame.CncGeneralsZeroHour:
                case SageGame.Bfme:
                case SageGame.Bfme2:
                case SageGame.Bfme2Rotwk:
                    SubsystemLoader.Load(Subsystem.Core);

                    // TODO: Defer subsystem loading until necessary
                    SubsystemLoader.Load(Subsystem.Audio);
                    SubsystemLoader.Load(Subsystem.Players);
                    SubsystemLoader.Load(Subsystem.ParticleSystems);
                    SubsystemLoader.Load(Subsystem.ObjectCreation);
                    SubsystemLoader.Load(Subsystem.Multiplayer);
                    SubsystemLoader.Load(Subsystem.LinearCampaign);
                    SubsystemLoader.Load(Subsystem.Wnd);
                    SubsystemLoader.Load(Subsystem.Terrain);
                    SubsystemLoader.Load(Subsystem.Credits);

                    break;

                case SageGame.Cnc3:
                    SubsystemLoader.Load(Subsystem.Core);
                    break;

                default:
                    break;
                }

                TranslationManager = Translation.TranslationManager.Instance;
                Translation.TranslationManager.LoadGameStrings(fileSystem, Language, sageGame);

                FontManager = new FontManager();

                WndImageLoader = AddDisposable(new WndImageLoader(this, game.AssetStore));
            }
        }
Exemple #3
0
        public IniParser(FileSystemEntry entry, AssetStore assetStore, SageGame sageGame, IniDataContext dataContext, Encoding localeSpecificEncoding)
        {
            var iniEncoding = Encoding.ASCII;

            {
                // Use locale specific encoding if a "9x ini file" is present:
                // https://github.com/OpenSAGE/OpenSAGE/issues/405
                var localeSpecificFileName = Path.ChangeExtension(entry.FilePath, null) + "9x.ini";
                var localeSpecificEntry    = entry.FileSystem.GetFile(localeSpecificFileName);
                if (localeSpecificEntry != null)
                {
                    entry       = localeSpecificEntry;
                    iniEncoding = localeSpecificEncoding;
                }
            }

            _directory   = Path.GetDirectoryName(entry.FilePath);
            _dataContext = dataContext;
            _fileSystem  = entry.FileSystem;
            _assetStore  = assetStore;
            SageGame     = sageGame;
            _encoding    = iniEncoding;

            _tokenReader = CreateTokenReader(entry, _encoding);

            _currentBlockOrFieldStack = new Stack <string>();
        }
Exemple #4
0
        protected StatePersister(Game game, StatePersistMode mode)
        {
            Segments = new Stack <Segment>();

            Mode = mode;

            Game       = game;
            SageGame   = game.SageGame;
            AssetStore = game.AssetStore;
        }
Exemple #5
0
        public IniParser(string source, FileSystemEntry entry, IniDataContext dataContext, SageGame game)
        {
            _directory   = Path.GetDirectoryName(entry.FilePath);
            _dataContext = dataContext;
            SageGame     = game;

            _tokenReader = new TokenReader(source, Path.Combine(entry.FileSystem.RootDirectory, entry.FilePath));

            _currentBlockOrFieldStack = new Stack <string>();
        }
        public IniParser(FileSystemEntry entry, AssetStore assetStore, SageGame sageGame, IniDataContext dataContext)
        {
            _directory   = Path.GetDirectoryName(entry.FilePath);
            _dataContext = dataContext;
            _fileSystem  = entry.FileSystem;
            _assetStore  = assetStore;
            SageGame     = sageGame;

            _tokenReader = CreateTokenReader(entry);

            _currentBlockOrFieldStack = new Stack <string>();
        }
        public TranslationManager(FileSystem fileSystem, SageGame game, string language)
        {
            _csfFiles = new List <CsfFile>();
            FileSystemEntry csfEntry          = null;
            var             currentFileSystem = fileSystem;

            while (currentFileSystem != null)
            {
                switch (game)
                {
                case SageGame.CncGenerals:
                case SageGame.CncGeneralsZeroHour:
                    csfEntry = fileSystem.GetFile($@"Data\{language}\generals.csf");
                    break;

                case SageGame.Bfme:
                    csfEntry = fileSystem.GetFile($@"Lang\{language}\lotr.csf");
                    break;

                case SageGame.Bfme2:
                case SageGame.Bfme2Rotwk:
                    csfEntry = fileSystem.GetFile(@"lotr.csf");
                    break;

                case SageGame.Cnc3:
                    break;

                case SageGame.Cnc3KanesWrath:
                    break;

                case SageGame.Ra3:
                    break;

                case SageGame.Ra3Uprising:
                    break;

                case SageGame.Cnc4:
                    break;
                }

                if (csfEntry != null)
                {
                    // TODO: Each game probably has its own path for this file.
                    _csfFiles.Add(CsfFile.FromFileSystemEntry(csfEntry));
                }

                currentFileSystem = currentFileSystem.NextFileSystem;
            }

            Labels = _csfFiles.SelectMany(x => x.Labels).ToList();
        }
Exemple #8
0
        public static uint GetAssetTypeId <T>(SageGame game) where T : BaseAsset
        {
            var type       = typeof(T);
            var attributes = type.GetCustomAttributes(typeof(AssetTypeIdOverrideAttribute), false);

            foreach (var attribute in attributes.Cast <AssetTypeIdOverrideAttribute>())
            {
                if (attribute.Game == game)
                {
                    return((uint)attribute.Type);
                }
            }
            return(AssetHash.GetHashCaseSensitive(type.Name));
        }
Exemple #9
0
        public static bool ShouldSkipFor(uint enumVal, SageGame game)
        {
            var type       = typeof(AssetType);
            var memInfo    = type.GetMember(((AssetType)enumVal).ToString());
            var attributes = memInfo[0].GetCustomAttributes(typeof(SkipParsingInAttribute), false);

            foreach (var attribute in attributes)
            {
                if (((SkipParsingInAttribute)attribute).Game == game)
                {
                    return(true);
                }
            }
            return(false);
        }
Exemple #10
0
        public static void Main(string[] args)
        {
            // TODO: Get this from a launch parameter.
            const SageGame sageGame = SageGame.CncGenerals;

            // TODO: Support other locators.
            var locator      = new RegistryInstallationLocator();
            var installation = locator.FindInstallations(sageGame).First();
            var fileSystem   = installation.CreateFileSystem();

            HostPlatform.Start();

            var game = new Game(
                HostPlatform.GraphicsDevice,
                HostPlatform.GraphicsDevice2D,
                fileSystem,
                sageGame);

            SetupInitialScene(game);

            var hostView = new GameView
            {
                Game = game,
                Dock = DockStyle.Fill
            };

            // TODO: Use something other than WinForms for cross-platform compatibility.
            var window = new Form
            {
                Size = new Size(1024, 768),
                // TODO: Read game version from assembly metadata or .git folder
                Text = "OpenSAGE (master)",
                Icon = GetIcon()
            };

            window.Controls.Add(hostView);
            window.Show();

            // TODO: This only works on Windows and DX11. Implement this for other platforms.
            RenderLoop.Run(hostView, game.Tick);

            HostPlatform.Stop();
        }
        public TranslationManager(FileSystem fileSystem, SageGame game)
        {
            FileSystemEntry csfEntry = null;

            switch (game)
            {
            case SageGame.CncGenerals:
                csfEntry = fileSystem.GetFile(@"Data\English\generals.csf");
                break;

            case SageGame.CncGeneralsZeroHour:
                break;

            case SageGame.BattleForMiddleEarth:
                csfEntry = fileSystem.GetFile(@"lotr.csf");
                break;

            case SageGame.BattleForMiddleEarthII:
                csfEntry = fileSystem.GetFile(@"lotr.csf");
                break;

            case SageGame.Cnc3:
                break;

            case SageGame.Cnc3KanesWrath:
                break;

            case SageGame.Ra3:
                break;

            case SageGame.Ra3Uprising:
                break;

            case SageGame.Cnc4:
                break;
            }

            if (csfEntry != null)
            {
                // TODO: Each game probably has its own path for this file.
                _csfFile = CsfFile.FromFileSystemEntry(csfEntry);
            }
        }
        public TranslationManager(FileSystem fileSystem, SageGame game, string language)
        {
            FileSystemEntry csfEntry = null;

            switch (game)
            {
            case SageGame.CncGenerals:
            case SageGame.CncGeneralsZeroHour:
                csfEntry = fileSystem.GetFile($@"Data\{language}\generals.csf");
                break;

            case SageGame.Bfme:
            case SageGame.Bfme2:
            case SageGame.Bfme2Rotwk:
                csfEntry = fileSystem.GetFile(@"lotr.csf");
                break;

            case SageGame.Cnc3:
                break;

            case SageGame.Cnc3KanesWrath:
                break;

            case SageGame.Ra3:
                break;

            case SageGame.Ra3Uprising:
                break;

            case SageGame.Cnc4:
                break;
            }

            if (csfEntry != null)
            {
                // TODO: Each game probably has its own path for this file.
                _csfFile = CsfFile.FromFileSystemEntry(csfEntry);
            }
        }
 public GameInstallation(SageGame game, string path, string secondaryPath = null)
 {
     Game          = game;
     Path          = path;
     SecondaryPath = secondaryPath;
 }
Exemple #14
0
 public GameFactAttribute(SageGame game, params SageGame[] otherGames)
 {
     Games = new[] { game }.Union(otherGames).ToArray();
 }
        public static string GetInstallationDirectory(SageGame game)
        {
            var definition = GameDefinition.FromGame(game);

            return(InstallationLocators.FindAllInstallations(definition).First().Path);
        }
Exemple #16
0
 public IniDataContext(FileSystem fileSystem, SageGame game)
 {
     _fileSystem = fileSystem;
     _game       = game;
 }
Exemple #17
0
        public ContentManager(
            Game game,
            FileSystem fileSystem,
            GraphicsDevice graphicsDevice,
            SageGame sageGame,
            WndCallbackResolver wndCallbackResolver)
        {
            using (GameTrace.TraceDurationEvent("ContentManager()"))
            {
                _game       = game;
                _fileSystem = fileSystem;

                GraphicsDevice = graphicsDevice;

                SageGame = sageGame;

                Language = LanguageUtility.ReadCurrentLanguage(game.Definition, fileSystem.RootDirectory);

                IniDataContext = new IniDataContext(fileSystem, sageGame);

                DataContext = new DataContext();

                SubsystemLoader = Content.SubsystemLoader.Create(game.Definition, _fileSystem, IniDataContext);

                switch (sageGame)
                {
                // Only load these INI files for a subset of games, because we can't parse them for others yet.
                case SageGame.CncGenerals:
                case SageGame.CncGeneralsZeroHour:
                case SageGame.Bfme:
                case SageGame.Bfme2:
                case SageGame.Bfme2Rotwk:
                    SubsystemLoader.Load(Subsystem.Core);

                    // TODO: Move this somewhere else.
                    // Subsystem.Core should load mouse and water config, but that isn't the case with at least BFME2.
                    IniDataContext.LoadIniFile(@"Data\INI\Mouse.ini");
                    IniDataContext.LoadIniFile(@"Data\INI\Water.ini");
                    IniDataContext.LoadIniFile(@"Data\INI\AudioSettings.ini");

                    break;

                default:
                    break;
                }

                // TODO: Defer subsystem loading until necessary
                switch (sageGame)
                {
                // Only load these INI files for a subset of games, because we can't parse them for others yet.
                case SageGame.CncGenerals:
                case SageGame.CncGeneralsZeroHour:
                case SageGame.Bfme:
                case SageGame.Bfme2:
                case SageGame.Bfme2Rotwk:
                    SubsystemLoader.Load(Subsystem.Players);
                    SubsystemLoader.Load(Subsystem.ParticleSystems);
                    SubsystemLoader.Load(Subsystem.ObjectCreation);
                    SubsystemLoader.Load(Subsystem.Multiplayer);
                    SubsystemLoader.Load(Subsystem.LinearCampaign);
                    break;

                default:
                    break;
                }

                _contentLoaders = new Dictionary <Type, ContentLoader>
                {
                    { typeof(Model), AddDisposable(new ModelLoader()) },
                    { typeof(Scene3D), AddDisposable(new MapLoader()) },
                    { typeof(Texture), AddDisposable(new TextureLoader(graphicsDevice)) },
                    { typeof(Window), AddDisposable(new WindowLoader(this, wndCallbackResolver, Language)) },
                    { typeof(AptWindow), AddDisposable(new AptLoader()) },
                };

                _cachedObjects = new Dictionary <string, object>();

                TranslationManager = Translation.TranslationManager.Instance;
                Translation.TranslationManager.LoadGameStrings(fileSystem, Language, sageGame);

                _cachedFonts = new Dictionary <FontKey, Font>();

                var linearClampSamplerDescription = SamplerDescription.Linear;
                linearClampSamplerDescription.AddressModeU = SamplerAddressMode.Clamp;
                linearClampSamplerDescription.AddressModeV = SamplerAddressMode.Clamp;
                linearClampSamplerDescription.AddressModeW = SamplerAddressMode.Clamp;
                LinearClampSampler = AddDisposable(
                    graphicsDevice.ResourceFactory.CreateSampler(ref linearClampSamplerDescription));

                var pointClampSamplerDescription = SamplerDescription.Point;
                pointClampSamplerDescription.AddressModeU = SamplerAddressMode.Clamp;
                pointClampSamplerDescription.AddressModeV = SamplerAddressMode.Clamp;
                pointClampSamplerDescription.AddressModeW = SamplerAddressMode.Clamp;
                PointClampSampler = AddDisposable(
                    graphicsDevice.ResourceFactory.CreateSampler(ref pointClampSamplerDescription));

                NullTexture = AddDisposable(graphicsDevice.ResourceFactory.CreateTexture(TextureDescription.Texture2D(1, 1, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Sampled)));

                _cachedNullStructuredBuffers = new Dictionary <uint, DeviceBuffer>();

                SolidWhiteTexture = AddDisposable(graphicsDevice.CreateStaticTexture2D(
                                                      1, 1, 1,
                                                      new TextureMipMapData(
                                                          new byte[] { 255, 255, 255, 255 },
                                                          4, 4, 1, 1),
                                                      PixelFormat.R8_G8_B8_A8_UNorm));

                ShaderResources = AddDisposable(new ShaderResourceManager(graphicsDevice, SolidWhiteTexture));

                WndImageLoader = AddDisposable(new WndImageLoader(this, new MappedImageLoader(this)));

                _fallbackFonts = new FontCollection();
                var assembly   = Assembly.GetExecutingAssembly();
                var fontStream = assembly.GetManifestResourceStream($"OpenSage.Content.Fonts.{_fallbackEmbeddedFont}-Regular.ttf");
                _fallbackFonts.Install(fontStream);
                fontStream = assembly.GetManifestResourceStream($"OpenSage.Content.Fonts.{_fallbackEmbeddedFont}-Bold.ttf");
                _fallbackFonts.Install(fontStream);
            }
        }
Exemple #18
0
 public static IGameDefinition FromGame(SageGame game) => Games[game];
Exemple #19
0
 public CsfTranslationProvider(Stream stream, SageGame game)
 {
     Debug.Assert(!(stream is null), $"{nameof(stream)} is null");
     _csf = new Csf();
     Csf.ReadCsf(_csf, stream, game);
 }
Exemple #20
0
 public AddedInAttribute(SageGame game)
 {
     Game = game;
 }
 public static string GetInstallationDirectory(SageGame game) => Locator.FindInstallations(game).First().Path;
Exemple #22
0
        public ContentManager(
            Game game,
            FileSystem fileSystem,
            GraphicsDevice graphicsDevice,
            SageGame sageGame)
        {
            using (GameTrace.TraceDurationEvent("ContentManager()"))
            {
                _game = game;

                FileSystem = fileSystem;

                GraphicsDevice = graphicsDevice;

                SageGame = sageGame;

                Language = LanguageUtility.ReadCurrentLanguage(game.Definition, fileSystem);

                TranslationManager = Translation.TranslationManager.Instance;
                Translation.TranslationManager.LoadGameStrings(fileSystem, Language, game.Definition);
                LocaleSpecificEncoding = Encoding.GetEncoding(TranslationManager.CurrentLanguage.TextInfo.ANSICodePage);

                void OnLanguageChanged(object sender, EventArgs e)
                {
                    //throw new NotImplementedException("Encoding change on LanguageChanged not implemented yet");
                }

                TranslationManager.LanguageChanged += OnLanguageChanged;
                AddDisposeAction(() => TranslationManager.LanguageChanged -= OnLanguageChanged);

                IniDataContext = new IniDataContext();

                SubsystemLoader = Content.SubsystemLoader.Create(game.Definition, FileSystem, game, this);

                switch (sageGame)
                {
                // Only load these INI files for a subset of games, because we can't parse them for others yet.
                // TODO: Defer subsystem loading until necessary
                case SageGame.CncGenerals:
                case SageGame.CncGeneralsZeroHour:
                    SubsystemLoader.Load(Subsystem.Core);
                    SubsystemLoader.Load(Subsystem.Audio);
                    SubsystemLoader.Load(Subsystem.Players);
                    SubsystemLoader.Load(Subsystem.ParticleSystems);
                    SubsystemLoader.Load(Subsystem.ObjectCreation);
                    SubsystemLoader.Load(Subsystem.Locomotors);
                    SubsystemLoader.Load(Subsystem.Sciences);
                    SubsystemLoader.Load(Subsystem.Weapons);
                    SubsystemLoader.Load(Subsystem.FXList);
                    SubsystemLoader.Load(Subsystem.Multiplayer);
                    SubsystemLoader.Load(Subsystem.LinearCampaign);
                    SubsystemLoader.Load(Subsystem.Wnd);
                    SubsystemLoader.Load(Subsystem.Terrain);
                    SubsystemLoader.Load(Subsystem.Credits);
                    SubsystemLoader.Load(Subsystem.Damage);
                    SubsystemLoader.Load(Subsystem.SpecialPower);
                    SubsystemLoader.Load(Subsystem.InGameUI);
                    SubsystemLoader.Load(Subsystem.Rank);
                    SubsystemLoader.Load(Subsystem.Animation2D);
                    break;

                case SageGame.Bfme:
                case SageGame.Bfme2:
                case SageGame.Bfme2Rotwk:
                    SubsystemLoader.Load(Subsystem.Core);
                    SubsystemLoader.Load(Subsystem.Audio);
                    SubsystemLoader.Load(Subsystem.Players);
                    SubsystemLoader.Load(Subsystem.ParticleSystems);
                    SubsystemLoader.Load(Subsystem.ObjectCreation);
                    SubsystemLoader.Load(Subsystem.Locomotors);
                    SubsystemLoader.Load(Subsystem.Sciences);
                    SubsystemLoader.Load(Subsystem.Weapons);
                    SubsystemLoader.Load(Subsystem.FXList);
                    SubsystemLoader.Load(Subsystem.Multiplayer);
                    SubsystemLoader.Load(Subsystem.LinearCampaign);
                    SubsystemLoader.Load(Subsystem.Wnd);
                    SubsystemLoader.Load(Subsystem.Terrain);
                    SubsystemLoader.Load(Subsystem.Credits);
                    SubsystemLoader.Load(Subsystem.Damage);
                    SubsystemLoader.Load(Subsystem.SpecialPower);
                    SubsystemLoader.Load(Subsystem.InGameUI);
                    SubsystemLoader.Load(Subsystem.Rank);
                    SubsystemLoader.Load(Subsystem.Animation2D);

                    SubsystemLoader.Load(Subsystem.ExperienceLevels);
                    SubsystemLoader.Load(Subsystem.AttributeModifiers);
                    break;

                case SageGame.Cnc3:
                case SageGame.Ra3:
                    SubsystemLoader.Load(Subsystem.Core);
                    break;

                default:
                    break;
                }

                UpgradeManager.Initialize(_game.AssetStore);

                FontManager = new FontManager(Language, StringComparer.Create(TranslationManager.CurrentLanguage, true));
            }
        }
Exemple #23
0
        public ContentManager(
            Game game,
            FileSystem fileSystem,
            GraphicsDevice graphicsDevice,
            SageGame sageGame,
            WndCallbackResolver wndCallbackResolver)
        {
            _game       = game;
            _fileSystem = fileSystem;

            GraphicsDevice = graphicsDevice;

            SageGame = sageGame;

            string language = LanguageUtility.ReadCurrentLanguage(game.Definition, fileSystem.RootDirectory);

            IniDataContext = new IniDataContext(fileSystem);

            IniDataContext.LoadIniFiles(@"Data\INI\Default\Object.ini");
            IniDataContext.LoadIniFiles(@"Data\INI\Object");
            IniDataContext.LoadIniFiles(@"Data\INI\multiplayer.ini");
            IniDataContext.LoadIniFile(@"Data\INI\PlayerTemplate.ini");

            IniDataContext.LoadIniFile(@"maps\MapCache.ini");

            _contentLoaders = new Dictionary <Type, ContentLoader>
            {
                { typeof(Model), AddDisposable(new ModelLoader()) },
                { typeof(Scene3D), AddDisposable(new MapLoader()) },
                { typeof(Texture), AddDisposable(new TextureLoader(graphicsDevice)) },
                { typeof(Window), AddDisposable(new WindowLoader(this, wndCallbackResolver, language)) },
                { typeof(AptWindow), AddDisposable(new AptLoader()) },
                { typeof(WavFile), AddDisposable(new WavLoader()) },
            };

            _cachedObjects = new Dictionary <string, object>();

            EffectLibrary = AddDisposable(new EffectLibrary(graphicsDevice));

            TranslationManager = new TranslationManager(fileSystem, sageGame, language);

            _cachedFonts = new Dictionary <FontKey, Font>();

            var linearClampSamplerDescription = SamplerDescription.Linear;

            linearClampSamplerDescription.AddressModeU = SamplerAddressMode.Clamp;
            linearClampSamplerDescription.AddressModeV = SamplerAddressMode.Clamp;
            linearClampSamplerDescription.AddressModeW = SamplerAddressMode.Clamp;
            LinearClampSampler = AddDisposable(
                graphicsDevice.ResourceFactory.CreateSampler(ref linearClampSamplerDescription));

            var pointClampSamplerDescription = SamplerDescription.Point;

            pointClampSamplerDescription.AddressModeU = SamplerAddressMode.Clamp;
            pointClampSamplerDescription.AddressModeV = SamplerAddressMode.Clamp;
            pointClampSamplerDescription.AddressModeW = SamplerAddressMode.Clamp;
            PointClampSampler = AddDisposable(
                graphicsDevice.ResourceFactory.CreateSampler(ref pointClampSamplerDescription));

            NullTexture = AddDisposable(graphicsDevice.ResourceFactory.CreateTexture(TextureDescription.Texture2D(1, 1, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Sampled)));

            _cachedNullStructuredBuffers = new Dictionary <uint, DeviceBuffer>();

            SolidWhiteTexture = AddDisposable(graphicsDevice.CreateStaticTexture2D(
                                                  1,
                                                  1,
                                                  new TextureMipMapData(
                                                      new byte[] { 255, 255, 255, 255 },
                                                      4, 4, 1, 1),
                                                  PixelFormat.R8_G8_B8_A8_UNorm));

            WndImageLoader = AddDisposable(new WndImageLoader(this, new MappedImageLoader(this)));

            _fallbackFonts = new FontCollection();
            var assembly   = Assembly.GetExecutingAssembly();
            var fontStream = assembly.GetManifestResourceStream($"OpenSage.Content.Fonts.{_fallbackEmbeddedFont}-Regular.ttf");

            _fallbackFonts.Install(fontStream);
            fontStream = assembly.GetManifestResourceStream($"OpenSage.Content.Fonts.{_fallbackEmbeddedFont}-Bold.ttf");
            _fallbackFonts.Install(fontStream);
        }
        public static GameInstallation GetInstallation(SageGame game)
        {
            var definition = GameDefinition.FromGame(game);

            return(InstallationLocators.FindAllInstallations(definition).First());
        }
 public static string GetInstallationDirectory(SageGame game)
 {
     return(GetInstallation(game).Path);
 }
Exemple #26
0
        internal AssetStore(
            SageGame sageGame,
            FileSystem fileSystem,
            string language,
            GraphicsDevice graphicsDevice,
            StandardGraphicsResources standardGraphicsResources,
            ShaderResourceManager shaderResources,
            OnDemandAssetLoadStrategy loadStrategy)
        {
            LoadContext = new AssetLoadContext(
                fileSystem,
                language,
                graphicsDevice,
                standardGraphicsResources,
                shaderResources,
                this);

            _scopedSingleAssetStorage   = new List <IScopedSingleAssetStorage>();
            _singleAssetStorageByTypeId = new Dictionary <uint, IScopedSingleAssetStorage>();

            void AddSingleAssetStorage <TAsset>(ScopedSingleAsset <TAsset> assetStorage)
                where TAsset : BaseSingletonAsset, new()
            {
                _scopedSingleAssetStorage.Add(assetStorage);

                var typeId = AssetTypeUtility.GetAssetTypeId <TAsset>(sageGame);

                _singleAssetStorageByTypeId.Add(typeId, assetStorage);
            }

            AddSingleAssetStorage(AIData = new ScopedSingleAsset <AIData>());
            AddSingleAssetStorage(AnimationSoundClientBehaviorGlobalSetting = new ScopedSingleAsset <AnimationSoundClientBehaviorGlobalSetting>());
            AddSingleAssetStorage(AptButtonTooltipMap    = new ScopedSingleAsset <AptButtonTooltipMap>());
            AddSingleAssetStorage(ArmySummaryDescription = new ScopedSingleAsset <ArmySummaryDescription>());
            AddSingleAssetStorage(AudioSettings          = new ScopedSingleAsset <AudioSettings>());
            AddSingleAssetStorage(AwardSystem            = new ScopedSingleAsset <AwardSystem>());
            AddSingleAssetStorage(BannerUI          = new ScopedSingleAsset <BannerUI>());
            AddSingleAssetStorage(ChallengeGenerals = new ScopedSingleAsset <ChallengeGenerals>());
            AddSingleAssetStorage(CreateAHeroSystem = new ScopedSingleAsset <CreateAHeroSystem>());
            AddSingleAssetStorage(Credits           = new ScopedSingleAsset <Credits>());
            AddSingleAssetStorage(DrawGroupInfo     = new ScopedSingleAsset <DrawGroupInfo>());
            AddSingleAssetStorage(Environment       = new ScopedSingleAsset <Environment>());
            AddSingleAssetStorage(Fire                                            = new ScopedSingleAsset <Fire>());
            AddSingleAssetStorage(FireLogicSystem                                 = new ScopedSingleAsset <FireLogicSystem>());
            AddSingleAssetStorage(FormationAssistant                              = new ScopedSingleAsset <FormationAssistant>());
            AddSingleAssetStorage(GameData                                        = new ScopedSingleAsset <GameData>());
            AddSingleAssetStorage(InGameNotificationBox                           = new ScopedSingleAsset <InGameNotificationBox>());
            AddSingleAssetStorage(InGameUI                                        = new ScopedSingleAsset <InGameUI>());
            AddSingleAssetStorage(Language                                        = new ScopedSingleAsset <Language>());
            AddSingleAssetStorage(LinearCampaign                                  = new ScopedSingleAsset <LinearCampaign>());
            AddSingleAssetStorage(LargeGroupAudioUnusedKnownKeys                  = new ScopedSingleAsset <LargeGroupAudioUnusedKnownKeys>());
            AddSingleAssetStorage(LivingWorldMapInfo                              = new ScopedSingleAsset <LivingWorldMapInfo>());
            AddSingleAssetStorage(LivingWorldAutoResolveResourceBonus             = new ScopedSingleAsset <LivingWorldAutoResolveResourceBonus>());
            AddSingleAssetStorage(LivingWorldAutoResolveSciencePurchasePointBonus = new ScopedSingleAsset <LivingWorldAutoResolveSciencePurchasePointBonus>());
            AddSingleAssetStorage(MiscAudio                                       = new ScopedSingleAsset <MiscAudio>());
            AddSingleAssetStorage(MiscEvaData                                     = new ScopedSingleAsset <MiscEvaData>());
            AddSingleAssetStorage(MissionObjectiveList                            = new ScopedSingleAsset <MissionObjectiveList>());
            AddSingleAssetStorage(MouseData                                       = new ScopedSingleAsset <MouseData>());
            AddSingleAssetStorage(MultiplayerSettings                             = new ScopedSingleAsset <MultiplayerSettings>());
            AddSingleAssetStorage(OnlineChatColors                                = new ScopedSingleAsset <OnlineChatColors>());
            AddSingleAssetStorage(Pathfinder                                      = new ScopedSingleAsset <Pathfinder>());
            AddSingleAssetStorage(StrategicHud                                    = new ScopedSingleAsset <StrategicHud>());
            AddSingleAssetStorage(WaterTransparency                               = new ScopedSingleAsset <WaterTransparency>());
            AddSingleAssetStorage(Weather                                         = new ScopedSingleAsset <Weather>());

            _scopedAssetCollections = new List <IScopedAssetCollection>();
            _byTypeId = new Dictionary <uint, IScopedAssetCollection>();

            void AddAssetCollection <TAsset>(ScopedAssetCollection <TAsset> assetCollection)
                where TAsset : BaseAsset
            {
                _scopedAssetCollections.Add(assetCollection);

                var typeId = AssetTypeUtility.GetAssetTypeId <TAsset>(sageGame);

                _byTypeId.Add(typeId, assetCollection);
            }

            AddAssetCollection(AIBases                           = new ScopedAssetCollection <AIBase>(this));
            AddAssetCollection(AIDozerAssignments                = new ScopedAssetCollection <AIDozerAssignment>(this));
            AddAssetCollection(AmbientStreams                    = new ScopedAssetCollection <AmbientStream>(this));
            AddAssetCollection(Animations                        = new ScopedAssetCollection <Animation>(this));
            AddAssetCollection(ArmorTemplates                    = new ScopedAssetCollection <ArmorTemplate>(this));
            AddAssetCollection(ArmyDefinitions                   = new ScopedAssetCollection <ArmyDefinition>(this));
            AddAssetCollection(AudioEvents                       = new ScopedAssetCollection <AudioEvent>(this));
            AddAssetCollection(AudioFiles                        = new ScopedAssetCollection <AudioFile>(this, loadStrategy.CreateAudioFileLoader()));
            AddAssetCollection(AudioLods                         = new ScopedAssetCollection <AudioLod>(this));
            AddAssetCollection(AutoResolveArmors                 = new ScopedAssetCollection <AutoResolveArmor>(this));
            AddAssetCollection(AutoResolveBodies                 = new ScopedAssetCollection <AutoResolveBody>(this));
            AddAssetCollection(AutoResolveCombatChains           = new ScopedAssetCollection <AutoResolveCombatChain>(this));
            AddAssetCollection(AutoResolveHandicapLevels         = new ScopedAssetCollection <AutoResolveHandicapLevel>(this));
            AddAssetCollection(AutoResolveLeaderships            = new ScopedAssetCollection <AutoResolveLeadership>(this));
            AddAssetCollection(AutoResolveReinforcementSchedules = new ScopedAssetCollection <AutoResolveReinforcementSchedule>(this));
            AddAssetCollection(AutoResolveWeapons                = new ScopedAssetCollection <AutoResolveWeapon>(this));
            AddAssetCollection(BannerTypes                       = new ScopedAssetCollection <BannerType>(this));
            AddAssetCollection(BenchProfiles                     = new ScopedAssetCollection <BenchProfile>(this));
            AddAssetCollection(BridgeTemplates                   = new ScopedAssetCollection <BridgeTemplate>(this));
            AddAssetCollection(CampaignTemplates                 = new ScopedAssetCollection <CampaignTemplate>(this));
            AddAssetCollection(CommandButtons                    = new ScopedAssetCollection <CommandButton>(this));
            AddAssetCollection(CommandMaps                       = new ScopedAssetCollection <CommandMap>(this));
            AddAssetCollection(CommandSets                       = new ScopedAssetCollection <CommandSet>(this));
            AddAssetCollection(ControlBarResizers                = new ScopedAssetCollection <ControlBarResizer>(this));
            AddAssetCollection(ControlBarSchemes                 = new ScopedAssetCollection <ControlBarScheme>(this));
            AddAssetCollection(CrateDatas                        = new ScopedAssetCollection <CrateData>(this));
            AddAssetCollection(CrowdResponses                    = new ScopedAssetCollection <CrowdResponse>(this));
            AddAssetCollection(DamageFXs                         = new ScopedAssetCollection <DamageFX>(this));
            AddAssetCollection(DialogEvents                      = new ScopedAssetCollection <DialogEvent>(this));
            AddAssetCollection(DynamicGameLods                   = new ScopedAssetCollection <DynamicGameLod>(this));
            AddAssetCollection(EmotionNuggets                    = new ScopedAssetCollection <EmotionNugget>(this));
            AddAssetCollection(EvaEvents                         = new ScopedAssetCollection <EvaEvent>(this));
            AddAssetCollection(ExperienceLevels                  = new ScopedAssetCollection <ExperienceLevel>(this));
            AddAssetCollection(ExperienceScalarTables            = new ScopedAssetCollection <ExperienceScalarTable>(this));
            AddAssetCollection(FactionVictoryDatas               = new ScopedAssetCollection <FactionVictoryData>(this));
            AddAssetCollection(FontDefaultSettings               = new ScopedAssetCollection <FontDefaultSetting>(this));
            AddAssetCollection(FontSubstitutions                 = new ScopedAssetCollection <FontSubstitution>(this));
            AddAssetCollection(FXLists                           = new ScopedAssetCollection <FXList>(this));
            AddAssetCollection(FXParticleSystemTemplates         = new ScopedAssetCollection <FXParticleSystemTemplate>(this));
            AddAssetCollection(GuiTextures                       = new ScopedAssetCollection <GuiTextureAsset>(this, loadStrategy.CreateGuiTextureLoader()));
            AddAssetCollection(HeaderTemplates                   = new ScopedAssetCollection <HeaderTemplate>(this));
            AddAssetCollection(HouseColors                       = new ScopedAssetCollection <HouseColor>(this));
            AddAssetCollection(LargeGroupAudioMaps               = new ScopedAssetCollection <LargeGroupAudioMap>(this));
            AddAssetCollection(LivingWorldAITemplates            = new ScopedAssetCollection <LivingWorldAITemplate>(this));
            AddAssetCollection(LivingWorldAnimObjects            = new ScopedAssetCollection <LivingWorldAnimObject>(this));
            AddAssetCollection(LivingWorldArmyIcons              = new ScopedAssetCollection <LivingWorldArmyIcon>(this));
            AddAssetCollection(LivingWorldBuildings              = new ScopedAssetCollection <LivingWorldBuilding>(this));
            AddAssetCollection(LivingWorldBuildingIcons          = new ScopedAssetCollection <LivingWorldBuildingIcon>(this));
            AddAssetCollection(LivingWorldBuildPlotIcons         = new ScopedAssetCollection <LivingWorldBuildPlotIcon>(this));
            AddAssetCollection(LivingWorldCampaigns              = new ScopedAssetCollection <LivingWorldCampaign>(this));
            AddAssetCollection(LivingWorldObjects                = new ScopedAssetCollection <LivingWorldObject>(this));
            AddAssetCollection(LivingWorldPlayerArmies           = new ScopedAssetCollection <LivingWorldPlayerArmy>(this));
            AddAssetCollection(LivingWorldPlayerTemplates        = new ScopedAssetCollection <LivingWorldPlayerTemplate>(this));
            AddAssetCollection(LivingWorldRegionCampaigns        = new ScopedAssetCollection <LivingWorldRegionCampaign>(this));
            AddAssetCollection(LivingWorldRegionEffects          = new ScopedAssetCollection <LivingWorldRegionEffects>(this));
            AddAssetCollection(LivingWorldSounds                 = new ScopedAssetCollection <LivingWorldSound>(this));
            AddAssetCollection(LocomotorTemplates                = new ScopedAssetCollection <LocomotorTemplate>(this));
            AddAssetCollection(LodPresets                        = new ScopedAssetCollection <LodPreset>(this));
            AddAssetCollection(MapCaches                         = new ScopedAssetCollection <MapCache>(this));
            AddAssetCollection(MappedImages                      = new ScopedAssetCollection <MappedImage>(this));
            AddAssetCollection(MeshNameMatches                   = new ScopedAssetCollection <MeshNameMatches>(this));
            AddAssetCollection(Models                          = new ScopedAssetCollection <Model>(this, loadStrategy.CreateModelLoader()));
            AddAssetCollection(ModelAnimations                 = new ScopedAssetCollection <Graphics.Animation.W3DAnimation>(this, loadStrategy.CreateAnimationLoader()));
            AddAssetCollection(ModelBoneHierarchies            = new ScopedAssetCollection <ModelBoneHierarchy>(this, loadStrategy.CreateModelBoneHierarchyLoader()));
            AddAssetCollection(ModelMeshes                     = new ScopedAssetCollection <ModelMesh>(this)); // TODO: ModelMesh loader?
            AddAssetCollection(ModifierLists                   = new ScopedAssetCollection <ModifierList>(this));
            AddAssetCollection(MouseCursors                    = new ScopedAssetCollection <MouseCursor>(this));
            AddAssetCollection(MultiplayerColors               = new ScopedAssetCollection <MultiplayerColor>(this));
            AddAssetCollection(MultiplayerStartingMoneyChoices = new ScopedAssetCollection <MultiplayerStartingMoneyChoice>(this));
            AddAssetCollection(Multisounds                     = new ScopedAssetCollection <Multisound>(this));
            AddAssetCollection(MusicTracks                     = new ScopedAssetCollection <MusicTrack>(this));
            AddAssetCollection(ObjectCreationLists             = new ScopedAssetCollection <ObjectCreationList>(this));
            AddAssetCollection(ObjectDefinitions               = new ScopedAssetCollection <ObjectDefinition>(this));
            AddAssetCollection(PlayerAITypes                   = new ScopedAssetCollection <PlayerAIType>(this));
            AddAssetCollection(PlayerTemplates                 = new ScopedAssetCollection <PlayerTemplate>(this));
            AddAssetCollection(Ranks                   = new ScopedAssetCollection <RankTemplate>(this));
            AddAssetCollection(RegionCampaigns         = new ScopedAssetCollection <RegionCampaign>(this));
            AddAssetCollection(RoadTemplates           = new ScopedAssetCollection <RoadTemplate>(this));
            AddAssetCollection(Sciences                = new ScopedAssetCollection <Science>(this));
            AddAssetCollection(ScoredKillEvaAnnouncers = new ScopedAssetCollection <ScoredKillEvaAnnouncer>(this));
            AddAssetCollection(ShellMenuSchemes        = new ScopedAssetCollection <ShellMenuScheme>(this));
            AddAssetCollection(SkirmishAIDatas         = new ScopedAssetCollection <SkirmishAIData>(this));
            AddAssetCollection(SkyboxTextureSets       = new ScopedAssetCollection <SkyboxTextureSet>(this));
            AddAssetCollection(SpecialPowers           = new ScopedAssetCollection <SpecialPower>(this));
            AddAssetCollection(StanceTemplates         = new ScopedAssetCollection <StanceTemplate>(this));
            AddAssetCollection(StaticGameLods          = new ScopedAssetCollection <StaticGameLod>(this));
            AddAssetCollection(StreamedSounds          = new ScopedAssetCollection <StreamedSound>(this));
            AddAssetCollection(Subsystems              = new ScopedAssetCollection <LoadSubsystem>(this));
            AddAssetCollection(TerrainTextures         = new ScopedAssetCollection <TerrainTexture>(this));
            AddAssetCollection(Textures                = new ScopedAssetCollection <TextureAsset>(this, loadStrategy.CreateTextureLoader()));
            AddAssetCollection(Upgrades                = new ScopedAssetCollection <UpgradeTemplate>(this));
            AddAssetCollection(VictorySystemDatas      = new ScopedAssetCollection <VictorySystemData>(this));
            AddAssetCollection(Videos                  = new ScopedAssetCollection <Video>(this));
            AddAssetCollection(WaterSets               = new ScopedAssetCollection <WaterSet>(this));
            AddAssetCollection(WaterTextureLists       = new ScopedAssetCollection <WaterTextureList>(this));
            AddAssetCollection(WeaponTemplates         = new ScopedAssetCollection <WeaponTemplate>(this));
            AddAssetCollection(WeatherDatas            = new ScopedAssetCollection <WeatherData>(this));
            AddAssetCollection(WindowTransitions       = new ScopedAssetCollection <WindowTransition>(this));
        }
Exemple #27
0
            public static void ReadCsf(Csf csf, Stream stream, SageGame game)
            {
                using (var reader = new BinaryReader(stream, Encoding.ASCII, true))
                {
                    var magic = reader.ReadInt32();
                    if (magic != _magicCsf)
                    {
                        throw new InvalidDataException("Error parsing csf (Magic: CSF expected).");
                    }
                    var version    = reader.ReadInt32();
                    var numLabels  = reader.ReadInt32();
                    var numStrings = reader.ReadInt32();
                    if (numLabels != numStrings)
                    {
                        // throw new NotSupportedException("Csf substrings are not supported.");
                        logger.Warn("[CSF] Number of labels and strings mismatch.");
                    }
                    csf._numStrings = numStrings;
                    reader.ReadUInt32(); // reserved
                    var    languageCode = reader.ReadUInt32();
                    string language;
                    switch (game)
                    {
                    case SageGame.CncGenerals:
                    case SageGame.CncGeneralsZeroHour:
                        language = ((LanguageGenerals)languageCode).GetName();
                        break;

                    case SageGame.Bfme:
                    case SageGame.Bfme2:
                    case SageGame.Bfme2Rotwk:
                        language = ((LanguageBFME)languageCode).GetName();
                        break;

                    case SageGame.Cnc3:
                    case SageGame.Cnc3KanesWrath:
                        language = ((LanguageCnC3)languageCode).GetName();
                        break;

                    default:
                        language = "en-US";
                        break;
                    }
                    if (language is null)
                    {
                        language = "en-US";
                        logger.Warn($"Unknown language id {languageCode} for game {game}.");
                    }
                    csf._language = language;
                    string label;
                    int    strCount;
                    string str;
                    int    colonIdx;
                    string categoryLabel;
                    for (var idx = 0; idx < numLabels; ++idx)
                    {
                        magic = reader.ReadInt32();
                        if (magic != _magicLabel)
                        {
                            throw new InvalidDataException("Error parsing csf (Magic: LBL expected).");
                        }
                        strCount = reader.ReadInt32();
                        label    = reader.ReadUInt32PrefixedAsciiString();
                        for (var idy = 0; idy < strCount; ++idy)
                        {
                            magic = reader.ReadInt32();
                            if (magic != _magicLString && magic != _magicLWideString)
                            {
                                throw new InvalidDataException("Error parsing csf (Magic: STR/STRW expected).");
                            }
                            if (idy == 0)
                            {
                                str = reader.ReadUInt32PrefixedNegatedUnicodeString();
                                if (magic == _magicLWideString)
                                {
                                    str += reader.ReadUInt32PrefixedAsciiString();
                                }
                                colonIdx = label.IndexOf(':');
                                if (colonIdx == -1)
                                {
                                    categoryLabel = string.Empty;
                                    logger.Warn($"Empty category found for {label}.");
                                }
                                else
                                {
                                    categoryLabel = label.Substring(0, colonIdx).ToUpperInvariant();
                                }
                                if (!csf._strings.TryGetValue(categoryLabel, out var category))
                                {
                                    category = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);
                                    csf._strings.Add(categoryLabel, category);
                                }
                                label = label.Substring(colonIdx + 1);
                                if (category.ContainsKey(label))
                                {
                                    logger.Warn($"[CSF] String duplication: '{categoryLabel}:{label}' -> '{category[label]}', new value: '{str}'");
                                }
                                else
                                {
                                    category.Add(label, str);
                                }
                            }
                            else
                            {
                                if (magic == _magicLString)
                                {
                                    logger.Info($"[CSF] Skipping substring '{reader.ReadUInt32PrefixedNegatedUnicodeString()}' from {label}.");
                                }
                                else
                                {
                                    logger.Info($"[CSF] Skipping substring '{reader.ReadUInt32PrefixedNegatedUnicodeString()}{reader.ReadUInt32PrefixedAsciiString()}' from {label}.");
                                }
                            }
                        }
                    }
                }
            }
Exemple #28
0
        public ContentManager(
            Game game,
            FileSystem fileSystem,
            GraphicsDevice graphicsDevice,
            SageGame sageGame)
        {
            using (GameTrace.TraceDurationEvent("ContentManager()"))
            {
                _game = game;

                FileSystem = fileSystem;

                GraphicsDevice = graphicsDevice;

                SageGame = sageGame;

                Language = LanguageUtility.ReadCurrentLanguage(game.Definition, fileSystem.RootDirectory);

                TranslationManager = Translation.TranslationManager.Instance;
                Translation.TranslationManager.LoadGameStrings(fileSystem, Language, sageGame);
                LocaleSpecificEncoding              = Encoding.GetEncoding(TranslationManager.CurrentLanguage.TextInfo.ANSICodePage);
                TranslationManager.LanguageChanged +=
                    (sender, e) => throw new NotImplementedException("Encoding change on LanguageChanged not implemented yet");

                IniDataContext = new IniDataContext();

                SubsystemLoader = Content.SubsystemLoader.Create(game.Definition, FileSystem, game, this);

                switch (sageGame)
                {
                // Only load these INI files for a subset of games, because we can't parse them for others yet.
                case SageGame.CncGenerals:
                case SageGame.CncGeneralsZeroHour:
                case SageGame.Bfme:
                case SageGame.Bfme2:
                case SageGame.Bfme2Rotwk:
                    SubsystemLoader.Load(Subsystem.Core);

                    // TODO: Defer subsystem loading until necessary
                    SubsystemLoader.Load(Subsystem.Audio);
                    SubsystemLoader.Load(Subsystem.Players);
                    SubsystemLoader.Load(Subsystem.ParticleSystems);
                    SubsystemLoader.Load(Subsystem.ObjectCreation);
                    SubsystemLoader.Load(Subsystem.Locomotors);
                    SubsystemLoader.Load(Subsystem.Weapons);
                    SubsystemLoader.Load(Subsystem.FXList);
                    SubsystemLoader.Load(Subsystem.Multiplayer);
                    SubsystemLoader.Load(Subsystem.LinearCampaign);
                    SubsystemLoader.Load(Subsystem.Wnd);
                    SubsystemLoader.Load(Subsystem.Terrain);
                    SubsystemLoader.Load(Subsystem.Credits);

                    break;

                case SageGame.Cnc3:
                    SubsystemLoader.Load(Subsystem.Core);
                    break;

                default:
                    break;
                }

                FontManager = new FontManager(Language, StringComparer.Create(TranslationManager.CurrentLanguage, true));
            }
        }
Exemple #29
0
        public ContentManager(
            Game game,
            FileSystem fileSystem,
            GraphicsDevice graphicsDevice,
            SageGame sageGame,
            WndCallbackResolver wndCallbackResolver)
        {
            _game       = game;
            _fileSystem = fileSystem;

            GraphicsDevice = graphicsDevice;

            SageGame = sageGame;

            IniDataContext = new IniDataContext(fileSystem);

            IniDataContext.LoadIniFiles(@"Data\INI\Default\Object.ini");
            IniDataContext.LoadIniFiles(@"Data\INI\Object");

            _contentLoaders = new Dictionary <Type, ContentLoader>
            {
                { typeof(Model), AddDisposable(new ModelLoader()) },
                { typeof(Scene3D), AddDisposable(new MapLoader()) },
                { typeof(Texture), AddDisposable(new TextureLoader(graphicsDevice)) },
                { typeof(Window), AddDisposable(new WindowLoader(this, wndCallbackResolver)) },
                { typeof(AptWindow), AddDisposable(new AptLoader()) },
                { typeof(WavFile), AddDisposable(new WavLoader()) },
            };

            _cachedObjects = new Dictionary <string, object>();

            EffectLibrary = AddDisposable(new EffectLibrary(graphicsDevice));

            TranslationManager = new TranslationManager(fileSystem, sageGame);

            _cachedFonts = new Dictionary <FontKey, Font>();

            var linearClampSamplerDescription = SamplerDescription.Linear;

            linearClampSamplerDescription.AddressModeU = SamplerAddressMode.Clamp;
            linearClampSamplerDescription.AddressModeV = SamplerAddressMode.Clamp;
            linearClampSamplerDescription.AddressModeW = SamplerAddressMode.Clamp;
            LinearClampSampler = AddDisposable(
                graphicsDevice.ResourceFactory.CreateSampler(ref linearClampSamplerDescription));

            var pointClampSamplerDescription = SamplerDescription.Point;

            pointClampSamplerDescription.AddressModeU = SamplerAddressMode.Clamp;
            pointClampSamplerDescription.AddressModeV = SamplerAddressMode.Clamp;
            pointClampSamplerDescription.AddressModeW = SamplerAddressMode.Clamp;
            PointClampSampler = AddDisposable(
                graphicsDevice.ResourceFactory.CreateSampler(ref pointClampSamplerDescription));

            NullTexture = AddDisposable(graphicsDevice.ResourceFactory.CreateTexture(TextureDescription.Texture2D(1, 1, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Sampled)));

            _cachedNullStructuredBuffers = new Dictionary <uint, DeviceBuffer>();

            SolidWhiteTexture = AddDisposable(graphicsDevice.CreateStaticTexture2D(
                                                  1,
                                                  1,
                                                  new TextureMipMapData(
                                                      new byte[] { 255, 255, 255, 255 },
                                                      4, 4, 1, 1),
                                                  PixelFormat.R8_G8_B8_A8_UNorm));

            WndImageLoader = AddDisposable(new WndImageLoader(this, new MappedImageLoader(this)));
        }