Example #1
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);

                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));
            }
        }
Example #2
0
        private void ChangeInstallation(GameInstallation installation)
        {
            _selectedInstallation = installation;

            _imGuiRenderer.ClearCachedImageResources();

            RemoveAndDispose(ref _contentView);
            _files = null;
            RemoveAndDispose(ref _game);
            RemoveAndDispose(ref _gamePanel);
            RemoveAndDispose(ref _fileSystem);
            RemoveAndDispose(ref _launcherImage);

            if (installation == null)
            {
                _files = new List <FileSystemEntry>();
                return;
            }

            _fileSystem = AddDisposable(installation.CreateFileSystem());

            var launcherImagePath = installation.Game.LauncherImagePath;

            if (launcherImagePath != null)
            {
                var prefixLang = installation.Game.LauncherImagePrefixLang;
                if (prefixLang)
                {
                    var lang = LanguageUtility.ReadCurrentLanguage(installation.Game, _fileSystem.RootDirectory);
                    launcherImagePath = lang + launcherImagePath;
                }

                var launcherImageEntry = _fileSystem.GetFile(launcherImagePath);

                if (launcherImageEntry != null)
                {
                    _launcherImage = AddDisposable(new ImageSharpTexture(launcherImageEntry.Open()).CreateDeviceTexture(
                                                       _gameWindow.GraphicsDevice, _gameWindow.GraphicsDevice.ResourceFactory));
                }
            }

            _files = _fileSystem.Files.OrderBy(x => x.FilePath).ToList();

            _currentFile = -1;

            _gamePanel = AddDisposable(new ImGuiGamePanel(_gameWindow));
            _gamePanel.EnsureFrame(new Mathematics.Rectangle(0, 0, 100, 100));

            _game = AddDisposable(GameFactory.CreateGame(
                                      installation,
                                      _fileSystem,
                                      _gamePanel));

            //InstallationChanged?.Invoke(this, new InstallationChangedEventArgs(installation, _fileSystem));
        }
Example #3
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);
            }
        }
Example #4
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));
            }
        }
Example #5
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));
            }
        }
Example #6
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);
        }
Example #7
0
        public void CanReadIniFiles()
        {
            var gameDefinitions = new[]
            {
                GameDefinition.FromGame(SageGame.CncGenerals),
                GameDefinition.FromGame(SageGame.CncGeneralsZeroHour),
                GameDefinition.FromGame(SageGame.Bfme),
                GameDefinition.FromGame(SageGame.Bfme2),
                GameDefinition.FromGame(SageGame.Bfme2Rotwk),
            };

            using var graphicsDevice = GraphicsDeviceUtility.CreateGraphicsDevice(null, null);

            using var standardGraphicsResources = new StandardGraphicsResources(graphicsDevice);
            using var shaderSetStore            = new ShaderSetStore(graphicsDevice, RenderPipeline.GameOutputDescription);
            using var shaderResources           = new ShaderResourceManager(graphicsDevice, standardGraphicsResources, shaderSetStore);
            var graphicsLoadContext = new GraphicsLoadContext(graphicsDevice, standardGraphicsResources, shaderResources, shaderSetStore);

            foreach (var gameDefinition in gameDefinitions)
            {
                foreach (var installation in InstallationLocators.FindAllInstallations(gameDefinition))
                {
                    using var fileSystem = installation.CreateFileSystem();

                    var assetStore = new AssetStore(
                        gameDefinition.Game,
                        fileSystem,
                        LanguageUtility.ReadCurrentLanguage(gameDefinition, fileSystem),
                        graphicsDevice,
                        standardGraphicsResources,
                        shaderResources,
                        shaderSetStore,
                        gameDefinition.CreateAssetLoadStrategy());

                    assetStore.PushScope();

                    var dataContext = new IniDataContext();

                    void LoadIniFile(FileSystemEntry entry)
                    {
                        var parser = new IniParser(
                            entry,
                            assetStore,
                            gameDefinition.Game,
                            dataContext,
                            LocaleSpecificEncoding);

                        parser.ParseFile();
                    }

                    switch (gameDefinition.Game)
                    {
                    case SageGame.Bfme:
                    case SageGame.Bfme2:
                    case SageGame.Bfme2Rotwk:
                        LoadIniFile(fileSystem.GetFile(@"Data\INI\GameData.ini"));
                        break;
                    }

                    foreach (var file in fileSystem.GetFilesInDirectory("", $"*.ini", SearchOption.AllDirectories))
                    {
                        var filename = Path.GetFileName(file.FilePath).ToLowerInvariant();

                        switch (filename)
                        {
                        case "webpages.ini":               // Don't care about this

                        case "buttonsets.ini":             // Doesn't seem to be used?
                        case "scripts.ini":                // Only needed by World Builder?
                        case "commandmapdebug.ini":        // Only applies to DEBUG and INTERNAL builds
                        case "fxparticlesystemcustom.ini": // Don't know if this is used, it uses Emitter property not used elsewhere
                        case "lightpoints.ini":            // Don't know if this is used.

                        //added in BFME and subsequent games
                        case "optionregistry.ini":   // Don't know if this is used
                        case "localization.ini":     // Don't know if we need this
                            continue;

                        case "credits.ini":
                            if (gameDefinition.Game == SageGame.Bfme2Rotwk)     //corrupted in rotwk (start of the block is commented out)
                            {
                                continue;
                            }
                            break;

                        //mods specific

                        //edain mod
                        case "einstellungen.ini":
                        case "einstellungendeakt.ini":
                        case "einstellungenedain.ini":
                        case "news.ini":
                            continue;

                        //unofficial patch 2.02
                        case "desktop.ini":     //got into a big file somehow
                        case "2.01.ini":
                        case "disable timer.ini":
                        case "enable timer.ini":
                        case "old music.ini":
                            continue;

                        default:
                            if (filename.StartsWith("2.02"))
                            {
                                continue;
                            }
                            break;
                        }

                        _output.WriteLine($"Reading file {file.FilePath}.");

                        LoadIniFile(file);
                    }
                }
            }
        }