Esempio n. 1
0
        public static void Main(string[] args)
        {
            var    noShellMap = false;
            var    definition = GameDefinition.FromGame(SageGame.CncGenerals);
            string mapName    = null;

            ArgumentSyntax.Parse(args, syntax =>
            {
                syntax.DefineOption("noshellmap", ref noShellMap, false, "Disables loading the shell map, speeding up startup time.");

                string gameName    = null;
                var availableGames = string.Join(", ", GameDefinition.All.Select(def => def.Game.ToString()));

                syntax.DefineOption("game", ref gameName, false, $"Chooses which game to start. Valid options: {availableGames}");

                // If a game has been specified, make sure it's valid.
                if (gameName != null && !GameDefinition.TryGetByName(gameName, out definition))
                {
                    syntax.ReportError($"Unknown game: {gameName}");
                }

                syntax.DefineOption("map", ref mapName, false,
                                    "Immediately starts a new skirmish with default settings in the specified map. The map file must be specified with the full path.");
            });

            Platform.CurrentPlatform = new Sdl2Platform();
            Platform.CurrentPlatform.Start();

            // TODO: Support other locators.
            var locator = new RegistryInstallationLocator();

            var game = GameFactory.CreateGame(
                definition,
                locator,
                // TODO: Read game version from assembly metadata or .git folder
                // TODO: Set window icon.
                () => Platform.CurrentPlatform.CreateWindow("OpenSAGE (master)", 100, 100, 1024, 768));

            game.Configuration.LoadShellMap = !noShellMap;

            if (mapName == null)
            {
                game.ShowMainMenu();
            }
            else
            {
                game.StartGame(mapName, new EchoConnection(), new[] { "America", "GLA" }, 0);
            }

            while (game.IsRunning)
            {
                game.Tick();
            }

            Platform.CurrentPlatform.Stop();
        }
Esempio n. 2
0
        public void CanReadIniFiles()
        {
            // TODO: Finish INI parsing for BFME and subsequent games.
            var gameDefinitions = new[]
            {
                GameDefinition.FromGame(SageGame.CncGenerals),
                GameDefinition.FromGame(SageGame.CncGeneralsZeroHour)
            };

            InstalledFilesTestData.ReadFiles(".ini", _output, gameDefinitions, entry =>
            {
                switch (Path.GetFileName(entry.FilePath).ToLowerInvariant())
                {
                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.
                    return;
                }

                var dataContext = new IniDataContext(entry.FileSystem);

                // BFME I and II need to have GameData.ini loaded before any other INI files,
                // because GameData.ini contains global macro definitions.
                if (entry.FilePath.ToLowerInvariant() != @"data\ini\gamedata.ini")
                {
                    dataContext.LoadIniFile(@"Data\INI\GameData.ini");
                }

                dataContext.LoadIniFile(entry);

                Assert.NotNull(dataContext.CommandMaps);

                foreach (var objectDefinition in dataContext.Objects)
                {
                    foreach (var draw in objectDefinition.Draws)
                    {
                        switch (draw)
                        {
                        case W3dModelDrawModuleData md:
                            //if (md.DefaultConditionState != null)
                            //{
                            //    Assert.True(md.DefaultConditionState.Animations.Count <= 1);
                            //}
                            //foreach (var conditionState in md.ConditionStates)
                            //{
                            //    Assert.True(conditionState.Animations.Count <= 1);
                            //}
                            break;
                        }
                    }
                }
            });
        }
