完善
This commit is contained in:
parent
8d0487be8b
commit
68d8c7d3b2
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
//{
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
//}
|
||||
}
|
Loading…
Reference in New Issue
Block a user