Results 1 to 2 of 2
  1. #1
    EmuTalk Member
    Join Date
    Sep 2006
    Posts
    1

    N64 Help w/ N64 Plugins & VB.Net...

    Hello,



    I started a new project yesterday as I’ve been sick the past couple of days , so I have some free programming time on my hands.

    For the fun of it I started to make a frontend for one of my N64 emulators & the 1st thing on my list was to conquer the plugins.

    Accessing them is pretty simple with a couple of API’s, pretty much the same as if you were to load a PSX plugin, like so:

    Code:
     
        <DllImport _
        ("kernel32.dll", CallingConvention:=CallingConvention.Winapi, _
         EntryPoint:="LoadLibraryA", CharSet:=CharSet.Ansi)> _
        Private Function LoadLibrary(ByVal lpLibFileName As String) As Integer
        End Function
    
        <DllImport _
         ("kernel32.dll", CallingConvention:=CallingConvention.Winapi, _
          EntryPoint:="GetProcAddress", CharSet:=CharSet.Ansi)> _
        Private Function GetProcAddress(ByVal hModule As Integer, ByVal lpProcName As String) As Integer
        End Function
    
        <DllImport _
        ("kernel32.dll", CallingConvention:=CallingConvention.Winapi, _
         EntryPoint:="FreeLibrary", CharSet:=CharSet.Ansi)> _
        Private Function FreeLibrary(ByVal hModule As Integer) As Integer
        End Function
    
        <DllImport("user32.dll", CallingConvention:=CallingConvention.Winapi, _
        EntryPoint:="CallWindowProcA", CharSet:=CharSet.Auto)> _
        Private Function CallWindowProc(ByVal lpPrevWndFunc As Integer, _
        ByVal hwnd As Integer, ByVal Msg As Integer, ByVal wParam As Integer, _
        ByVal lParam As Integer) As Integer
        End Function
    
        Public Sub PlugConfig(ByVal PlugPath As String)
            Dim hProc, hModule, hResult As Integer
            hModule = LoadLibrary(PlugPath)
    
            hProc = GetProcAddress(hModule, About)
            If hProc Then
                hResult = CallWindowProc(hProc, 0, 0, 0, 0)
            End If
    
            hProc = GetProcAddress(hModule, "DllConfig")
            FreeLibrary(hModule)
        End Sub
    
        Public Sub PlugAbout(ByVal PlugPath As String)
            Dim hProc, hModule, hResult As Integer
            hModule = LoadLibrary(PlugPath)
    
            hProc = GetProcAddress(hModule, About)
    
            If hProc Then
                hResult = CallWindowProc(hProc, 0, 0, 0, 0)
            End If
    
            hProc = GetProcAddress(hModule, "DllAbout")
            FreeLibrary(hModule)
        End Sub
    Then on a button or your pref. of control call:

    Code:
    PlugConfig(“C:\YourPath\YourPluggin.dll”)
    Or

    Code:
    PlugAbout(“C:\YourPath\YourPluggin.dll”)
    However I am wondering how I might go about using “GetDllInfo” to gather all the information about the plugin. So far all my attempts to accomplish this have been unsuccessful, any ideas on accomplishing this in VB .NET?

    This is my 1st time tackling an N64 EMU-based project & I am not finding too many technical docs on the subject, any recommendations?

    Thanks much!


    • Advertising

      advertising
      EmuTalk.net
      has no influence
      on the ads that
      are displayed
        
       

  2. #2
    EmuTalk Member
    Join Date
    May 2003
    Location
    Montreal
    Posts
    6
    Here is the code that I use to talk to a plugin (this is converted from C#, so I'm not sure if the converter messed stuff).

    Code:
    Imports System
    Imports System.Collections.Generic
    Imports System.ComponentModel
    Imports System.Runtime.InteropServices
    Imports System.Text
    
    Namespace CWDev.N64Emulator.Plugins
    
        Public Enum PluginType As Short
            RSP = 1
            Graphic = 2
            Audio = 3
            Controller = 4
        End Enum
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
        Friend Structure PluginInfo
            Public Version As UInt16
            Public Type As PluginType
    
            <MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst:=100)> _
            Public Name As String
    
            Public NormalMemory As Boolean
            Public MemoryBswaped As Boolean
        End Structure
    
        Public Class Plugin
            Implements IDisposable
    
            Public Sub New(ByVal dllName As String)
                m_dllName = dllName
                m_dllWrapper = New UnmanagedDllWrapper(dllName)
    
                m_delegateGetDllInfo = CType(GetDelegate("GetDllInfo", GetType(DelegateGetPluginInfo)), DelegateGetPluginInfo)
                If m_delegateGetDllInfo Is Nothing Then
                    Throw New Exception(String.Format("Cannot find function 'GetDllInfo' in '{0}'!", m_dllName))
                End If
    
                m_pluginInfo = New PluginInfo()
                GetDllInfo(m_pluginInfo)
    
                m_dllAboutDelegate = CType(GetDelegate("DllAbout", GetType(DllAboutDelegate)), DllAboutDelegate)
                m_dllConfigDelegate = CType(GetDelegate("DllConfig", GetType(DllConfigDelegate)), DllConfigDelegate)
                m_dllTestDelegate = CType(GetDelegate("DllTest", GetType(DllTestDelegate)), DllTestDelegate)
                m_closeDLLDelegate = CType(GetDelegate("CloseDLL", GetType(CloseDLLDelegate)), CloseDLLDelegate)
    
                m_romOpenDelegate = CType(GetDelegate("RomOpen", GetType(RomOpenDelegate)), RomOpenDelegate)
                m_romClosedDelegate = CType(GetDelegate("RomClosed", GetType(RomClosedDelegate)), RomClosedDelegate)
            End Sub
    
            Private m_dllName As String
            Private m_dllWrapper As UnmanagedDllWrapper
    
            Public Sub Dispose() Implements IDisposable.Dispose
                m_dllWrapper.Dispose()
            End Sub
    
            Private Delegate Sub DelegateGetPluginInfo(ByRef pluginInfo As PluginInfo)
            Private m_delegateGetDllInfo As DelegateGetPluginInfo
            Private Sub GetDllInfo(ByRef pluginInfo As PluginInfo)
                m_delegateGetDllInfo(pluginInfo)
            End Sub
    
            Private Delegate Sub DllAboutDelegate(ByVal parentWindow As IntPtr)
            Private m_dllAboutDelegate As DllAboutDelegate
            Friend Sub DllAbout(ByVal parentWindow As IntPtr)
                If Not m_dllAboutDelegate Is Nothing Then
                    m_dllAboutDelegate(parentWindow)
                End If
            End Sub
    
            Private Delegate Sub DllTestDelegate(ByVal parentWindow As IntPtr)
            Private m_dllTestDelegate As DllTestDelegate
            Friend Sub DllTest(ByVal parentWindow As IntPtr)
                If Not m_dllTestDelegate Is Nothing Then
                    m_dllTestDelegate(parentWindow)
                End If
            End Sub
    
            Private Delegate Sub DllConfigDelegate(ByVal parentWindow As IntPtr)
            Private m_dllConfigDelegate As DllConfigDelegate
            Friend Sub DllConfig(ByVal parentWindow As IntPtr)
                If Not m_dllConfigDelegate Is Nothing Then
                    m_dllConfigDelegate(parentWindow)
                End If
            End Sub
    
            Private Delegate Sub CloseDLLDelegate()
            Private m_closeDLLDelegate As CloseDLLDelegate
            Friend Sub CloseDLL()
                If Not m_closeDLLDelegate Is Nothing Then
                    m_closeDLLDelegate()
                End If
            End Sub
    
            Private Delegate Sub RomOpenDelegate()
            Private m_romOpenDelegate As RomOpenDelegate
            Friend Sub RomOpen()
                If Not m_romOpenDelegate Is Nothing Then
                    m_romOpenDelegate()
                End If
            End Sub
    
            Private Delegate Sub RomClosedDelegate()
            Private m_romClosedDelegate As RomClosedDelegate
            Friend Sub RomClosed()
                If Not m_romClosedDelegate Is Nothing Then
                    m_romClosedDelegate()
                End If
            End Sub
    
            Private m_pluginInfo As PluginInfo
    
            Public ReadOnly Property Name() As String
                Get
                    Return m_pluginInfo.Name
                End Get
            End Property
    
            Public ReadOnly Property PluginType() As PluginType
                Get
                    Return m_pluginInfo.Type
                End Get
            End Property
    
            Public ReadOnly Property Version() As Integer
                Get
                    Return m_pluginInfo.Version
                End Get
            End Property
    
            Public ReadOnly Property IsNormalMemorySupported() As Boolean
                Get
                    Return m_pluginInfo.NormalMemory
                End Get
            End Property
    
            Public ReadOnly Property IsBswapedMemorySupported() As Boolean
                Get
                    Return m_pluginInfo.MemoryBswaped
                End Get
            End Property
    
            Protected Function GetDelegate( _
                        ByVal functionName As String, _
                        ByVal delegateType As Type _
                        ) As [Delegate]
    
                Dim pointer As IntPtr = m_dllWrapper.GetProcAddress(functionName)
                If pointer = IntPtr.Zero Then
                    Return Nothing
                End If
    
                Return Marshal.GetDelegateForFunctionPointer(pointer, delegateType)
            End Function
    
            ' the nested private class that allocates and release the unmanaged resource
            Private Class UnmanagedDllWrapper
                Implements IDisposable
    
                Public Handle As IntPtr
    
                Public Sub New(ByVal dllName As String)
                    Me.Handle = LoadLibrary(dllName)
                    If Me.Handle = IntPtr.Zero Then
                        Throw New Win32Exception()
                    End If
                End Sub
    
                ' the Dispose method can be invoked only by the parent class
                Public Sub Dispose() Implements System.IDisposable.Dispose
                    Dispose(True)
                    GC.SuppressFinalize(Me)
                End Sub
    
                ' the finalizer
                Protected Overrides Sub Finalize()
                    Dispose(False)
                End Sub
    
                ' This is where the unmanaged resource is actually disposed of.
                ' Notice that it takes an argument only for compliance with .NET coding standards
                ' but the disposing argument is never used, because in all cases this class
                ' can access and release only the single unmanaged resource it wraps.
                Private Sub Dispose(ByVal disposing As Boolean)
                    ' exit now if this object didn't completed its constructor correctly
                    If Me.Handle = IntPtr.Zero Then
                        Return
                    End If
    
                    ' release the unmanaged resource
                    FreeLibrary(Me.Handle)
    
                    ' finally, invalidate the handle
                    Me.Handle = IntPtr.Zero
                End Sub
    
                Public Function GetProcAddress(ByVal procName As String) As IntPtr
                    Return GetProcAddress(Me.Handle, procName)
                End Function
    
                <DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
                Private Shared Function LoadLibrary(ByVal dllName As String) As IntPtr
                End Function
    
                <DllImport("kernel32.dll")> _
                Private Shared Function GetProcAddress(ByVal dllHandle As IntPtr, ByVal procName As String) As IntPtr
                End Function
    
                <DllImport("kernel32.dll")> _
                Private Shared Function FreeLibrary(ByVal dllHandle As IntPtr) As Integer
                End Function
    
            End Class
    
        End Class
    
    End Namespace
    To use the class, you can do something like this:

    Code:
    Using plugin As New Plugin("C:\YourPath\YourPluggin.dll")
        plugin.DllAbout(myform.Handle)
    
        Dim pluginType As String = plugin.PluginType
        Dim pluginName As String = plugin.Name
        ...
    
    End Using ' End Using automaticly call the Dispose method, which release the handle on the loaded dll
    You should know that some plugin cannot be loaded in .Net. By example, most of the Jabo plugin throw an "Invalid access to memory location" exception on LoadLibrary. My guess is that those plugin are doing stuff in their "DllMain" function that doesn't work with the .Net runtime.

    Hope this help.

Similar Threads

  1. Forums for N64 GPU plugins.
    By xamenus in forum Suggestions?
    Replies: 4
    Last Post: May 1st, 2005, 13:33
  2. Cool Screenies
    By Zeo in forum Screenshots
    Replies: 136
    Last Post: September 18th, 2004, 05:52
  3. N64: The Adaptoid
    By Martin in forum Emulation64.com Reviews
    Replies: 15
    Last Post: October 16th, 2003, 08:12
  4. the best n64 emu, and video and sound plugins?
    By midiguy in forum General N64 Emulation Discussion
    Replies: 9
    Last Post: May 24th, 2003, 15:53
  5. N64 graphic plugins page added!
    By Martin in forum Emulation64.com News
    Replies: 0
    Last Post: November 27th, 2002, 05:25

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •