328 lines
12 KiB
C++
328 lines
12 KiB
C++
/****************************************************************************
|
|
* *
|
|
* Project 64 - A Nintendo 64 emulator. *
|
|
* http://www.pj64-emu.com/ *
|
|
* Copyright (C) 2012 Project64. All rights reserved. *
|
|
* *
|
|
* License: *
|
|
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
|
* *
|
|
****************************************************************************/
|
|
#include "stdafx.h"
|
|
|
|
void FixUPXIssue ( BYTE * ProgramLocation );
|
|
|
|
CControl_Plugin::CControl_Plugin ( const char * FileName) :
|
|
m_hDll(NULL),
|
|
m_Initilized(false),
|
|
m_RomOpen(false),
|
|
m_AllocatedControllers(false),
|
|
Config(NULL),
|
|
WM_KeyDown(NULL),
|
|
WM_KeyUp(NULL),
|
|
RumbleCommand(NULL),
|
|
GetKeys(NULL),
|
|
ReadController(NULL),
|
|
ControllerCommand(NULL),
|
|
CloseDLL(NULL),
|
|
RomOpen(NULL),
|
|
RomClosed(NULL),
|
|
PluginOpened(NULL),
|
|
SetSettingInfo(NULL),
|
|
SetSettingInfo2(NULL)
|
|
{
|
|
memset(&m_PluginInfo,0,sizeof(m_PluginInfo));
|
|
memset(&m_PluginControllers,0,sizeof(m_PluginControllers));
|
|
memset(&m_Controllers,0,sizeof(m_Controllers));
|
|
|
|
Init(FileName);
|
|
}
|
|
|
|
void CControl_Plugin::Init ( const char * FileName )
|
|
{
|
|
//Make sure all parts of the class are initialized
|
|
UnloadPlugin();
|
|
|
|
//Try to load the DLL library
|
|
UINT LastErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS );
|
|
m_hDll = LoadLibrary(FileName);
|
|
SetErrorMode(LastErrorMode);
|
|
|
|
if (m_hDll == NULL) {
|
|
UnloadPlugin();
|
|
return;
|
|
}
|
|
FixUPXIssue((BYTE *)m_hDll);
|
|
|
|
//Get DLL information
|
|
void (__cdecl *GetDllInfo) ( PLUGIN_INFO * PluginInfo );
|
|
GetDllInfo = (void (__cdecl *)(PLUGIN_INFO *))GetProcAddress( (HMODULE)m_hDll, "GetDllInfo" );
|
|
if (GetDllInfo == NULL) { UnloadPlugin(); return; }
|
|
|
|
GetDllInfo(&m_PluginInfo);
|
|
if (!CPluginList::ValidPluginVersion(m_PluginInfo)) { UnloadPlugin(); return; }
|
|
|
|
//Find entries for functions in DLL
|
|
void (__cdecl *InitFunc) ( void );
|
|
Config = (void (__cdecl *)(DWORD))GetProcAddress( (HMODULE)m_hDll, "DllConfig" );
|
|
ControllerCommand = (void (__cdecl *)(int,BYTE *))GetProcAddress( (HMODULE)m_hDll, "ControllerCommand" );
|
|
GetKeys = (void (__cdecl *)(int,BUTTONS*)) GetProcAddress( (HMODULE)m_hDll, "GetKeys" );
|
|
ReadController = (void (__cdecl *)(int,BYTE *))GetProcAddress( (HMODULE)m_hDll, "ReadController" );
|
|
WM_KeyDown = (void (__cdecl *)(DWORD,DWORD))GetProcAddress( (HMODULE)m_hDll, "WM_KeyDown" );
|
|
WM_KeyUp = (void (__cdecl *)(DWORD,DWORD))GetProcAddress( (HMODULE)m_hDll, "WM_KeyUp" );
|
|
InitFunc = (void (__cdecl *)(void)) GetProcAddress( (HMODULE)m_hDll, "InitiateControllers" );
|
|
RomOpen = (void (__cdecl *)(void)) GetProcAddress( (HMODULE)m_hDll, "RomOpen" );
|
|
RomClosed = (void (__cdecl *)(void)) GetProcAddress( (HMODULE)m_hDll, "RomClosed" );
|
|
CloseDLL = (void (__cdecl *)(void)) GetProcAddress( (HMODULE)m_hDll, "CloseDLL" );
|
|
RumbleCommand = (void (__cdecl *)(int, BOOL))GetProcAddress( (HMODULE)m_hDll, "RumbleCommand" );
|
|
|
|
//version 101 functions
|
|
PluginOpened = (void (__cdecl *)(void))GetProcAddress( (HMODULE)m_hDll, "PluginLoaded" );
|
|
|
|
//Make sure dll had all needed functions
|
|
if (InitFunc == NULL) { UnloadPlugin(); return; }
|
|
if (CloseDLL == NULL) { UnloadPlugin(); return; }
|
|
|
|
SetSettingInfo3 = (void (__cdecl *)(PLUGIN_SETTINGS3 *))GetProcAddress( (HMODULE)m_hDll, "SetSettingInfo3" );
|
|
if (SetSettingInfo3)
|
|
{
|
|
PLUGIN_SETTINGS3 info;
|
|
info.FlushSettings = (void (*)( void * handle))CSettings::FlushSettings;
|
|
SetSettingInfo3(&info);
|
|
}
|
|
|
|
SetSettingInfo2 = (void (__cdecl *)(PLUGIN_SETTINGS2 *))GetProcAddress( (HMODULE)m_hDll, "SetSettingInfo2" );
|
|
if (SetSettingInfo2)
|
|
{
|
|
PLUGIN_SETTINGS2 info;
|
|
info.FindSystemSettingId = (unsigned int (*)( void * handle, const char * ))CSettings::FindSetting;
|
|
SetSettingInfo2(&info);
|
|
}
|
|
|
|
SetSettingInfo = (void (__cdecl *)(PLUGIN_SETTINGS *))GetProcAddress( (HMODULE)m_hDll, "SetSettingInfo" );
|
|
if (SetSettingInfo)
|
|
{
|
|
PLUGIN_SETTINGS info;
|
|
info.dwSize = sizeof(PLUGIN_SETTINGS);
|
|
info.DefaultStartRange = FirstCtrlDefaultSet;
|
|
info.SettingStartRange = FirstCtrlSettings;
|
|
info.MaximumSettings = MaxPluginSetting;
|
|
info.NoDefault = Default_None;
|
|
info.DefaultLocation = g_Settings->LoadDword(Setting_UseFromRegistry) ? SettingType_Registry : SettingType_CfgFile;
|
|
info.handle = g_Settings;
|
|
info.RegisterSetting = (void (*)(void *,int,int,SettingDataType,SettingType,const char *,const char *, DWORD))CSettings::RegisterSetting;
|
|
info.GetSetting = (unsigned int (*)( void * handle, int ID ))CSettings::GetSetting;
|
|
info.GetSettingSz = (const char * (*)( void *, int, char *, int ))CSettings::GetSettingSz;
|
|
info.SetSetting = (void (*)(void *,int,unsigned int))CSettings::SetSetting;
|
|
info.SetSettingSz = (void (*)(void *,int,const char *))CSettings::SetSettingSz;
|
|
info.UseUnregisteredSetting = NULL;
|
|
|
|
SetSettingInfo(&info);
|
|
// g_Settings->UnknownSetting_CTRL = info.UseUnregisteredSetting;
|
|
}
|
|
|
|
if (m_PluginInfo.Version >= 0x0102)
|
|
{
|
|
if (PluginOpened == NULL) { UnloadPlugin(); return; }
|
|
|
|
PluginOpened();
|
|
}
|
|
|
|
//Allocate our own controller
|
|
m_AllocatedControllers = true;
|
|
m_Controllers[0] = new CCONTROL(m_PluginControllers[0].Present,m_PluginControllers[0].RawData,m_PluginControllers[0].Plugin);
|
|
m_Controllers[1] = new CCONTROL(m_PluginControllers[1].Present,m_PluginControllers[1].RawData,m_PluginControllers[1].Plugin);
|
|
m_Controllers[2] = new CCONTROL(m_PluginControllers[2].Present,m_PluginControllers[2].RawData,m_PluginControllers[2].Plugin);
|
|
m_Controllers[3] = new CCONTROL(m_PluginControllers[3].Present,m_PluginControllers[3].RawData,m_PluginControllers[3].Plugin);
|
|
}
|
|
|
|
CControl_Plugin::~CControl_Plugin (void) {
|
|
Close();
|
|
UnloadPlugin();
|
|
}
|
|
|
|
bool CControl_Plugin::Initiate ( CN64System * System, CMainGui * RenderWindow ) {
|
|
m_PluginControllers[0].Present = FALSE;
|
|
m_PluginControllers[0].RawData = FALSE;
|
|
m_PluginControllers[0].Plugin = PLUGIN_NONE;
|
|
|
|
m_PluginControllers[1].Present = FALSE;
|
|
m_PluginControllers[1].RawData = FALSE;
|
|
m_PluginControllers[1].Plugin = PLUGIN_NONE;
|
|
|
|
m_PluginControllers[2].Present = FALSE;
|
|
m_PluginControllers[2].RawData = FALSE;
|
|
m_PluginControllers[2].Plugin = PLUGIN_NONE;
|
|
|
|
m_PluginControllers[3].Present = FALSE;
|
|
m_PluginControllers[3].RawData = FALSE;
|
|
m_PluginControllers[3].Plugin = PLUGIN_NONE;
|
|
|
|
//Get DLL information
|
|
void (__cdecl *GetDllInfo) ( PLUGIN_INFO * PluginInfo );
|
|
GetDllInfo = (void (__cdecl *)(PLUGIN_INFO *))GetProcAddress( (HMODULE)m_hDll, "GetDllInfo" );
|
|
if (GetDllInfo == NULL) { return false; }
|
|
|
|
PLUGIN_INFO PluginInfo;
|
|
GetDllInfo(&PluginInfo);
|
|
|
|
//Test Plugin version
|
|
if (PluginInfo.Version == 0x0100) {
|
|
//Get Function from DLL
|
|
void (__cdecl *InitiateControllers_1_0)( HWND hMainWindow, CONTROL Controls[4] );
|
|
InitiateControllers_1_0 = (void (__cdecl *)(HWND, CONTROL *))GetProcAddress( (HMODULE)m_hDll, "InitiateControllers" );
|
|
if (InitiateControllers_1_0 == NULL) { return false; }
|
|
InitiateControllers_1_0((HWND)RenderWindow->m_hMainWindow,m_PluginControllers);
|
|
m_Initilized = true;
|
|
}
|
|
if (PluginInfo.Version >= 0x0101) {
|
|
typedef struct {
|
|
HWND hMainWindow;
|
|
HINSTANCE hinst;
|
|
|
|
BOOL MemoryBswaped; // If this is set to TRUE, then the memory has been pre
|
|
// bswap on a dword (32 bits) boundry, only effects header.
|
|
// eg. the first 8 bytes are stored like this:
|
|
// 4 3 2 1 8 7 6 5
|
|
BYTE * HEADER; // This is the rom header (first 40h bytes of the rom)
|
|
CONTROL *Controls; // A pointer to an array of 4 controllers .. eg:
|
|
// CONTROL Controls[4];
|
|
} CONTROL_INFO;
|
|
|
|
//Get Function from DLL
|
|
void (__cdecl *InitiateControllers_1_1)( CONTROL_INFO * ControlInfo );
|
|
InitiateControllers_1_1 = (void (__cdecl *)(CONTROL_INFO *))GetProcAddress( (HMODULE)m_hDll, "InitiateControllers" );
|
|
if (InitiateControllers_1_1 == NULL) { return false; }
|
|
|
|
CONTROL_INFO ControlInfo;
|
|
if (System == NULL) {
|
|
BYTE Buffer[100];
|
|
|
|
ControlInfo.Controls = m_PluginControllers;
|
|
ControlInfo.HEADER = Buffer;
|
|
ControlInfo.hinst = GetModuleHandle(NULL);
|
|
ControlInfo.hMainWindow = (HWND)RenderWindow->m_hMainWindow;
|
|
ControlInfo.MemoryBswaped = TRUE;
|
|
InitiateControllers_1_1(&ControlInfo);
|
|
m_Initilized = true;
|
|
} else {
|
|
ControlInfo.Controls = m_PluginControllers;
|
|
ControlInfo.HEADER = g_Rom->GetRomAddress();
|
|
ControlInfo.hinst = GetModuleHandle(NULL);
|
|
ControlInfo.hMainWindow = (HWND)RenderWindow->m_hMainWindow;
|
|
ControlInfo.MemoryBswaped = TRUE;
|
|
InitiateControllers_1_1(&ControlInfo);
|
|
m_Initilized = true;
|
|
}
|
|
}
|
|
|
|
//jabo had a bug so I call CreateThread so his dllmain gets called again
|
|
DWORD ThreadID;
|
|
HANDLE hthread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)DummyFunction,NULL,0, &ThreadID);
|
|
CloseHandle(hthread);
|
|
|
|
|
|
return m_Initilized;
|
|
}
|
|
|
|
void CControl_Plugin::RomOpened ( void )
|
|
{
|
|
//Real system ... then make the file as open
|
|
if (!m_RomOpen)
|
|
{
|
|
RomOpen();
|
|
m_RomOpen = true;
|
|
}
|
|
}
|
|
|
|
void CControl_Plugin::RomClose ( void )
|
|
{
|
|
if (m_RomOpen)
|
|
{
|
|
RomClosed();
|
|
m_RomOpen = false;
|
|
}
|
|
}
|
|
|
|
void CControl_Plugin::Close(void) {
|
|
if (m_RomOpen) {
|
|
RomClosed();
|
|
m_RomOpen = false;
|
|
}
|
|
if (m_Initilized) {
|
|
CloseDLL();
|
|
m_Initilized = false;
|
|
}
|
|
}
|
|
|
|
void CControl_Plugin::GameReset(void)
|
|
{
|
|
if (m_RomOpen)
|
|
{
|
|
RomClosed();
|
|
RomOpen();
|
|
}
|
|
}
|
|
|
|
void CControl_Plugin::UnloadPlugin(void) {
|
|
if (m_AllocatedControllers) {
|
|
for (int count = 0; count < sizeof(m_Controllers) / sizeof(m_Controllers[0]); count++) {
|
|
delete m_Controllers[count];
|
|
m_Controllers[count] = NULL;
|
|
}
|
|
}
|
|
memset(&m_PluginInfo,0,sizeof(m_PluginInfo));
|
|
if (m_hDll != NULL ) {
|
|
FreeLibrary((HMODULE)m_hDll);
|
|
m_hDll = NULL;
|
|
}
|
|
m_AllocatedControllers = false;
|
|
m_Controllers[0] = NULL;
|
|
m_Controllers[1] = NULL;
|
|
m_Controllers[2] = NULL;
|
|
m_Controllers[3] = NULL;
|
|
Config = NULL;
|
|
ControllerCommand = NULL;
|
|
GetKeys = NULL;
|
|
ReadController = NULL;
|
|
WM_KeyDown = NULL;
|
|
WM_KeyUp = NULL;
|
|
CloseDLL = NULL;
|
|
RomOpen = NULL;
|
|
RomClosed = NULL;
|
|
|
|
}
|
|
|
|
void CControl_Plugin::UpdateKeys (void) {
|
|
if (!m_AllocatedControllers) { return; }
|
|
for (int cont = 0; cont < sizeof(m_Controllers) / sizeof(m_Controllers[0]); cont++) {
|
|
if (!m_Controllers[cont]->m_Present) { continue; }
|
|
if (!m_Controllers[cont]->m_RawData) {
|
|
GetKeys(cont,&m_Controllers[cont]->m_Buttons);
|
|
} else {
|
|
g_Notify->BreakPoint(__FILE__,__LINE__);
|
|
}
|
|
}
|
|
if (ReadController) { ReadController(-1,NULL); }
|
|
}
|
|
|
|
void CControl_Plugin::SetControl(CControl_Plugin const * const Plugin)
|
|
{
|
|
if (m_AllocatedControllers) {
|
|
for (int count = 0; count < sizeof(m_Controllers) / sizeof(m_Controllers[0]); count++) {
|
|
delete m_Controllers[count];
|
|
m_Controllers[count] = NULL;
|
|
}
|
|
}
|
|
m_AllocatedControllers = false;
|
|
for (int count = 0; count < sizeof(m_Controllers) / sizeof(m_Controllers[0]); count++) {
|
|
m_Controllers[count] = Plugin->m_Controllers[count];
|
|
}
|
|
|
|
}
|
|
|
|
CCONTROL::CCONTROL(DWORD &Present,DWORD &RawData, int &PlugType) :
|
|
m_Present(Present),m_RawData(RawData),m_PlugType(PlugType)
|
|
{
|
|
m_Buttons.Value = 0;
|
|
} |