From 2fdb7fb26ac56c69efe5a50cb80ae2c16a76fdc7 Mon Sep 17 00:00:00 2001 From: cph5236 <33178603+cph5236@users.noreply.github.com> Date: Fri, 27 Dec 2019 14:29:07 -0500 Subject: [PATCH] Added Sega Genesis support by fixing LibretroWraper.cs switch case XRGB8888 it now uses RGB8888 jobs in unities jobs system, fixed RetroAudioSample function. --- .../RetroUnity/Examples/Scenes/Main.unity | 8 +- .../Plugins/RetroUnity/Scripts/GameManager.cs | 4 +- .../RetroUnity/Scripts/LibretroWrapper.cs | 74 ++++++++++++------- .../Scripts/Materials/MainScreen.mat | 28 +++++++ .../Plugins/RetroUnity/Scripts/RGB8888Job.cs | 19 +++++ 5 files changed, 100 insertions(+), 33 deletions(-) create mode 100644 Assets/Plugins/RetroUnity/Scripts/Materials/MainScreen.mat create mode 100644 Assets/Plugins/RetroUnity/Scripts/RGB8888Job.cs diff --git a/Assets/Plugins/RetroUnity/Examples/Scenes/Main.unity b/Assets/Plugins/RetroUnity/Examples/Scenes/Main.unity index 4cd0c83..cdf5de2 100644 --- a/Assets/Plugins/RetroUnity/Examples/Scenes/Main.unity +++ b/Assets/Plugins/RetroUnity/Examples/Scenes/Main.unity @@ -273,7 +273,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 635089073} m_LocalRotation: {x: 0, y: 0, z: 1, w: -0.00000016292068} - m_LocalPosition: {x: 0, y: 6.2, z: -0.16} + m_LocalPosition: {x: 0, y: 6.2, z: -0.17} m_LocalScale: {x: 14.1, y: 7.3, z: 1} m_Children: [] m_Father: {fileID: 589599783} @@ -517,8 +517,8 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 52ea678dff3796c4c92ab162cb5764bd, type: 3} m_Name: m_EditorClassIdentifier: - CoreName: snes9x_libretro.dll - RomName: Chrono Trigger (USA).sfc + CoreName: blastem_libretro.dll + RomName: LW_build_0479.bin Display: {fileID: 635089074} --- !u!1001 &1178825821 PrefabInstance: @@ -659,7 +659,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1702816979} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalPosition: {x: 0, y: 1.28, z: -2.23} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 0} diff --git a/Assets/Plugins/RetroUnity/Scripts/GameManager.cs b/Assets/Plugins/RetroUnity/Scripts/GameManager.cs index 0b9b810..da0614c 100644 --- a/Assets/Plugins/RetroUnity/Scripts/GameManager.cs +++ b/Assets/Plugins/RetroUnity/Scripts/GameManager.cs @@ -5,8 +5,8 @@ namespace RetroUnity { public class GameManager : MonoBehaviour { - [SerializeField] private string CoreName = "snes9x_libretro.dll"; - [SerializeField] private string RomName = "Chrono Trigger (USA).sfc"; + [SerializeField] private string CoreName = "blastem_libretro.dll"; + [SerializeField] private string RomName = "LW_build_0479.bin"; private LibretroWrapper.Wrapper wrapper; private float _frameTimer; diff --git a/Assets/Plugins/RetroUnity/Scripts/LibretroWrapper.cs b/Assets/Plugins/RetroUnity/Scripts/LibretroWrapper.cs index 64bc7f9..18b1c46 100644 --- a/Assets/Plugins/RetroUnity/Scripts/LibretroWrapper.cs +++ b/Assets/Plugins/RetroUnity/Scripts/LibretroWrapper.cs @@ -21,8 +21,12 @@ using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; +using System.Threading; using RetroUnity.Utility; using UnityEngine; +using Unity.Collections; +using UnityEngine.Profiling; +using Unity.Jobs; namespace RetroUnity { public class LibretroWrapper : MonoBehaviour { @@ -205,7 +209,6 @@ public Pixel[] GetFramebuffer() { } private unsafe void RetroVideoRefresh(void* data, uint width, uint height, uint pitch) { - // Process Pixels one by one for now...this is not the best way to do it // should be using memory streams or something @@ -216,10 +219,10 @@ private unsafe void RetroVideoRefresh(void* data, uint width, uint height, uint //Get the array from unmanaged memory as a pointer var pixels = (IntPtr)data; //Gets The pointer to the row start to use with the pitch - //IntPtr rowStart = pixels; + IntPtr rowStart = pixels; //Get the size to move the pointer - //int size = 0; + int size = 24; uint i; uint j; @@ -258,34 +261,41 @@ private unsafe void RetroVideoRefresh(void* data, uint width, uint height, uint } break; case PixelFormat.RetroPixelFormatXRGB8888: - LibretroWrapper.w = Convert.ToInt32(width); LibretroWrapper.h = Convert.ToInt32(height); - if (tex == null) { - tex = new Texture2D(LibretroWrapper.w, LibretroWrapper.h, TextureFormat.RGB565, false); + if (tex == null||tex.height!= LibretroWrapper.h ||tex.width!=LibretroWrapper.w) { + tex = new Texture2D(LibretroWrapper.w, LibretroWrapper.h, TextureFormat.ARGB32, false); } LibretroWrapper.p = Convert.ToInt32(pitch); - //size = Marshal.SizeOf(typeof(int)); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) { - int packed = Marshal.ReadInt32(pixels); - _frameBuffer[i * width + j] = new Pixel { - Alpha = 1, - Red = ((packed >> 16) & 0x00FF) / 255.0f, - Green = ((packed >> 8) & 0x00FF) / 255.0f, - Blue = (packed & 0x00FF) / 255.0f - }; - var color = new Color(((packed >> 16) & 0x00FF) / 255.0f, ((packed >> 8) & 0x00FF) / 255.0f, (packed & 0x00FF) / 255.0f, 1.0f); - tex.SetPixel((int)i, (int)j, color); - //pixels = (IntPtr)((int)pixels + size); - } - //pixels = (IntPtr)((int)rowStart + pitch); - //rowStart = pixels; - - } - - tex.filterMode = FilterMode.Trilinear; + size = Marshal.SizeOf(typeof(int)); + //Get Pixel Array from Libretro + Int32[] pixelarr = new Int32[width*height]; + Marshal.Copy(pixels, pixelarr, 0, (int)(width * height)); + + //Create Color Array + Color32[] color32arr = new Color32[width*height]; + + //create job handles list + JobHandle jobHandle = new JobHandle(); + //create native pixel array and color array for returning from unity Job + var nativePixelArray = new NativeArray(pixelarr, Allocator.TempJob); + var nativeColorArray = new NativeArray(color32arr, Allocator.TempJob); + + var job = new RGB8888Job + { + pixelarray = nativePixelArray, + color32array = nativeColorArray + }; + jobHandle= (job.Schedule(pixelarr.Length, 1000)); + jobHandle.Complete(); + nativeColorArray.CopyTo(color32arr); + nativePixelArray.Dispose(); + nativeColorArray.Dispose(); + + + tex.SetPixels32(color32arr, 0); + tex.filterMode = FilterMode.Trilinear; tex.Apply(); break; @@ -326,6 +336,14 @@ private unsafe void RetroVideoRefresh(void* data, uint width, uint height, uint private void RetroAudioSample(short left, short right) { // Unused. + float value = left * -0.000030517578125f; + value = Mathf.Clamp(value, -1.0f, 1.0f); // Unity's audio only takes values between -1 and 1. + AudioBatch.Add(value); + + value = right * -0.000030517578125f; + value = Mathf.Clamp(value, -1.0f, 1.0f); // Unity's audio only takes values between -1 and 1. + AudioBatch.Add(value); + } private unsafe void RetroAudioSampleBatch(short* data, uint frames) { @@ -468,6 +486,8 @@ public bool LoadGame(string gamePath) { _av = new SystemAVInfo(); Libretro.RetroGetSystemAVInfo(ref _av); + + var audioConfig = AudioSettings.GetConfiguration(); audioConfig.sampleRate = (int)_av.timing.sample_rate; AudioSettings.Reset(audioConfig); @@ -480,7 +500,7 @@ public bool LoadGame(string gamePath) { Debug.Log("Aspect ratio: " + _av.geometry.aspect_ratio); Debug.Log("Geometry:"); Debug.Log("Target fps: " + _av.timing.fps); - Debug.Log("Sample rate " + _av.timing.sample_rate); + Debug.Log("Sample rate " + _av.timing.sample_rate); return ret; } } diff --git a/Assets/Plugins/RetroUnity/Scripts/Materials/MainScreen.mat b/Assets/Plugins/RetroUnity/Scripts/Materials/MainScreen.mat new file mode 100644 index 0000000..ea74e54 --- /dev/null +++ b/Assets/Plugins/RetroUnity/Scripts/Materials/MainScreen.mat @@ -0,0 +1,28 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: MainScreen + m_Shader: {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _MainTex: + m_Texture: {fileID: 8400000, guid: 17d99b3f7ed959243b29881f8c962052, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: [] + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/Plugins/RetroUnity/Scripts/RGB8888Job.cs b/Assets/Plugins/RetroUnity/Scripts/RGB8888Job.cs new file mode 100644 index 0000000..93a17c8 --- /dev/null +++ b/Assets/Plugins/RetroUnity/Scripts/RGB8888Job.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Unity.Collections; +using Unity.Jobs; +using UnityEngine; +using UnityEngine.Profiling; + +public struct RGB8888Job : IJobParallelFor +{ + public NativeArray pixelarray; + public NativeArray color32array; + public void Execute(int index) + { + int packed = pixelarray[index]; + + color32array[index] = new Color32((Byte)((packed >> 16) & 0x00FF), (Byte)((packed >> 8) & 0x00FF), (Byte)(packed & 0x00FF), (Byte)((packed >> 24) & 0x00FF)); + } +}