mirror of
https://github.com/BluestormDNA/ProjectPSX.git
synced 2024-05-20 12:57:38 -04:00
Project: Add barebones OpenTK frontend
This hopefully works on Linux...
This commit is contained in:
parent
4f5f276b2e
commit
a90ff95999
66
ProjectPSX.OpenTK/AudioPlayer.cs
Normal file
66
ProjectPSX.OpenTK/AudioPlayer.cs
Normal file
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using OpenToolkit.Audio.OpenAL;
|
||||
using OpenToolkit.Mathematics;
|
||||
|
||||
namespace ProjectPSX.OpenTK {
|
||||
|
||||
public class AudioPlayer {
|
||||
int audioSource;
|
||||
ALDevice audioDevice;
|
||||
ALContext audioContext;
|
||||
int queueLength = 0;
|
||||
public bool fastForward;
|
||||
public bool audioDisabled;
|
||||
|
||||
public AudioPlayer() {
|
||||
audioDevice = ALC.OpenDevice(null);
|
||||
if (audioDevice == null) {
|
||||
Console.WriteLine("Unable to create audio device");
|
||||
return;
|
||||
}
|
||||
audioContext = ALC.CreateContext(audioDevice, (int[])null);
|
||||
ALC.MakeContextCurrent(audioContext);
|
||||
audioSource = AL.GenSource();
|
||||
AL.Listener(ALListener3f.Position, 0, 0, 0);
|
||||
AL.Listener(ALListener3f.Velocity, 0, 0, 0);
|
||||
var orientation = new Vector3(0, 0, 0);
|
||||
AL.Listener(ALListenerfv.Orientation, ref orientation, ref orientation);
|
||||
fastForward = false;
|
||||
audioDisabled = false;
|
||||
}
|
||||
|
||||
public unsafe void UpdateAudio(byte[] samples) {
|
||||
int processed = 0;
|
||||
int alBuffer = 0;
|
||||
|
||||
while (true) {
|
||||
AL.GetSource(audioSource, ALGetSourcei.BuffersProcessed, out processed);
|
||||
|
||||
while (processed-- > 0) {
|
||||
AL.SourceUnqueueBuffers(audioSource, 1, ref alBuffer);
|
||||
AL.DeleteBuffer(alBuffer);
|
||||
queueLength--;
|
||||
}
|
||||
|
||||
if (queueLength < 5 || fastForward) break;
|
||||
}
|
||||
|
||||
if (queueLength < 5) {
|
||||
alBuffer = AL.GenBuffer();
|
||||
AL.BufferData(alBuffer, ALFormat.Stereo16, samples, samples.Length, 44100);
|
||||
AL.SourceQueueBuffer(audioSource, alBuffer);
|
||||
queueLength++;
|
||||
}
|
||||
|
||||
if (AL.GetSourceState(audioSource) != ALSourceState.Playing)
|
||||
AL.SourcePlay(audioSource);
|
||||
|
||||
}
|
||||
|
||||
// Is this automatically called by GC?
|
||||
~AudioPlayer() {
|
||||
ALC.DestroyContext(audioContext);
|
||||
ALC.CloseDevice(audioDevice);
|
||||
}
|
||||
}
|
||||
}
|
25
ProjectPSX.OpenTK/Program.cs
Normal file
25
ProjectPSX.OpenTK/Program.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
using OpenToolkit.Mathematics;
|
||||
using OpenToolkit.Windowing.Desktop;
|
||||
using System;
|
||||
|
||||
namespace ProjectPSX.OpenTK {
|
||||
static class Program {
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main() {
|
||||
GameWindowSettings settings = new GameWindowSettings();
|
||||
settings.RenderFrequency = 60;
|
||||
settings.UpdateFrequency = 60;
|
||||
NativeWindowSettings nativeWindow = new NativeWindowSettings();
|
||||
nativeWindow.Size = new Vector2i(1024, 512);
|
||||
nativeWindow.Title = "ProjectPSX";
|
||||
nativeWindow.Profile = OpenToolkit.Windowing.Common.ContextProfile.Compatability;
|
||||
|
||||
Window window = new Window(settings, nativeWindow);
|
||||
window.VSync = OpenToolkit.Windowing.Common.VSyncMode.On;
|
||||
window.Run();
|
||||
}
|
||||
}
|
||||
}
|
20
ProjectPSX.OpenTK/ProjectPSX.OpenTK.csproj
Normal file
20
ProjectPSX.OpenTK/ProjectPSX.OpenTK.csproj
Normal file
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="OpenTK" Version="4.0.0-pre9.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ProjectPSX\ProjectPSX.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
136
ProjectPSX.OpenTK/Window.cs
Normal file
136
ProjectPSX.OpenTK/Window.cs
Normal file
|
@ -0,0 +1,136 @@
|
|||
using OpenToolkit.Windowing.Common;
|
||||
using OpenToolkit.Windowing.Desktop;
|
||||
using OpenToolkit.Graphics.OpenGL;
|
||||
using System.Collections.Generic;
|
||||
using OpenToolkit.Windowing.Common.Input;
|
||||
using ProjectPSX.Devices.Input;
|
||||
using System;
|
||||
|
||||
namespace ProjectPSX.OpenTK {
|
||||
public class Window : GameWindow, IHostWindow {
|
||||
|
||||
private ProjectPSX psx;
|
||||
private int[] displayBuffer;
|
||||
private Dictionary<Key, GamepadInputsEnum> _gamepadKeyMap;
|
||||
private AudioPlayer audioPlayer = new AudioPlayer();
|
||||
|
||||
public Window(GameWindowSettings gameWindowSettings, NativeWindowSettings nativeWindowSettings) : base(gameWindowSettings, nativeWindowSettings) {
|
||||
psx = new ProjectPSX(this, @"C:\Users\Wapens\source\repos\ProjectPSX\ProjectPSX\bin\r4.bin");
|
||||
psx.POWER_ON();
|
||||
|
||||
_gamepadKeyMap = new Dictionary<Key, GamepadInputsEnum>() {
|
||||
{ Key.Space, GamepadInputsEnum.Space},
|
||||
{ Key.Z , GamepadInputsEnum.Z },
|
||||
{ Key.C , GamepadInputsEnum.C },
|
||||
{ Key.Enter , GamepadInputsEnum.Enter },
|
||||
{ Key.Up , GamepadInputsEnum.Up },
|
||||
{ Key.Right , GamepadInputsEnum.Right },
|
||||
{ Key.Down , GamepadInputsEnum.Down },
|
||||
{ Key.Left , GamepadInputsEnum.Left },
|
||||
{ Key.F1 , GamepadInputsEnum.D1 },
|
||||
{ Key.F3 , GamepadInputsEnum.D3 },
|
||||
{ Key.Q , GamepadInputsEnum.Q },
|
||||
{ Key.E , GamepadInputsEnum.E },
|
||||
{ Key.W , GamepadInputsEnum.W },
|
||||
{ Key.D , GamepadInputsEnum.D },
|
||||
{ Key.S , GamepadInputsEnum.S },
|
||||
{ Key.A , GamepadInputsEnum.A },
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnLoad() {
|
||||
GL.Enable(EnableCap.Blend);
|
||||
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
GL.DepthFunc(DepthFunction.Lequal);
|
||||
GL.Enable(EnableCap.Texture2D);
|
||||
GL.ClearColor(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
protected override void OnRenderFrame(FrameEventArgs args) {
|
||||
//Console.WriteLine(this.RenderFrequency);
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||
|
||||
int id = GL.GenTexture();
|
||||
GL.BindTexture(TextureTarget.Texture2D, id);
|
||||
|
||||
GL.TexImage2D(TextureTarget.Texture2D, 0,
|
||||
PixelInternalFormat.Rgb,
|
||||
1024, 512, 0,
|
||||
PixelFormat.Bgra,
|
||||
PixelType.UnsignedByte,
|
||||
displayBuffer);
|
||||
|
||||
GL.TexParameter(TextureTarget.Texture2D,
|
||||
TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
|
||||
GL.TexParameter(TextureTarget.Texture2D,
|
||||
TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
|
||||
|
||||
GL.Begin(PrimitiveType.Quads);
|
||||
GL.TexCoord2(0, 1); GL.Vertex2(-1, -1);
|
||||
GL.TexCoord2(1, 1); GL.Vertex2(1, -1);
|
||||
GL.TexCoord2(1, 0); GL.Vertex2(1, 1);
|
||||
GL.TexCoord2(0, 0); GL.Vertex2(-1, 1);
|
||||
GL.End();
|
||||
|
||||
GL.DeleteTexture(id);
|
||||
SwapBuffers();
|
||||
//Console.WriteLine("painting");
|
||||
}
|
||||
|
||||
protected override void OnUpdateFrame(FrameEventArgs args) {
|
||||
base.OnUpdateFrame(args);
|
||||
psx.RunFrame();
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyboardKeyEventArgs e) {
|
||||
GamepadInputsEnum? button = GetGamepadButton(e.Key);
|
||||
if (button != null)
|
||||
psx.JoyPadDown(button.Value);
|
||||
}
|
||||
|
||||
protected override void OnKeyUp(KeyboardKeyEventArgs e) {
|
||||
GamepadInputsEnum? button = GetGamepadButton(e.Key);
|
||||
if (button != null)
|
||||
psx.JoyPadUp(button.Value);
|
||||
}
|
||||
|
||||
private GamepadInputsEnum? GetGamepadButton(Key keyCode) {
|
||||
if (_gamepadKeyMap.TryGetValue(keyCode, out GamepadInputsEnum gamepadButtonValue))
|
||||
return gamepadButtonValue;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Update(int[] bits) {
|
||||
displayBuffer = bits;
|
||||
}
|
||||
|
||||
public int GetFPS() {
|
||||
return (int)RenderFrequency;
|
||||
}
|
||||
|
||||
public void SetWindowText(string newText) {
|
||||
this.Title = newText;
|
||||
}
|
||||
|
||||
public void SetDisplayMode(int horizontalRes, int verticalRes, bool is24BitDepth) {
|
||||
//throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetHorizontalRange(ushort displayX1, ushort displayX2) {
|
||||
//throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetVRAMStart(ushort displayVRAMXStart, ushort displayVRAMYStart) {
|
||||
//throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetVerticalRange(ushort displayY1, ushort displayY2) {
|
||||
//throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void Play(byte[] samples) {
|
||||
audioPlayer.UpdateAudio(samples);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProjectPSX.WinForms", "Proj
|
|||
{6351ED6D-2403-43EE-8DD8-EB7E796B41EB} = {6351ED6D-2403-43EE-8DD8-EB7E796B41EB}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectPSX.OpenTK", "ProjectPSX.OpenTK\ProjectPSX.OpenTK.csproj", "{8206B712-6B1E-4DEE-8156-5757EDBD3315}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{6351ED6D-2403-43EE-8DD8-EB7E796B41EB} = {6351ED6D-2403-43EE-8DD8-EB7E796B41EB}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -44,6 +49,18 @@ Global
|
|||
{826358E3-4610-4688-96DD-86963BE51A58}.Release|x64.Build.0 = Release|Any CPU
|
||||
{826358E3-4610-4688-96DD-86963BE51A58}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{826358E3-4610-4688-96DD-86963BE51A58}.Release|x86.Build.0 = Release|Any CPU
|
||||
{8206B712-6B1E-4DEE-8156-5757EDBD3315}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8206B712-6B1E-4DEE-8156-5757EDBD3315}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8206B712-6B1E-4DEE-8156-5757EDBD3315}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{8206B712-6B1E-4DEE-8156-5757EDBD3315}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{8206B712-6B1E-4DEE-8156-5757EDBD3315}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{8206B712-6B1E-4DEE-8156-5757EDBD3315}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{8206B712-6B1E-4DEE-8156-5757EDBD3315}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8206B712-6B1E-4DEE-8156-5757EDBD3315}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8206B712-6B1E-4DEE-8156-5757EDBD3315}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{8206B712-6B1E-4DEE-8156-5757EDBD3315}.Release|x64.Build.0 = Release|Any CPU
|
||||
{8206B712-6B1E-4DEE-8156-5757EDBD3315}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8206B712-6B1E-4DEE-8156-5757EDBD3315}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
Loading…
Reference in a new issue