Esempio n. 3
0
        public void CanReadIniFiles()
        {
            // TODO: Finish INI parsing for BFME2 and subsequent games.
            var gameDefinitions = new[]
            {
                GameDefinition.FromGame(SageGame.CncGenerals),
                GameDefinition.FromGame(SageGame.CncGeneralsZeroHour),
                GameDefinition.FromGame(SageGame.Bfme),
                //GameDefinition.FromGame(SageGame.Bfme2),
            };

            foreach (var gameDefinition in gameDefinitions)
            {
                InstalledFilesTestData.ReadFiles(".ini", _output, new List <IGameDefinition> {
                    gameDefinition
                }, entry =>
                {
                    switch (Path.GetFileName(entry.FilePath).ToLowerInvariant())
                    {
                    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.

                    //BFME
                    case "optionregistry.ini":   // Don't know if this is used
                    case "localization.ini":     // Don't know if we need this
                        return;
                    }

                    var dataContext = new IniDataContext(entry.FileSystem, gameDefinition.Game);

                    // BFME I and II need to have GameData.ini loaded before any other INI files,
                    // because GameData.ini contains global macro definitions.
                    if (entry.FilePath.ToLowerInvariant() != @"data\ini\gamedata.ini")
                    {
                        dataContext.LoadIniFile(@"Data\INI\GameData.ini");
                    }

                    dataContext.LoadIniFile(entry);
                });
            }
        }
Esempio n. 4
0
    private static void Run(Options opts)
    {
        Platform.Start();

        var definition   = GameDefinition.FromGame(opts.SageGame);
        var installation = InstallationLocators.FindAllInstallations(definition).First();
        var game         = new Game(installation);

        // Read .sav file from binary file.
        using var stream = File.OpenRead(opts.SaveFilePath);
        SaveFile.LoadFromStream(stream, game);

        // Write .sav file to JSON.
        var outputPath = Path.ChangeExtension(opts.SaveFilePath, ".json");

        using var jsonWriter = new JsonSaveWriter(game, outputPath);
        SaveFile.Persist(jsonWriter);

        game.EndGame();

        Platform.Stop();
    }
Esempio n. 5
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),
            };

            foreach (var gameDefinition in gameDefinitions)
            {
                var rootDirectories = InstallationLocators.FindAllInstallations(gameDefinition).Select(i => i.Path).ToList();

                foreach (var rootDirectory in rootDirectories)
                {
                    using (var fileSystem = new FileSystem(rootDirectory))
                    {
                        var dataContext = new IniDataContext(fileSystem, gameDefinition.Game);

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

                        foreach (var file in fileSystem.Files)
                        {
                            if (Path.GetExtension(file.FilePath).ToLowerInvariant() != ".ini")
                            {
                                continue;
                            }

                            var filename = Path.GetFileName(file.FilePath).ToLowerInvariant();

                            switch (filename)
                            {
                            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}.");

                            dataContext.LoadIniFile(file);
                        }
                    }
                }
            }
        }
