This commit is contained in:
sin365 2024-08-16 21:50:32 +08:00
parent 8d0487be8b
commit 68d8c7d3b2
6 changed files with 115 additions and 144 deletions

View File

@ -182,11 +182,11 @@ MonoBehaviour:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 14
m_FontSize: 53
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_MaxSize: 53
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
@ -907,8 +907,8 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -471, y: -281}
m_SizeDelta: {x: 160, y: 30}
m_AnchoredPosition: {x: -560.94934, y: -316.46082}
m_SizeDelta: {x: 339.8987, y: 100.9216}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1712987039
MonoBehaviour:

View File

@ -14,9 +14,9 @@ public class AudioProvider : MonoBehaviour
public void Awake()
{
//var dummy = AudioClip.Create("dummy", 1,2, AudioSettings.outputSampleRate, false);
AudioClip clip = AudioClip.Create("blank", GbaAudio.SampleRate * 2, 2, GbaAudio.SampleRate, true);
_buffer = new RingBuffer<float>(GbaAudio.SampleRate * 2);
AudioClip clip = AudioClip.Create("dummy", GbaAudio.SampleRate * 2, 2, GbaAudio.SampleRate, true);
AudioSettings.GetDSPBufferSize(out int bufferLength, out _);
_buffer = new RingBuffer<float>(bufferLength * 2 * 2);
m_as.clip = clip;
m_as.playOnAwake = true;
//m_as.loop = true;
@ -36,13 +36,9 @@ public class AudioProvider : MonoBehaviour
for (int i = 0; i < data.Length; i += step)
{
if (_buffer.TryRead(out float rawData))
{
data[i] = rawData;
}
else
{
break;
}
}
//int step = channels;

View File

@ -28,9 +28,9 @@ public class Emulator : MonoBehaviour
Thread EmulationThread;
AutoResetEvent ThreadSync = new AutoResetEvent(false);
private int _samplesAvailable;
//private int _samplesAvailable;
//private PipeStream _pipeStream;
private byte[] _buffer;
//private byte[] _buffer;
public float audioGain = 1.0f;
// key delegate
@ -42,19 +42,11 @@ public class Emulator : MonoBehaviour
private void Awake()
{
instance = this;
//BetterStreamingAssets.Initialize();
// must set it to 60 or it won't sync with audio or run too fast.
Application.targetFrameRate = (int)FrameRate;
//audioSource = GetComponent<AudioSource>();
//AudioClip clip = AudioClip.Create("blank", GbaAudio.SampleRate * 2, 2, GbaAudio.SampleRate, true);
//audioSource.clip = clip;
//audioSource.playOnAwake = true;
//audioSource.enabled = false;
//screenRenderer.material.mainTexture = new Texture2D(240, 160, TextureFormat.RGBA32, false, false);
// Get Unity Buffer size
AudioSettings.GetDSPBufferSize(out int bufferLength, out _);
_samplesAvailable = bufferLength;
//AudioSettings.GetDSPBufferSize(out int bufferLength, out _);
//_samplesAvailable = bufferLength;
// Must be set to 32768
var audioConfig = AudioSettings.GetConfiguration();
audioConfig.sampleRate = GbaAudio.SampleRate;
@ -62,7 +54,7 @@ public class Emulator : MonoBehaviour
// Prepare our buffer
//_pipeStream = new PipeStream();
//_pipeStream.MaxBufferLength = _samplesAvailable * 2 * sizeof(float);
_buffer = new byte[_samplesAvailable * 2 * sizeof(float)];
//_buffer = new byte[_samplesAvailable * 2 * sizeof(float)];
}
void Start()
{
@ -155,15 +147,15 @@ public class Emulator : MonoBehaviour
}
}
public int GetOutputSampleRate()
{
return AudioSettings.outputSampleRate;
}
//public int GetOutputSampleRate()
//{
// return AudioSettings.outputSampleRate;
//}
public int GetSamplesAvailable()
{
return _samplesAvailable;
}
//public int GetSamplesAvailable()
//{
// return _samplesAvailable;
//}
//private void OnAudioFilterRead(float[] data, int channels)
//{

View File

@ -33,6 +33,8 @@ public class EmulatorGUI : MonoBehaviour
#if UNITY_EDITOR || UNITY_STANDALONE
bool input = Input.GetKey( keyboardKeyCodeMap[keyCode]);
if(input) return true;else return false;
#else
return false;
#endif
}
}

View File

