public IniView(AssetViewContext context) { var iniDataContext = new IniDataContext(context.Entry.FileSystem, context.Game.SageGame); iniDataContext.LoadIniFile(context.Entry); using (var stream = context.Entry.Open()) { using (var reader = new StreamReader(stream)) { _iniString = reader.ReadToEnd(); } } _subObjects = new List <IniEntry>(); foreach (var objectDefinition in iniDataContext.Objects) { _subObjects.Add(new IniEntry(objectDefinition.Name, () => new ObjectDefinitionView(context, objectDefinition))); } foreach (var particleSystem in iniDataContext.ParticleSystems) { _subObjects.Add(new IniEntry(particleSystem.Name, () => new ParticleSystemView(context, particleSystem))); } // If we can't show this file in object view, default to text view. _currentView = _subObjects.Count == 0 ? ViewMode.TextView : ViewMode.ObjectView; }
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)); } }
public IniView(FileSystemEntry entry, Func <IntPtr, Game> createGame) { var iniDataContext = new IniDataContext(entry.FileSystem); iniDataContext.LoadIniFile(entry); var subObjects = new List <IniEntry>(); foreach (var objectDefinition in iniDataContext.Objects) { subObjects.Add(new IniEntry(objectDefinition.Name, () => new ObjectDefinitionView(createGame, objectDefinition))); } foreach (var particleSystem in iniDataContext.ParticleSystems) { subObjects.Add(new IniEntry(particleSystem.Name, () => new ParticleSystemView(createGame, particleSystem))); } _listBox = new ListBox { Width = 200, ItemTextBinding = Binding.Property((IniEntry v) => v.Name), DataStore = subObjects }; _listBox.SelectedValueChanged += OnSelectedValueChanged; Panel1 = _listBox; Panel2 = new Panel(); }
public void ParseFile(IniDataContext dataContext) { while (Current.TokenType != IniTokenType.EndOfFile) { switch (Current.TokenType) { case IniTokenType.Identifier: if (BlockParsers.TryGetValue(Current.StringValue, out var blockParser)) { _currentBlockOrFieldStack.Push(Current.StringValue); blockParser(this, dataContext); _currentBlockOrFieldStack.Pop(); } else { throw new IniParseException($"Unexpected block '{Current.StringValue}'.", Current.Position); } break; case IniTokenType.DefineKeyword: NextToken(); var macroName = ParseIdentifier(); var macroValue = ParseString(true); dataContext.Defines.Add(macroName, macroValue); NextToken(IniTokenType.EndOfLine); break; default: UnexpectedToken(Current); break; } } }
public ConfiguredSubsystemLoader(IGameDefinition gameDefinition, FileSystem fileSystem, IniDataContext iniDataContext) { _gameDefinition = gameDefinition; _iniDataContext = iniDataContext; _fileSystem = fileSystem; _iniDataContext.LoadIniFile(@"Data\INI\Default\subsystemlegend.ini"); _subsystems = _iniDataContext.Subsystems.ToDictionary(subsystem => subsystem.Name); }
public IniParser(string source, FileSystemEntry entry, IniDataContext dataContext) { _directory = Path.GetDirectoryName(entry.FilePath); _dataContext = dataContext; _tokenReader = new TokenReader(source, Path.Combine(entry.FileSystem.RootDirectory, entry.FilePath)); _currentBlockOrFieldStack = new Stack <string>(); }
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; } } } }); }
public IniFileContentViewModel(FileSystemEntry file) : base(file) { _iniDataContext = new IniDataContext(file.FileSystem); _iniDataContext.LoadIniFile(file); foreach (var objectDefinition in _iniDataContext.Objects) { SubObjects.Add(new ObjectDefinitionIniEntryViewModel(objectDefinition)); } foreach (var particleSystem in _iniDataContext.ParticleSystems) { SubObjects.Add(new ParticleSystemIniEntryViewModel(particleSystem)); } }
public void CanReadIniFiles() { var tasks = new List <Task>(); InstalledFilesTestData.ReadFiles(".ini", _output, entry => { if (Path.GetFileName(entry.FilePath) == "ButtonSets.ini") { return; // This file doesn't seem to be used? } if (Path.GetFileName(entry.FilePath).ToLowerInvariant() == "scripts.ini") { return; // Only needed by World Builder? } if (Path.GetFileName(entry.FilePath).ToLowerInvariant() != "particlesystem.ini") { return; } tasks.Add(Task.Run(() => { var dataContext = new IniDataContext(entry.FileSystem); 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; } } } })); });
public Entity InstantiateObject(string typeName) { // TODO: Don't do this every time. IniDataContext.LoadIniFiles(@"Data\INI\Object"); var objectDefinition = IniDataContext.Objects.FirstOrDefault(x => x.Name == typeName); if (objectDefinition != null) { return(Entity.FromObjectDefinition(objectDefinition)); } else { // TODO return(null); } }
public IniView(AssetViewContext context) { var iniDataContext = new IniDataContext(context.Entry.FileSystem); iniDataContext.LoadIniFile(context.Entry); _subObjects = new List <IniEntry>(); foreach (var objectDefinition in iniDataContext.Objects) { _subObjects.Add(new IniEntry(objectDefinition.Name, () => new ObjectDefinitionView(context, objectDefinition))); } foreach (var particleSystem in iniDataContext.ParticleSystems) { _subObjects.Add(new IniEntry(particleSystem.Name, () => new ParticleSystemView(context, particleSystem))); } }
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); }); } }
public WndFileContentViewModel(FileSystemEntry file) : base(file) { _fileSystem = file.FileSystem; _csfFile = CsfFile.FromFileSystemEntry(_fileSystem.GetFile(@"Data\English\generals.csf")); var iniDataContext = new IniDataContext(_fileSystem); iniDataContext.LoadIniFiles(@"Data\INI\MappedImages\HandCreated\"); iniDataContext.LoadIniFiles(@"Data\INI\MappedImages\TextureSize_512\"); _mappedImages = iniDataContext.MappedImages; var wndFile = WndFile.FromFileSystemEntry(file); ContainerView = new NonInheritingCanvas { Width = wndFile.RootWindow.ScreenRect.CreationResolution.Width, Height = wndFile.RootWindow.ScreenRect.CreationResolution.Height, }; AddWindow(wndFile.RootWindow); }
public ContentManager(FileSystem fileSystem, GraphicsDevice graphicsDevice) { _fileSystem = fileSystem; GraphicsDevice = graphicsDevice; _contentLoaders = new Dictionary <Type, ContentLoader> { { typeof(Model), AddDisposable(new ModelLoader()) }, { typeof(Scene), AddDisposable(new MapLoader()) }, { typeof(Texture), AddDisposable(new TextureLoader(graphicsDevice)) } }; _cachedObjects = new Dictionary <string, object>(); _effects = new Dictionary <Type, Effect> { { typeof(MeshEffect), AddDisposable(new MeshEffect(graphicsDevice)) }, { typeof(ParticleEffect), AddDisposable(new ParticleEffect(graphicsDevice)) }, { typeof(SpriteEffect), AddDisposable(new SpriteEffect(graphicsDevice)) }, }; IniDataContext = new IniDataContext(fileSystem); }
public static ISubsystemLoader Create(IGameDefinition gameDefinition, FileSystem fileSystem, IniDataContext iniDataContext) { switch (gameDefinition.Game) { case SageGame.CncGenerals: case SageGame.CncGeneralsZeroHour: return(new GeneralsSubsystemLoader(iniDataContext)); case SageGame.Bfme: case SageGame.Bfme2: case SageGame.Bfme2Rotwk: case SageGame.Cnc3: case SageGame.Cnc3KanesWrath: return(new ConfiguredSubsystemLoader(gameDefinition, fileSystem, iniDataContext)); default: // TODO: Implement subsystem loader for new XML-based format used in RA3 and beyond. return(null); } }
public GeneralsSubsystemLoader(IniDataContext iniDataContext) { _iniDataContext = iniDataContext; }
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); } } } }
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 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))); }
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); } }
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)); } }
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)); } }
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); } } } } }
public static ISubsystemLoader Create(IGameDefinition gameDefinition, FileSystem fileSystem, IniDataContext iniDataContext) { switch (gameDefinition.Game) { case SageGame.CncGenerals: case SageGame.CncGeneralsZeroHour: return(new GeneralsSubsystemLoader(iniDataContext)); // TODO: Do all the other games use configured subsystems? default: return(new ConfiguredSubsystemLoader(gameDefinition, fileSystem, iniDataContext)); } }