Esempio n. 6
0
        public static void Run(Options opts)
        {
            logger.Info("Starting...");

            var DetectedGame = opts.Game;
            var GameFolder   = opts.GamePath;
            var UseLocators  = true;

            if (GameFolder == null)
            {
                GameFolder = Environment.CurrentDirectory;
            }

            foreach (var gameDef in GameDefinition.All)
            {
                if (gameDef.Probe(GameFolder))
                {
                    DetectedGame = gameDef.Game;
                    UseLocators  = false;
                }
            }

            var definition = GameDefinition.FromGame(DetectedGame);
            GameInstallation installation;

            if (UseLocators)
            {
                installation = GameInstallation
                               .FindAll(new[] { definition })
                               .FirstOrDefault();
            }
            else
            {
                installation = new GameInstallation(definition, GameFolder);
            }

            if (installation == null)
            {
                Console.WriteLine($"OpenSAGE was unable to find any installations of {definition.DisplayName}.\n");

                Console.WriteLine("You can manually specify the installation path by setting the following environment variable:");
                Console.WriteLine($"\t{definition.Identifier.ToUpper()}_PATH=<installation path>\n");

                Console.WriteLine("OpenSAGE doesn't yet detect every released version of every game. Please report undetected versions to our GitHub page:");
                Console.WriteLine("\thttps://github.com/OpenSAGE/OpenSAGE/issues");

                Console.WriteLine("\n\n Press any key to exit.");

                Console.ReadLine();

                Environment.Exit(1);
            }

            logger.Debug($"Have installation of {definition.DisplayName}");

            Platform.Start();

            var traceEnabled = !string.IsNullOrEmpty(opts.TraceFile);

            if (traceEnabled)
            {
                GameTrace.Start(opts.TraceFile);
            }

            // TODO: Read game version from assembly metadata or .git folder
            // TODO: Set window icon.
            var config = new Configuration()
            {
                UseRenderDoc   = opts.RenderDoc,
                LoadShellMap   = !opts.NoShellmap,
                UseUniquePorts = opts.UseUniquePorts
            };

            UPnP.InitializeAsync(TimeSpan.FromSeconds(10)).ContinueWith(_ => logger.Info($"UPnP status: {UPnP.Status}"));

            logger.Debug($"Have configuration");

            using (var window = new GameWindow($"OpenSAGE - {installation.Game.DisplayName} - master", 100, 100, 1024, 768, opts.Fullscreen))
                using (var game = new Game(installation, opts.Renderer, config, window))
                    using (var textureCopier = new TextureCopier(game, window.Swapchain.Framebuffer.OutputDescription))
                        using (var developerModeView = new DeveloperModeView(game, window))
                        {
                            game.GraphicsDevice.SyncToVerticalBlank = !opts.DisableVsync;

                            var developerModeEnabled = opts.DeveloperMode;

                            if (opts.DeveloperMode)
                            {
                                window.Maximized = true;
                            }

                            if (opts.ReplayFile != null)
                            {
                                var replayFile = game.ContentManager.UserDataFileSystem?.GetFile(Path.Combine("Replays", opts.ReplayFile));
                                if (replayFile == null)
                                {
                                    logger.Debug("Could not find entry for Replay " + opts.ReplayFile);
                                    game.ShowMainMenu();
                                }

                                game.LoadReplayFile(replayFile);
                            }
                            else if (opts.Map != null)
                            {
                                game.Restart = StartMap;
                                StartMap();

                                void StartMap()
                                {
                                    var mapCache = game.AssetStore.MapCaches.GetByName(opts.Map);

                                    if (mapCache == null)
                                    {
                                        logger.Debug("Could not find MapCache entry for map " + opts.Map);
                                        game.ShowMainMenu();
                                    }
                                    else if (mapCache.IsMultiplayer)
                                    {
                                        var pSettings = new PlayerSetting[]
                                        {
                                            new PlayerSetting(null, "FactionAmerica", new ColorRgb(255, 0, 0), 0, PlayerOwner.Player),
                                            new PlayerSetting(null, "FactionGLA", new ColorRgb(0, 255, 0), 0, PlayerOwner.EasyAi),
                                        };

                                        logger.Debug("Starting multiplayer game");

                                        game.StartSkirmishOrMultiPlayerGame(opts.Map,
                                                                            new EchoConnection(),
                                                                            pSettings,
                                                                            Environment.TickCount,
                                                                            false);
                                    }
                                    else
                                    {
                                        logger.Debug("Starting singleplayer game");

                                        game.StartSinglePlayerGame(opts.Map);
                                    }
                                }
                            }
                            else
                            {
                                logger.Debug("Showing main menu");
                                game.ShowMainMenu();
                            }

                            game.InputMessageBuffer.Handlers.Add(
                                new CallbackMessageHandler(
                                    HandlingPriority.Window,
                                    message =>
                            {
                                if (message.MessageType == InputMessageType.KeyDown && message.Value.Key == Key.Enter && (message.Value.Modifiers & ModifierKeys.Alt) != 0)
                                {
                                    window.Fullscreen = !window.Fullscreen;
                                    return(InputMessageResult.Handled);
                                }

                                if (message.MessageType == InputMessageType.KeyDown && message.Value.Key == Key.F11)
                                {
                                    developerModeEnabled = !developerModeEnabled;
                                    return(InputMessageResult.Handled);
                                }

                                return(InputMessageResult.NotHandled);
                            }));

                            logger.Debug("Starting game");

                            game.StartRun();

                            while (game.IsRunning)
                            {
                                if (!window.PumpEvents())
                                {
                                    break;
                                }

                                if (developerModeEnabled)
                                {
                                    developerModeView.Tick();
                                }
                                else
                                {
                                    game.Update(window.MessageQueue);

                                    game.Panel.EnsureFrame(window.ClientBounds);

                                    game.Render();

                                    textureCopier.Execute(
                                        game.Panel.Framebuffer.ColorTargets[0].Target,
                                        window.Swapchain.Framebuffer);
                                }

                                window.MessageQueue.Clear();

                                game.GraphicsDevice.SwapBuffers(window.Swapchain);
                            }
                        }

            if (traceEnabled)
            {
                GameTrace.Stop();
            }

            Platform.Stop();
        }
