public GameView(DataSource dataSource, Size virtualScreenSize, DeviceType deviceType = DeviceType.Desktop, SizingPolicy sizingPolicy = SizingPolicy.FitRatio, OrientationPolicy orientationPolicy = OrientationPolicy.Support180DegreeRotation) { VirtualScreen = new Rect(0, 0, Math.Min(virtualScreenSize.Width, Global.MAX_VIRTUAL_SCREEN_WIDTH), Math.Min(virtualScreenSize.Height, Global.MAX_VIRTUAL_SCREEN_HEIGHT)); virtualScreenDisplay = new Rect(VirtualScreen); this.sizingPolicy = sizingPolicy; this.orientationPolicy = orientationPolicy; this.deviceType = deviceType; isLandscapeRatio = VirtualScreen.Size.Width > VirtualScreen.Size.Height; context = new Context(VirtualScreen.Size.Width, VirtualScreen.Size.Height); if (dataSource == null || !dataSource.IsLoaded) { throw new ExceptionFreeserf(ErrorSystemType.Data, "Given data source is not useable."); } DataSource = dataSource; // factories spriteFactory = new SpriteFactory(VirtualScreen); triangleFactory = new TriangleFactory(VirtualScreen); coloredRectFactory = new ColoredRectFactory(VirtualScreen); minimapTextureFactory = new MinimapTextureFactory(); audioFactory = new AudioFactory(dataSource); var audio = audioFactory.GetAudio(); if (audio != null) { var musicPlayer = audio.GetMusicPlayer(); var soundPlayer = audio.GetSoundPlayer(); var volumeController = audio.GetVolumeController(); if (musicPlayer != null) { musicPlayer.Enabled = UserConfig.Audio.Music; } if (soundPlayer != null) { soundPlayer.Enabled = UserConfig.Audio.Sound; } if (volumeController != null) { volumeController.SetVolume(UserConfig.Audio.Volume); } } TextureAtlasManager.RegisterFactory(new TextureAtlasBuilderFactory()); var textureAtlas = TextureAtlasManager.Instance; textureAtlas.AddAll(dataSource); foreach (Layer layer in Enum.GetValues(typeof(Layer))) { if (layer == Layer.None) { continue; } // TODO: color keys? try { var texture = (layer == Layer.Minimap) ? minimapTextureFactory.GetMinimapTexture() : textureAtlas.GetOrCreate(layer).Texture as Texture; var renderLayer = Create(layer, texture, layer == Layer.Gui, // only the gui supports colored rects null, // no color key for now layer == Layer.GuiFont ? new Render.Color(115, 179, 67, 255) : null); // UI font uses green color overlay if (layer == Layer.Gui || layer == Layer.GuiBuildings || layer == Layer.Minimap) { // the gui needs scaling renderLayer.PositionTransformation = (Position position) => { float factorX = (float)VirtualScreen.Size.Width / 640.0f; float factorY = (float)VirtualScreen.Size.Height / 480.0f; return(new Position(Misc.Round(position.X * factorX), Misc.Round(position.Y * factorY))); }; renderLayer.SizeTransformation = (Size size) => { float factorX = (float)VirtualScreen.Size.Width / 640.0f; float factorY = (float)VirtualScreen.Size.Height / 480.0f; // don't scale a dimension of 0 int width = (size.Width == 0) ? 0 : Misc.Round(size.Width * factorX); int height = (size.Height == 0) ? 0 : Misc.Round(size.Height * factorY); return(new Size(width, height)); }; } else if (layer == Layer.GuiFont) // UI Font needs different scaling { renderLayer.PositionTransformation = (Position position) => { float factorX = (float)VirtualScreen.Size.Width / 640.0f; float factorY = (float)VirtualScreen.Size.Height / 480.0f; return(new Position(Misc.Round(position.X * factorX), Misc.Round(position.Y * factorY))); }; renderLayer.SizeTransformation = (Size size) => { // The UI expects 8x8 characters but we may use different sizes. // So we adjust the scale factors accordingly. float factorX = (8.0f / Global.UIFontCharacterWidth) * (float)VirtualScreen.Size.Width / 640.0f; float factorY = (8.0f / Global.UIFontCharacterHeight) * (float)VirtualScreen.Size.Height / 480.0f; // don't scale a dimension of 0 int width = (size.Width == 0) ? 0 : Misc.Round(size.Width * factorX); int height = (size.Height == 0) ? 0 : Misc.Round(size.Height * factorY); return(new Size(width, height)); }; } renderLayer.Visible = true; AddLayer(renderLayer); } catch (Exception ex) { throw new ExceptionFreeserf(ErrorSystemType.Render, $"Unable to create layer '{layer.ToString()}': {ex.Message}"); } } gui = new UI.Gui(this, this); }
public RenderView(IContextProvider contextProvider, IGameData gameData, IGraphicProvider graphicProvider, IFontProvider fontProvider, ITextProcessor textProcessor, Func <TextureAtlasManager> textureAtlasManagerProvider, int framebufferWidth, int framebufferHeight, Size windowSize, DeviceType deviceType = DeviceType.Desktop, SizingPolicy sizingPolicy = SizingPolicy.FitRatio, OrientationPolicy orientationPolicy = OrientationPolicy.Support180DegreeRotation) : base(new State(contextProvider)) { AspectProcessor = UpdateAspect; GameData = gameData; GraphicProvider = graphicProvider; TextProcessor = textProcessor; RenderArea = new Rect(0, 0, framebufferWidth, framebufferHeight); renderDisplayArea = new Rect(RenderArea); this.windowSize = new Size(windowSize); this.sizingPolicy = sizingPolicy; this.orientationPolicy = orientationPolicy; this.deviceType = deviceType; IsLandscapeRatio = RenderArea.Width > RenderArea.Height; Resize(framebufferWidth, framebufferHeight); context = new Context(State, renderDisplayArea.Width, renderDisplayArea.Height, 1.0f); // factories var visibleArea = new Rect(0, 0, Global.VirtualScreenWidth, Global.VirtualScreenHeight); spriteFactory = new SpriteFactory(visibleArea); coloredRectFactory = new ColoredRectFactory(visibleArea); surface3DFactory = new Surface3DFactory(visibleArea); renderTextFactory = new RenderTextFactory(visibleArea); fowFactory = new FowFactory(visibleArea); camera3D = new Camera3D(State); TextureAtlasManager.RegisterFactory(new TextureAtlasBuilderFactory(State)); var textureAtlasManager = textureAtlasManagerProvider?.Invoke(); var palette = textureAtlasManager.CreatePalette(graphicProvider); foreach (var layer in Enum.GetValues <Layer>()) { if (layer == Layer.None) { continue; } try { var texture = textureAtlasManager.GetOrCreate(layer)?.Texture; var renderLayer = Create(layer, texture, palette); if (layer != Layer.Map3DBackground && layer != Layer.Map3D && layer != Layer.Billboards3D) { renderLayer.Visible = true; } AddLayer(renderLayer); } catch (Exception ex) { throw new AmbermoonException(ExceptionScope.Render, $"Unable to create layer '{layer}': {ex.Message}"); } } }