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
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emux.GameBoy.Tests", "Emux.GameBoy.Tests\Emux.GameBoy.Tests.csproj", "{365C6CF7-99E3-4861-B63B-E9D352E386AF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emux.MonoGame", "Emux.MonoGame\Emux.MonoGame.csproj", "{A8CDE19D-11F0-47AB-8391-EFF20F3532FB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(Performance) = preSolution
|
||||
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}.Release|Any CPU.ActiveCfg = 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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
Loading…
Reference in New Issue