Esempio n. 7
0
        public static void Run(Options opts)
        {
            var             definition       = GameDefinition.FromGame(opts.Game);
            GraphicsBackend?preferredBackend = null;

            var installation = GameInstallation
                               .FindAll(new[] { definition })
                               .FirstOrDefault();

            if (installation == null)
            {
                Console.WriteLine($"OpenSAGE was unable to find any installations of {definition.DisplayName}.\n");

                Console.WriteLine("You can manually specify the installation path by setting the following environment variable:");
                Console.WriteLine($"\t{definition.Identifier.ToUpper()}_PATH=<installation path>\n");

                Console.WriteLine("OpenSAGE doesn't yet detect every released version of every game. Please report undetected versions to our GitHub page:");
                Console.WriteLine("\thttps://github.com/OpenSAGE/OpenSAGE/issues");

                Console.WriteLine("\n\n Press any key to exit.");

                Console.ReadLine();

                Environment.Exit(1);
            }

            if (opts.Renderer != Renderer.Default)
            {
                preferredBackend = (GraphicsBackend)opts.Renderer;
            }

            Platform.Start();

            // TODO: Read game version from assembly metadata or .git folder
            // TODO: Set window icon.
            using (var window = new GameWindow("OpenSAGE (master)", 100, 100, 1024, 768, preferredBackend))
                using (var gamePanel = GamePanel.FromGameWindow(window))
                    using (var game = GameFactory.CreateGame(installation, installation.CreateFileSystem(), gamePanel))
                    {
                        window.GraphicsDevice.SyncToVerticalBlank = !opts.DisableVsync;

                        game.Configuration.LoadShellMap = !opts.NoShellmap;

                        if (opts.Map == null)
                        {
                            game.ShowMainMenu();
                        }
                        else
                        {
                            game.StartGame(opts.Map, new EchoConnection(), new[] { "America", "GLA" }, 0);
                        }

                        while (game.IsRunning)
                        {
                            if (!window.PumpEvents())
                            {
                                break;
                            }

                            game.Tick();
                        }
                    }

            Platform.Stop();
        }