@ -6,6 +6,10 @@ using static OptimeGBA.MemoryUtil;
using Unity.Burst.Intrinsics;
using static Unity.Burst.Intrinsics.X86;
#if UNITY_STANDALONE_WIN || UNITY_EDITOR
#else
#endif
namespace OptimeGBA
{
public sealed unsafe class PpuRenderer
@ -39,7 +43,7 @@ namespace OptimeGBA
WinMasks = MemoryUtil.AllocateUnmanagedArray(Width + 16);
BgLo = MemoryUtil.AllocateUnmanagedArray32(width + 16);
BgHi = MemoryUtil.AllocateUnmanagedArray32(width + 16);
#else
#else
ScreenFront = new ushort[ScreenBufferSize];
ScreenBack = new ushort[ScreenBufferSize];
@ -613,86 +617,91 @@ namespace OptimeGBA
v256 indicesVec;
uint paletteRow = 0;
if (bg.Use8BitColor)
{
clearMaskVec = new v256(0xFFU);
//mm256_cvtepu8_epi32 用于将无符号的8位整数uint8转换成32位整数int32
uint vramTileAddr = charBase + tileNumber * 64 + effectiveIntraTileY * 8;
ulong data = GetUlong(vram, vramTileAddr);
//{
// if (bg.Use8BitColor)
// {
// clearMaskVec = new v256(0xFFU);
if (data != 0)
{
indicesVec = Avx2.mm256_cvtepu8_epi32(new v128(data));
if (xFlip)
{
// First, reverse within 128-bit lanes
indicesVec = Avx2.mm256_shuffle_epi32(indicesVec, 0b00_01_10_11);
// Then, swap upper and lower halves
indicesVec = Avx2.mm256_permute2x128_si256(indicesVec, indicesVec, 1);
}
indicesVec = Avx2.mm256_and_si256(indicesVec, clearMaskVec);
}
else
{
pixelX += 8;
lineIndex += 8;
continue;
}
}
else
{
clearMaskVec = new v256(0xFU);
// uint vramTileAddr = charBase + tileNumber * 64 + effectiveIntraTileY * 8;
// ulong data = GetUlong(vram, vramTileAddr);
paletteRow = (mapEntry >> 12) & 0xF;
uint vramTileAddr = charBase + tileNumber * 32 + effectiveIntraTileY * 4;
// if (data != 0)
// {
// indicesVec = Avx2.mm256_cvtepu8_epi32(new v128(data));
// if (xFlip)
// {
// // First, reverse within 128-bit lanes
// indicesVec = Avx2.mm256_shuffle_epi32(indicesVec, 0b00_01_10_11);
// // Then, swap upper and lower halves
// indicesVec = Avx2.mm256_permute2x128_si256(indicesVec, indicesVec, 1);
// }
// indicesVec = Avx2.mm256_and_si256(indicesVec, clearMaskVec);
// }
// else
// {
// pixelX += 8;
// lineIndex += 8;
// continue;
// }
// }
// else
// {
// clearMaskVec = new v256(0xFU);
uint data = GetUint(vram, vramTileAddr);
// paletteRow = (mapEntry >> 12) & 0xF;
// uint vramTileAddr = charBase + tileNumber * 32 + effectiveIntraTileY * 4;
if (data != 0)
{
v256 shifts;
if (xFlip)
{
shifts = new v256(28U, 24U, 20U, 16U, 12U, 8U, 4U, 0U);
}
else
{
shifts = new v256(0U, 4U, 8U, 12U, 16U, 20U, 24U, 28U);
}
indicesVec = new v256(data);
indicesVec = Avx2.mm256_srlv_epi32(indicesVec, shifts);
indicesVec = Avx2.mm256_and_si256(indicesVec, clearMaskVec);
}
else
{
pixelX += 8;
lineIndex += 8;
continue;
}
}
// uint data = GetUint(vram, vramTileAddr);
v256 color = Avx2.mm256_i32gather_epi32((int*)((ushort*)palettes + paletteRow * 16), indicesVec, sizeof(ushort));
color = Avx2.mm256_and_si256(color, new v256(0xFFFF));
// Weave metadata (priority, ID) into color data
color = Avx2.mm256_or_si256(color, Avx2.mm256_slli_epi32(metaVec, 16));
// if (data != 0)
// {
// v256 shifts;
// if (xFlip)
// {
// shifts = new v256(28U, 24U, 20U, 16U, 12U, 8U, 4U, 0U);
// }
// else
// {
// shifts = new v256(0U, 4U, 8U, 12U, 16U, 20U, 24U, 28U);
// }
// indicesVec = new v256(data);
// indicesVec = Avx2.mm256_srlv_epi32(indicesVec, shifts);
// indicesVec = Avx2.mm256_and_si256(indicesVec, clearMaskVec);
// }
// else
// {
// pixelX += 8;
// lineIndex += 8;
// continue;
// }
// }
ulong addr = GetUlong(winMasks, lineIndex);
v256 winMask = Avx2.mm256_cvtepi8_epi32(new v128(addr));
winMask = Avx2.mm256_and_si256(winMask, metaVec);
winMask = Avx2.mm256_cmpeq_epi32(winMask, new v256((byte)0));
// Get important color bits
v256 clear = Avx2.mm256_and_si256(indicesVec, clearMaskVec);
// Are those bits clear?
clear = Avx2.mm256_cmpeq_epi32(clear, new v256(0));
// Merge with window mask
winMask = Avx2.mm256_or_si256(winMask, clear);
winMask = Avx2.mm256_xor_si256(winMask, new v256(int.MinValue));
// v256 color = Avx2.mm256_i32gather_epi32((int*)((ushort*)palettes + paletteRow * 16), indicesVec, sizeof(ushort));
// color = Avx2.mm256_and_si256(color, new v256(0xFFFF));
// // Weave metadata (priority, ID) into color data
// color = Avx2.mm256_or_si256(color, Avx2.mm256_slli_epi32(metaVec, 16));
// ulong addr = GetUlong(winMasks, lineIndex);
// v256 winMask = Avx2.mm256_cvtepi8_epi32(new v128(addr));
// winMask = Avx2.mm256_and_si256(winMask, metaVec);
// winMask = Avx2.mm256_cmpeq_epi32(winMask, new v256((byte)0));
// // Get important color bits
// v256 clear = Avx2.mm256_and_si256(indicesVec, clearMaskVec);
// // Are those bits clear?
// clear = Avx2.mm256_cmpeq_epi32(clear, new v256(0));
// // Merge with window mask
// winMask = Avx2.mm256_or_si256(winMask, clear);
// winMask = Avx2.mm256_xor_si256(winMask, new v256(int.MinValue));
// // Push back covered pixels from hi to lo
// // This render the front image
// Avx2.mm256_maskstore_epi32((void*)(lo + lineIndex), winMask, Avx2.mm256_stream_load_si256((void*)(hi + lineIndex)));
// // This render the background, has some bugs
// Avx2.mm256_maskstore_epi32((void*)(hi + lineIndex), winMask, color);
//}
// Push back covered pixels from hi to lo
// This render the front image
Avx2.mm256_maskstore_epi32((void*)(lo + lineIndex), winMask, Avx2.mm256_stream_load_si256((void*)(hi + lineIndex)));
// This render the background, has some bugs
Avx2.mm256_maskstore_epi32((void*)(hi + lineIndex), winMask, color);
pixelX += 8;
lineIndex += 8;

View File

@ -13,12 +13,10 @@ public class VideoProvider : MonoBehaviour
private Texture2D wrapTex;
private int TexBufferSize;
uint[] wrapTexBuffer = new uint[240 * 160];
Color32[] DisplayColorBuffer = new Color32[240 * 160];
//Color32[] DisplayColorBuffer = new Color32[240 * 160];
public void OnRenderFrame()
private void Awake()
{
if (wrapTex == null)
{
@ -39,10 +37,9 @@ public class VideoProvider : MonoBehaviour
m_drawCanvasrect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, targetWidth);
}
DrawDisplay();
}
public void DrawDisplay()
public void OnRenderFrame()
{
var buf = Emulator.instance.ShowBackBuf ? Emulator.instance.gba.Ppu.Renderer.ScreenBack : Emulator.instance.gba.Ppu.Renderer.ScreenFront;
unsafe
@ -50,41 +47,16 @@ public class VideoProvider : MonoBehaviour
for (uint i = 0; i < 240 * 160; i++)
{
wrapTexBuffer[i] = PpuRenderer.ColorLutCorrected[buf[i] & 0x7FFF];
fixed (uint* p = &wrapTexBuffer[i])
{
byte* bp = (byte*)p;
DisplayColorBuffer[i] = new Color32(*(bp++), *(bp++), *(bp++), *(bp++));
}
//fixed (uint* p = &wrapTexBuffer[i])
//{
// byte* bp = (byte*)p;
// DisplayColorBuffer[i] = new Color32(*(bp++), *(bp++), *(bp++), *(bp++));
//}
}
}
//wrapTex.LoadRawTextureData(wrapTexBufferPointer, TexBufferSize);
wrapTex.SetPixels32(DisplayColorBuffer, 0);
wrapTex.LoadRawTextureData(wrapTexBufferPointer, TexBufferSize);
//wrapTex.SetPixels32(DisplayColorBuffer, 0);
wrapTex.Apply();
}
//public void SetDrawData(uint[] screenData, byte[] lineColorMode, int screenWidth, int screenHeight)
//{
// if (wrapTex == null)
// {
// //wrapTex = new Texture2D(272, 240, TextureFormat.BGRA32, false);
// wrapTex = new Texture2D(272, 240, TextureFormat.RGBA32, false);
// wrapTex.filterMode = FilterMode.Point;
// wrapTexBuffer = screenData;
// // 固定数组,防止垃圾回收器移动它
// GCHandle handle = GCHandle.Alloc(wrapTexBuffer, GCHandleType.Pinned);
// // 获取数组的指针
// wrapTexBufferPointer = handle.AddrOfPinnedObject();
// Image.texture = wrapTex;
// Image.material.SetTexture("_MainTex", wrapTex);
// TexBufferSize = wrapTexBuffer.Length * 4;
// }
// wrapTex.LoadRawTextureData(wrapTexBufferPointer, TexBufferSize);
// wrapTex.Apply();
//}
}