using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text; namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi { class mupen64plusVideoApi { IntPtr GfxDll;// Graphics plugin specific [DllImport("kernel32.dll")] public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); /// /// Fills a provided buffer with the mupen64plus framebuffer /// /// The buffer to fill /// A pointer to a variable to fill with the width of the framebuffer /// A pointer to a variable to fill with the height of the framebuffer /// Which buffer to read: 0 = front, 1 = back [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void ReadScreen2(int[] framebuffer, ref int width, ref int height, int buffer); ReadScreen2 GFXReadScreen2; /// /// Gets the width and height of the mupen64plus framebuffer /// /// Use IntPtr.Zero /// A pointer to a variable to fill with the width of the framebuffer /// A pointer to a variable to fill with the height of the framebuffer /// Which buffer to read: 0 = front, 1 = back [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void ReadScreen2Res(IntPtr dummy, ref int width, ref int height, int buffer); ReadScreen2Res GFXReadScreen2Res; [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate Int32 GetScreenTextureID(); GetScreenTextureID GFXGetScreenTextureID; public mupen64plusVideoApi(mupen64plusApi core, VideoPluginSettings settings) { string videoplugin; switch (settings.Plugin) { default: case PluginType.Rice: videoplugin = "mupen64plus-video-rice.dll"; break; case PluginType.Glide: videoplugin = "mupen64plus-video-glide64.dll"; break; case PluginType.GlideMk2: videoplugin = "mupen64plus-video-glide64mk2.dll"; break; case PluginType.Jabo: videoplugin = "mupen64plus-video-jabo.dll"; break; } GfxDll = core.AttachPlugin(mupen64plusApi.m64p_plugin_type.M64PLUGIN_GFX, videoplugin); GFXReadScreen2 = (ReadScreen2)Marshal.GetDelegateForFunctionPointer(GetProcAddress(GfxDll, "ReadScreen2"), typeof(ReadScreen2)); GFXReadScreen2Res = (ReadScreen2Res)Marshal.GetDelegateForFunctionPointer(GetProcAddress(GfxDll, "ReadScreen2"), typeof(ReadScreen2Res)); if(GetProcAddress(GfxDll, "GetScreenTextureID") != IntPtr.Zero) GFXGetScreenTextureID = (GetScreenTextureID)Marshal.GetDelegateForFunctionPointer(GetProcAddress(GfxDll, "GetScreenTextureID"), typeof(GetScreenTextureID)); } public void GetScreenDimensions(ref int width, ref int height) { GFXReadScreen2Res(IntPtr.Zero, ref width, ref height, 0); } private int[] m64pBuffer = new int[0]; /// /// This function copies the frame buffer from mupen64plus /// public void Getm64pFrameBuffer(int[] buffer, ref int width, ref int height) { if (m64pBuffer.Length != width * height) m64pBuffer = new int[width * height]; // Actually get the frame buffer GFXReadScreen2(m64pBuffer, ref width, ref height, 0); // vflip int fromindex = width * (height - 1) * 4; int toindex = 0; for (int j = 0; j < height; j++) { Buffer.BlockCopy(m64pBuffer, fromindex, buffer, toindex, width * 4); fromindex -= width * 4; toindex += width * 4; } // opaque unsafe { fixed (int* ptr = &buffer[0]) { int l = buffer.Length; for (int i = 0; i < l; i++) { ptr[i] |= unchecked((int)0xff000000); } } } } } public class VideoPluginSettings { public PluginType Plugin; //public Dictionary IntParameters = new Dictionary(); //public Dictionary StringParameters = new Dictionary(); public Dictionary Parameters = new Dictionary(); public int Height; public int Width; public VideoPluginSettings(PluginType Plugin, int Width, int Height) { this.Plugin = Plugin; this.Width = Width; this.Height = Height; } } }