Esempio n. 8
0
        public static void Run(Options opts)
        {
            logger.Info("Starting...");

            var DetectedGame = opts.Game;
            var GameFolder   = opts.GamePath;
            var UseLocators  = true;

            if (GameFolder == null)
            {
                GameFolder = Environment.CurrentDirectory;
            }

            foreach (var gameDef in GameDefinition.All)
            {
                if (gameDef.Probe(GameFolder))
                {
                    DetectedGame = gameDef.Game;
                    UseLocators  = false;
                }
            }

            var definition = GameDefinition.FromGame(DetectedGame);
            GameInstallation installation;

            if (UseLocators)
            {
                installation = GameInstallation
                               .FindAll(new[] { definition })
                               .FirstOrDefault();
            }
            else
            {
                installation = new GameInstallation(definition, GameFolder);
            }

            if (installation == null)
            {
                Console.WriteLine($"OpenSAGE was unable to find any installations of {definition.DisplayName}.\n");

                Console.WriteLine("You can manually specify the installation path by setting the following environment variable:");
                Console.WriteLine($"\t{definition.Identifier.ToUpper()}_PATH=<installation path>\n");

                Console.WriteLine("OpenSAGE doesn't yet detect every released version of every game. Please report undetected versions to our GitHub page:");
                Console.WriteLine("\thttps://github.com/OpenSAGE/OpenSAGE/issues");

                Console.WriteLine("\n\n Press any key to exit.");

                Console.ReadLine();

                Environment.Exit(1);
            }

            logger.Debug($"Have installation of {definition.DisplayName}");

            Platform.Start();

            var traceEnabled = !string.IsNullOrEmpty(opts.TraceFile);

            if (traceEnabled)
            {
                GameTrace.Start(opts.TraceFile);
            }

            // TODO: Read game version from assembly metadata or .git folder
            // TODO: Set window icon.
            var config = new Configuration()
            {
                UseFullscreen = opts.Fullscreen,
                UseRenderDoc  = opts.RenderDoc,
                LoadShellMap  = !opts.NoShellmap,
            };

            if (opts.LanIPAddress != "")
            {
                try {
                    config.LanIpAddress = IPAddress.Parse(opts.LanIPAddress);
                }catch (FormatException) {
                    logger.Error($"Could not parse specified LAN IP address: {opts.LanIPAddress}");
                }
            }

            logger.Debug($"Have configuration");

            using (var game = new Game(installation, opts.Renderer, config))
            {
                game.GraphicsDevice.SyncToVerticalBlank = !opts.DisableVsync;

                game.DeveloperModeEnabled = opts.DeveloperMode;

                if (opts.DeveloperMode)
                {
                    game.Window.Maximized = true;
                }

                if (opts.ReplayFile != null)
                {
                    var replayFile = game.ContentManager.UserDataFileSystem?.GetFile(Path.Combine("Replays", opts.ReplayFile));
                    if (replayFile == null)
                    {
                        logger.Debug("Could not find entry for Replay " + opts.ReplayFile);
                        game.ShowMainMenu();
                    }

                    game.LoadReplayFile(replayFile);
                }
                else if (opts.Map != null)
                {
                    game.Restart = StartMap;
                    StartMap();

                    void StartMap()
                    {
                        var mapCache = game.AssetStore.MapCaches.GetByName(opts.Map);

                        if (mapCache == null)
                        {
                            logger.Debug("Could not find MapCache entry for map " + opts.Map);
                            game.ShowMainMenu();
                        }
                        else if (mapCache.IsMultiplayer)
                        {
                            var pSettings = new PlayerSetting?[]
                            {
                                new PlayerSetting(null, game.AssetStore.PlayerTemplates.GetByName("FactionAmerica"), new ColorRgb(255, 0, 0), PlayerOwner.Player),
                                new PlayerSetting(null, game.AssetStore.PlayerTemplates.GetByName("FactionGLA"), new ColorRgb(0, 255, 0), PlayerOwner.EasyAi),
                            };

                            logger.Debug("Starting multiplayer game");

                            game.StartMultiPlayerGame(opts.Map,
                                                      new EchoConnection(),
                                                      pSettings,
                                                      0);
                        }
                        else
                        {
                            logger.Debug("Starting singleplayer game");

                            game.StartSinglePlayerGame(opts.Map);
                        }
                    }
                }
                else
                {
                    logger.Debug("Showing main menu");
                    game.ShowMainMenu();
                }

                logger.Debug("Starting game");

                game.Run();
            }

            if (traceEnabled)
            {
                GameTrace.Stop();
            }

            Platform.Stop();
        }
