mirror of
https://github.com/digital-jellyfish/Virtu.git
synced 2024-06-12 01:29:27 +00:00
0182641281
Added save state support to all machine components. Switched from xml serialization to binary serialization. Refactored audio service for performance. Bumped machine version to 0.9.0 for next release. Miscellaneous cosmetic or minor changes.
139 lines
6.0 KiB
C#
139 lines
6.0 KiB
C#
using System;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
#if WINDOWS
|
|
using System.Windows;
|
|
#endif
|
|
using Jellyfish.Library;
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
|
namespace Jellyfish.Virtu.Services
|
|
{
|
|
public sealed class XnaVideoService : VideoService
|
|
{
|
|
public XnaVideoService(Machine machine, GameBase game) :
|
|
base(machine)
|
|
{
|
|
if (game == null)
|
|
{
|
|
throw new ArgumentNullException("game");
|
|
}
|
|
|
|
_game = game;
|
|
|
|
_game.GraphicsDeviceManager.PreparingDeviceSettings += OnGraphicsDeviceManagerPreparingDeviceSettings;
|
|
_game.GraphicsDeviceService.DeviceCreated += OnGraphicsDeviceServiceDeviceCreated;
|
|
_game.GraphicsDeviceService.DeviceReset += (sender, e) => SetTexturePosition();
|
|
}
|
|
|
|
public override void SetFullScreen(bool isFullScreen)
|
|
{
|
|
#if WINDOWS
|
|
var graphicsDeviceManager = _game.GraphicsDeviceManager;
|
|
if (graphicsDeviceManager.IsFullScreen != isFullScreen)
|
|
{
|
|
graphicsDeviceManager.IsFullScreen = isFullScreen;
|
|
_game.SynchronizationContext.Send(state => graphicsDeviceManager.ApplyChanges(), null);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow")]
|
|
public override void SetPixel(int x, int y, uint color)
|
|
{
|
|
_pixels[y * TextureWidth + x] = (color & 0xFF00FF00) | ((color << 16) & 0x00FF0000) | ((color >> 16) & 0x000000FF); // RGBA
|
|
_pixelsDirty = true;
|
|
}
|
|
|
|
public override void Update() // main thread
|
|
{
|
|
if (_pixelsDirty)
|
|
{
|
|
_pixelsDirty = false;
|
|
_texture.SetData(_pixels);
|
|
}
|
|
|
|
_spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, SamplerState.PointClamp, null, null);
|
|
_spriteBatch.Draw(_texture, _texturePosition, null, Color.White, 0, Vector2.Zero, _textureScale, SpriteEffects.None, 0);
|
|
_spriteBatch.End();
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (disposing)
|
|
{
|
|
_spriteBatch.Dispose();
|
|
_texture.Dispose();
|
|
}
|
|
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
private void OnGraphicsDeviceManagerPreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
|
|
{
|
|
var displayMode = e.GraphicsDeviceInformation.Adapter.CurrentDisplayMode;
|
|
var presentationParameters = e.GraphicsDeviceInformation.PresentationParameters;
|
|
|
|
#if WINDOWS_PHONE
|
|
bool portraitOrientation = (presentationParameters.DisplayOrientation & DisplayOrientation.Portrait) != 0;
|
|
if (portraitOrientation)
|
|
{
|
|
_textureScale = Math.Max(1, Math.Min(displayMode.TitleSafeArea.Width / TextureWidth, displayMode.TitleSafeArea.Height / TextureHeight));
|
|
presentationParameters.BackBufferWidth = displayMode.Width; // always use portrait display mode
|
|
presentationParameters.BackBufferHeight = displayMode.Height;
|
|
}
|
|
else
|
|
{
|
|
_textureScale = Math.Max(1, Math.Min(displayMode.TitleSafeArea.Height / TextureWidth, displayMode.TitleSafeArea.Width / TextureHeight));
|
|
presentationParameters.BackBufferWidth = displayMode.Height; // always use landscape display mode
|
|
presentationParameters.BackBufferHeight = displayMode.Width;
|
|
}
|
|
#elif XBOX
|
|
_textureScale = Math.Max(1, Math.Min(displayMode.TitleSafeArea.Width / TextureWidth, displayMode.TitleSafeArea.Height / TextureHeight));
|
|
presentationParameters.BackBufferWidth = displayMode.Width; // always use display mode
|
|
presentationParameters.BackBufferHeight = displayMode.Height;
|
|
#else
|
|
if (presentationParameters.IsFullScreen)
|
|
{
|
|
_textureScale = Math.Max(1, Math.Min((int)SystemParameters.PrimaryScreenWidth / TextureWidth, (int)SystemParameters.PrimaryScreenHeight / TextureHeight));
|
|
presentationParameters.BackBufferWidth = displayMode.Width; // avoids changing display mode
|
|
presentationParameters.BackBufferHeight = displayMode.Height;
|
|
}
|
|
else
|
|
{
|
|
_textureScale = Math.Max(1, Math.Min((int)SystemParameters.FullPrimaryScreenWidth / TextureWidth, (int)SystemParameters.FullPrimaryScreenHeight / TextureHeight));
|
|
presentationParameters.BackBufferWidth = _textureScale * TextureWidth;
|
|
presentationParameters.BackBufferHeight = _textureScale * TextureHeight;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
private void OnGraphicsDeviceServiceDeviceCreated(object sender, EventArgs e)
|
|
{
|
|
_graphicsDevice = _game.GraphicsDevice;
|
|
_spriteBatch = new SpriteBatch(_graphicsDevice);
|
|
_texture = new Texture2D(_graphicsDevice, TextureWidth, TextureHeight, false, SurfaceFormat.Color);
|
|
_pixels = new uint[TextureWidth * TextureHeight];
|
|
SetTexturePosition();
|
|
}
|
|
|
|
private void SetTexturePosition()
|
|
{
|
|
_texturePosition.X = (_graphicsDevice.PresentationParameters.BackBufferWidth - TextureWidth * _textureScale) / 2; // centered
|
|
_texturePosition.Y = (_graphicsDevice.PresentationParameters.BackBufferHeight - TextureHeight * _textureScale) / 2;
|
|
}
|
|
|
|
private const int TextureWidth = 560;
|
|
private const int TextureHeight = 384;
|
|
|
|
private GameBase _game;
|
|
private GraphicsDevice _graphicsDevice;
|
|
private SpriteBatch _spriteBatch;
|
|
private Texture2D _texture;
|
|
private Vector2 _texturePosition;
|
|
private int _textureScale;
|
|
private uint[] _pixels;
|
|
private bool _pixelsDirty;
|
|
}
|
|
}
|