From 54ff07fbfc91a71db4f13a4d2a36eeb484123892 Mon Sep 17 00:00:00 2001 From: goyuken Date: Sat, 4 May 2013 01:16:27 +0000 Subject: [PATCH] n64: fix race bug introduced in previous revision. also turn display upside down --- .../Consoles/Nintendo/N64/N64.cs | 20 +++++++++++++----- .../output/dll/mupen64plus-video-rice.dll | Bin 495616 -> 495616 bytes .../output/dll/mupen64plus.dll | Bin 422912 -> 422912 bytes .../mupen64plus-core/src/api/frontend.c | 2 +- .../mupen64plus-core/src/main/main.c | 4 ++-- .../mupen64plus-core/src/main/main.h | 2 +- .../mupen64plus-core/src/r4300/r4300.c | 5 ++++- .../mupen64plus-core/src/r4300/r4300.h | 2 +- .../mupen64plus-video-rice/src/Video.cpp | 2 +- 9 files changed, 25 insertions(+), 12 deletions(-) diff --git a/BizHawk.Emulation/Consoles/Nintendo/N64/N64.cs b/BizHawk.Emulation/Consoles/Nintendo/N64/N64.cs index 88dc14b7dd..e1ef907823 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/N64/N64.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/N64/N64.cs @@ -22,6 +22,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64 public int[] frameBuffer = new int[800 * 600]; public int[] GetVideoBuffer() { + /* for (int row = 0; row < 600; row++) { for (int col = 0; col < 800; col++) @@ -30,6 +31,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64 frameBuffer[(599 - row) * 800 + col] = (m64p_FrameBuffer[(i * 3)] << 16) + (m64p_FrameBuffer[(i * 3) + 1] << 8) + (m64p_FrameBuffer[(i * 3) + 2]); } } + */ return frameBuffer; } public int VirtualWidth { get { return 800; } } @@ -301,7 +303,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64 // Graphics plugin specific [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void ReadScreen2(byte[] framebuffer, ref int width, ref int height, int buffer); + private delegate void ReadScreen2(int[] framebuffer, ref int width, ref int height, int buffer); ReadScreen2 GFXReadScreen2; // Audio plugin specific @@ -343,13 +345,17 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void FrameCallback(); FrameCallback m64pFrameCallback; - - byte[] m64p_FrameBuffer = new byte[800 * 600 * 3]; + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void StartupCallback(); + + //byte[] m64p_FrameBuffer = new byte[800 * 600 * 3]; public void Getm64pFrameBuffer() { int width = 0; int height = 0; - GFXReadScreen2(m64p_FrameBuffer, ref width, ref height, 0); + //GFXReadScreen2(m64p_FrameBuffer, ref width, ref height, 0); + GFXReadScreen2(frameBuffer, ref width, ref height, 0); //m64pFrameComplete = true; } @@ -392,6 +398,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64 AutoResetEvent m64pFrameComplete = new AutoResetEvent(false); + ManualResetEvent m64pStartupComplete = new ManualResetEvent(false); + public N64(CoreComm comm, GameInfo game, byte[] rom) { if (AttachedCore != null) @@ -496,6 +504,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64 } while (state != (int)m64p_emu_state.M64EMU_PAUSED); */ //m64pFrameComplete.WaitOne(); + m64pStartupComplete.WaitOne(); // because of when we're doing this, we can't call this yet m64pSamplingRate = 32000; // (uint)AudGetAudioRate(); @@ -510,7 +519,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.N64 public void ExecuteEmulator() { emulator_running = true; - m64pCoreDoCommandPtr(m64p_command.M64CMD_EXECUTE, 0, IntPtr.Zero); + m64pCoreDoCommandPtr(m64p_command.M64CMD_EXECUTE, 0, + Marshal.GetFunctionPointerForDelegate(new StartupCallback(() => m64pStartupComplete.Set()))); emulator_running = false; } diff --git a/BizHawk.MultiClient/output/dll/mupen64plus-video-rice.dll b/BizHawk.MultiClient/output/dll/mupen64plus-video-rice.dll index d3824cb9678f69d02f834ee43e62646c3003995e..a573f5a3c082a035ab163f3a25df519963200158 100644 GIT binary patch delta 83 zcmZozAlI-!Zi56P6LZpJDMml0vZc*gjO|&BAj|~B%s|YtJ&TdmA&u!_!}c}ltTSYR hYPY+!vg&0rGH)+^$6Bw!^gprvn;6^nZ({6Rl>jWu8qoj% delta 83 zcmZozAlI-!Zi56P(?zGrQjC5~%nzEg7~8WLL6`}MnSq#PdlnjiH8esqc diff --git a/BizHawk.MultiClient/output/dll/mupen64plus.dll b/BizHawk.MultiClient/output/dll/mupen64plus.dll index 29d2896618f1160afb3e5efbcd6392808890c7d2..18ebd5151ba03bd615729e0683f266356add1b91 100644 GIT binary patch delta 17303 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 delta 17275 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