Esempio n. 9
0
        public static void Run(Options opts)
        {
            logger.Info("Starting...");

            var definition = GameDefinition.FromGame(opts.Game);

            var installation = GameInstallation
                               .FindAll(new[] { definition })
                               .FirstOrDefault();

            if (installation == null)
            {
                Console.WriteLine($"OpenSAGE was unable to find any installations of {definition.DisplayName}.\n");

                Console.WriteLine("You can manually specify the installation path by setting the following environment variable:");
                Console.WriteLine($"\t{definition.Identifier.ToUpper()}_PATH=<installation path>\n");

                Console.WriteLine("OpenSAGE doesn't yet detect every released version of every game. Please report undetected versions to our GitHub page:");
                Console.WriteLine("\thttps://github.com/OpenSAGE/OpenSAGE/issues");

                Console.WriteLine("\n\n Press any key to exit.");

                Console.ReadLine();

                Environment.Exit(1);
            }

            logger.Debug($"Have installation of {definition.DisplayName}");

            Platform.Start();

            var traceEnabled = !string.IsNullOrEmpty(opts.TraceFile);

            if (traceEnabled)
            {
                GameTrace.Start(opts.TraceFile);
            }

            // TODO: Read game version from assembly metadata or .git folder
            // TODO: Set window icon.
            var config = new Configuration()
            {
                UseFullscreen = opts.Fullscreen,
                UseRenderDoc  = opts.RenderDoc,
                LoadShellMap  = !opts.NoShellmap,
            };

            logger.Debug($"Have configuration");

            using (var game = new Game(installation, opts.Renderer, config))
            {
                game.GraphicsDevice.SyncToVerticalBlank = !opts.DisableVsync;

                game.DeveloperModeEnabled = opts.DeveloperMode;

                if (opts.ReplayFile != null)
                {
                    using (var fileSystem = new FileSystem(Path.Combine(game.UserDataFolder, "Replays")))
                    {
                        game.LoadReplayFile(fileSystem.GetFile(opts.ReplayFile));
                    }
                }
                else if (opts.Map != null)
                {
                    var pSettings = new PlayerSetting?[]
                    {
                        new PlayerSetting(null, "America", new ColorRgb(255, 0, 0)),
                        new PlayerSetting(null, "GLA", new ColorRgb(255, 255, 255)),
                    };

                    logger.Debug("Starting multiplayer game");
                    game.StartMultiPlayerGame(opts.Map,
                                              new EchoConnection(),
                                              pSettings,
                                              0);
                }
                else
                {
                    logger.Debug("Showing main menu");
                    game.ShowMainMenu();
                }

                logger.Debug("Starting game");

                game.Run();
            }

            if (traceEnabled)
            {
                GameTrace.Stop();
            }

            Platform.Stop();
        }
Esempio n. 10
0
        public static string GetInstallationDirectory(SageGame game)
        {
            var definition = GameDefinition.FromGame(game);

            return(InstallationLocators.FindAllInstallations(definition).First().Path);
        }
Esempio n. 11
0
        public static void Main(string[] args)
        {
            var             noShellMap       = false;
            var             definition       = GameDefinition.FromGame(SageGame.CncGenerals);
            string          mapName          = null;
            GraphicsBackend?preferredBackend = null;

            ArgumentSyntax.Parse(args, syntax =>
            {
                string preferredBackendString = null;
                syntax.DefineOption("renderer", ref preferredBackendString, false, $"Choose which renderer backend should be used. Valid options: {string.Join(",", Enum.GetNames(typeof(GraphicsBackend)))}");
                if (preferredBackendString != null)
                {
                    if (Enum.TryParse <GraphicsBackend>(preferredBackendString, out var preferredBackendTemp))
                    {
                        preferredBackend = preferredBackendTemp;
                    }
                    else
                    {
                        syntax.ReportError($"Unknown renderer backend: {preferredBackendString}");
                    }
                }

                syntax.DefineOption("noshellmap", ref noShellMap, false, "Disables loading the shell map, speeding up startup time.");

                string gameName    = null;
                var availableGames = string.Join(", ", GameDefinition.All.Select(def => def.Game.ToString()));

                syntax.DefineOption("game", ref gameName, false, $"Chooses which game to start. Valid options: {availableGames}");

                // If a game has been specified, make sure it's valid.
                if (gameName != null && !GameDefinition.TryGetByName(gameName, out definition))
                {
                    syntax.ReportError($"Unknown game: {gameName}");
                }

                syntax.DefineOption("map", ref mapName, false,
                                    "Immediately starts a new skirmish with default settings in the specified map. The map file must be specified with the full path.");
            });

            var installation = GameInstallation
                               .FindAll(new[] { definition })
                               .FirstOrDefault();

            if (installation == null)
            {
                Console.WriteLine($"OpenSAGE was unable to find any installations of {definition.DisplayName}.\n");

                Console.WriteLine("You can manually specify the installation path by setting the following environment variable:");
                Console.WriteLine($"\t{definition.Identifier.ToUpper()}_PATH=<installation path>\n");

                Console.WriteLine("OpenSAGE doesn't yet detect every released version of every game. Please report undetected versions to our GitHub page:");
                Console.WriteLine("\thttps://github.com/OpenSAGE/OpenSAGE/issues");

                Environment.Exit(1);
            }

            Platform.Start();

            // TODO: Read game version from assembly metadata or .git folder
            // TODO: Set window icon.
            using (var window = new GameWindow("OpenSAGE (master)", 100, 100, 1024, 768, preferredBackend))
                using (var gamePanel = GamePanel.FromGameWindow(window))
                    using (var game = GameFactory.CreateGame(installation, installation.CreateFileSystem(), gamePanel))
                    {
                        game.Configuration.LoadShellMap = !noShellMap;

                        if (mapName == null)
                        {
                            game.ShowMainMenu();
                        }
                        else
                        {
                            game.StartGame(mapName, new EchoConnection(), new[] { "America", "GLA" }, 0);
                        }

                        while (game.IsRunning)
                        {
                            if (!window.PumpEvents())
                            {
                                break;
                            }

                            game.Tick();
                        }
                    }

            Platform.Stop();
        }
