mirror of https://github.com/Washi1337/Emux.git
Frame rendering.
This commit is contained in:
parent
9f2094575c
commit
120d9455ba
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
#----------------------------- Global Properties ----------------------------#
|
||||||
|
|
||||||
|
/outputDir:bin/$(Platform)
|
||||||
|
/intermediateDir:obj/$(Platform)
|
||||||
|
/platform:DesktopGL
|
||||||
|
/config:
|
||||||
|
/profile:Reach
|
||||||
|
/compress:False
|
||||||
|
|
||||||
|
#-------------------------------- References --------------------------------#
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------- Content ---------------------------------#
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<MonoGameContentReference Include="**\*.mgcb" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="MonoGame.Content.Builder" Version="3.7.0.4" />
|
||||||
|
<PackageReference Include="MonoGame.Framework.DesktopGL.Core" Version="3.7.0.7" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Emux.GameBoy\Emux.GameBoy.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,116 @@
|
||||||
|
using System;
|
||||||
|
using Emux.GameBoy.Cpu;
|
||||||
|
using Emux.GameBoy.Graphics;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
using Color = Microsoft.Xna.Framework.Color;
|
||||||
|
|
||||||
|
namespace Emux.MonoGame
|
||||||
|
{
|
||||||
|
public class EmuxHost : Game, IClock, IVideoOutput
|
||||||
|
{
|
||||||
|
public new event EventHandler Tick;
|
||||||
|
|
||||||
|
private GraphicsDeviceManager _graphics;
|
||||||
|
private SpriteBatch _spriteBatch;
|
||||||
|
private Texture2D _video;
|
||||||
|
private bool _clockEnabled = false;
|
||||||
|
|
||||||
|
public EmuxHost()
|
||||||
|
{
|
||||||
|
_graphics = new GraphicsDeviceManager(this);
|
||||||
|
Content.RootDirectory = "Content";
|
||||||
|
IsMouseVisible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameBoy.GameBoy GameBoy
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadContent()
|
||||||
|
{
|
||||||
|
_spriteBatch = new SpriteBatch(GraphicsDevice);
|
||||||
|
|
||||||
|
_video = new Texture2D(GraphicsDevice, 160, 144);
|
||||||
|
GameBoy.Cpu.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update(GameTime gameTime)
|
||||||
|
{
|
||||||
|
if (_clockEnabled)
|
||||||
|
Tick?.Invoke(this, EventArgs.Empty);
|
||||||
|
|
||||||
|
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
|
||||||
|
Keyboard.GetState().IsKeyDown(Keys.Escape))
|
||||||
|
Exit();
|
||||||
|
|
||||||
|
base.Update(gameTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(GameTime gameTime)
|
||||||
|
{
|
||||||
|
GraphicsDevice.Clear(Color.Black);
|
||||||
|
|
||||||
|
_spriteBatch.Begin();
|
||||||
|
|
||||||
|
float aspectRatio = 160f / 144f;
|
||||||
|
|
||||||
|
int screenHeight = _graphics.PreferredBackBufferHeight;
|
||||||
|
int screenWidth = _graphics.PreferredBackBufferWidth;
|
||||||
|
|
||||||
|
int frameWidth;
|
||||||
|
int frameHeight;
|
||||||
|
if (screenHeight > screenWidth)
|
||||||
|
{
|
||||||
|
frameWidth = screenWidth;
|
||||||
|
frameHeight = (int) (frameWidth / aspectRatio);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
frameHeight = screenHeight;
|
||||||
|
frameWidth = (int) (frameHeight / aspectRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
_spriteBatch.Draw(_video,
|
||||||
|
new Rectangle((screenWidth - frameWidth) / 2, (screenHeight - frameHeight) / 2, frameWidth, frameHeight),
|
||||||
|
Color.White);
|
||||||
|
|
||||||
|
_spriteBatch.End();
|
||||||
|
|
||||||
|
base.Draw(gameTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
_clockEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
_clockEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RenderFrame(byte[] pixelData)
|
||||||
|
{
|
||||||
|
var rawData = new byte[160 * 144 * sizeof(int)];
|
||||||
|
|
||||||
|
for (int i = 0, j = 0; j < pixelData.Length; i+=4, j+=3)
|
||||||
|
{
|
||||||
|
rawData[i] = pixelData[j + 2];
|
||||||
|
rawData[i + 1] = pixelData[j + 1];
|
||||||
|
rawData[i + 2] = pixelData[j];
|
||||||
|
rawData[i + 3] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
_video.SetData(rawData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Emux.GameBoy.Audio;
|
||||||
|
using Emux.GameBoy.Cartridge;
|
||||||
|
|
||||||
|
namespace Emux.MonoGame
|
||||||
|
{
|
||||||
|
internal class AudioOutput : IAudioChannelOutput
|
||||||
|
{
|
||||||
|
public int SampleRate
|
||||||
|
{
|
||||||
|
get { return 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BufferSoundSamples(float[] sampleData, int offset, int length)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
private static void PrintAbout()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Emux.MonoGame: v{0}, Core: v{1}",
|
||||||
|
typeof(Program).Assembly.GetName().Version,
|
||||||
|
typeof(GameBoy.GameBoy).Assembly.GetName().Version);
|
||||||
|
Console.WriteLine("Copyright © Washi 2017-2018");
|
||||||
|
Console.WriteLine("Repository and issue tracker: https://www.github.com/Washi1337/Emux");
|
||||||
|
}
|
||||||
|
|
||||||
|
[STAThread]
|
||||||
|
private static void Main(string[] args)
|
||||||
|
{
|
||||||
|
PrintAbout();
|
||||||
|
|
||||||
|
string romFile;
|
||||||
|
string saveFile;
|
||||||
|
|
||||||
|
switch (args.Length)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
Console.WriteLine("Usage: Emux.MonoGame.exe romfile [savefile]");
|
||||||
|
return;
|
||||||
|
case 1:
|
||||||
|
romFile = args[0].Replace("\"", "");
|
||||||
|
saveFile = Path.ChangeExtension(romFile, ".sav");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
romFile = args[0].Replace("\"", "");
|
||||||
|
saveFile = args[1].Replace("\"", "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!File.Exists(romFile))
|
||||||
|
{
|
||||||
|
Console.WriteLine("ROM could not be found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var game = new EmuxHost())
|
||||||
|
using (var saveFs = File.Open(saveFile, FileMode.OpenOrCreate))
|
||||||
|
{
|
||||||
|
var cartridge = new EmulatedCartridge(File.ReadAllBytes(romFile), new StreamedExternalMemory(saveFs));
|
||||||
|
var device = new GameBoy.GameBoy(cartridge, game, false);
|
||||||
|
game.GameBoy = device;
|
||||||
|
device.Gpu.VideoOutput = game;
|
||||||
|
|
||||||
|
for (var i = 0; i < device.Spu.Channels.Count; i++)
|
||||||
|
{
|
||||||
|
var channel = device.Spu.Channels[i];
|
||||||
|
channel.ChannelOutput = new AudioOutput();
|
||||||
|
channel.ChannelVolume = 0.05f;
|
||||||
|
}
|
||||||
|
|
||||||
|
game.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
Emux.sln
6
Emux.sln
|
@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emux", "Emux\Emux.csproj",
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emux.GameBoy.Tests", "Emux.GameBoy.Tests\Emux.GameBoy.Tests.csproj", "{365C6CF7-99E3-4861-B63B-E9D352E386AF}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emux.GameBoy.Tests", "Emux.GameBoy.Tests\Emux.GameBoy.Tests.csproj", "{365C6CF7-99E3-4861-B63B-E9D352E386AF}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emux.MonoGame", "Emux.MonoGame\Emux.MonoGame.csproj", "{A8CDE19D-11F0-47AB-8391-EFF20F3532FB}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(Performance) = preSolution
|
GlobalSection(Performance) = preSolution
|
||||||
HasPerformanceSessions = true
|
HasPerformanceSessions = true
|
||||||
|
@ -30,6 +32,10 @@ Global
|
||||||
{365C6CF7-99E3-4861-B63B-E9D352E386AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{365C6CF7-99E3-4861-B63B-E9D352E386AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{365C6CF7-99E3-4861-B63B-E9D352E386AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{365C6CF7-99E3-4861-B63B-E9D352E386AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{365C6CF7-99E3-4861-B63B-E9D352E386AF}.Release|Any CPU.Build.0 = Release|Any CPU
|
{365C6CF7-99E3-4861-B63B-E9D352E386AF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A8CDE19D-11F0-47AB-8391-EFF20F3532FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{A8CDE19D-11F0-47AB-8391-EFF20F3532FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A8CDE19D-11F0-47AB-8391-EFF20F3532FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A8CDE19D-11F0-47AB-8391-EFF20F3532FB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
Loading…
Reference in New Issue