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;
}
}
}