Esempio n. 12
0
        public static void Main(string[] args)
        {
            var             noShellMap       = false;
            var             definition       = GameDefinition.FromGame(SageGame.CncGenerals);
            string          mapName          = null;
            GraphicsBackend?preferredBackend = null;

            ArgumentSyntax.Parse(args, syntax =>
            {
                string preferredBackendString = null;
                syntax.DefineOption("renderer", ref preferredBackendString, false, $"Choose which renderer backend should be used. Valid options: {string.Join(",", Enum.GetNames(typeof(GraphicsBackend)))}");
                if (preferredBackendString != null)
                {
                    if (Enum.TryParse <GraphicsBackend>(preferredBackendString, out var preferredBackendTemp))
                    {
                        preferredBackend = preferredBackendTemp;
                    }
                    else
                    {
                        syntax.ReportError($"Unknown renderer backend: {preferredBackendString}");
                    }
                }

                syntax.DefineOption("noshellmap", ref noShellMap, false, "Disables loading the shell map, speeding up startup time.");

                string gameName    = null;
                var availableGames = string.Join(", ", GameDefinition.All.Select(def => def.Game.ToString()));

                syntax.DefineOption("game", ref gameName, false, $"Chooses which game to start. Valid options: {availableGames}");

                // If a game has been specified, make sure it's valid.
                if (gameName != null && !GameDefinition.TryGetByName(gameName, out definition))
                {
                    syntax.ReportError($"Unknown game: {gameName}");
                }

                syntax.DefineOption("map", ref mapName, false,
                                    "Immediately starts a new skirmish with default settings in the specified map. The map file must be specified with the full path.");
            });

            Platform.Start();

            // TODO: Read game version from assembly metadata or .git folder
            // TODO: Set window icon.
            using (var window = new GameWindow("OpenSAGE (master)", 100, 100, 1024, 768, preferredBackend))
                using (var gamePanel = GamePanel.FromGameWindow(window))
                    using (var game = GameFactory.CreateGame(definition, gamePanel))
                    {
                        game.Configuration.LoadShellMap = !noShellMap;

                        if (mapName == null)
                        {
                            game.ShowMainMenu();
                        }
                        else
                        {
                            game.StartGame(mapName, new EchoConnection(), new[] { "America", "GLA" }, 0);
                        }

                        while (game.IsRunning)
                        {
                            if (!window.PumpEvents())
                            {
                                break;
                            }
                            game.Tick();
                        }

                        game.Dispose();
                    }

            Platform.Stop();
        }
Esempio n. 13
0
        public static GameInstallation GetInstallation(SageGame game)
        {
            var definition = GameDefinition.FromGame(game);

            return(InstallationLocators.FindAllInstallations(definition).First());
        }
Esempio n. 14
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);
                    }
                }
            }
        }