391 lines
9.7 KiB
C++
391 lines
9.7 KiB
C++
|
|
#include "Common.h"
|
|
#include "pluginspecs_wiimote.h"
|
|
|
|
#include "WiimoteReal/WiimoteReal.h"
|
|
|
|
#include "ControllerInterface/ControllerInterface.h"
|
|
#include "WiimoteEmu/WiimoteEmu.h"
|
|
|
|
#if defined(HAVE_WX) && HAVE_WX
|
|
#include "WiimoteConfigDiag.h"
|
|
#include "../../InputUICommon/Src/ConfigDiag.h"
|
|
#endif
|
|
#include "../../InputCommon/Src/InputConfig.h"
|
|
|
|
#if defined(HAVE_X11) && HAVE_X11
|
|
#include <X11/Xlib.h>
|
|
#if defined(HAVE_WX) && HAVE_WX
|
|
#include <gtk/gtk.h>
|
|
#include <gdk/gdkx.h>
|
|
#endif
|
|
#endif
|
|
|
|
#define PLUGIN_VERSION 0x0100
|
|
|
|
#define PLUGIN_NAME "Dolphin Wiimote New Incomplete"
|
|
#ifdef DEBUGFAST
|
|
#define PLUGIN_FULL_NAME PLUGIN_NAME" (DebugFast)"
|
|
#else
|
|
#ifdef _DEBUG
|
|
#define PLUGIN_FULL_NAME PLUGIN_NAME" (Debug)"
|
|
#else
|
|
#define PLUGIN_FULL_NAME PLUGIN_NAME
|
|
#endif
|
|
#endif
|
|
|
|
// plugin globals
|
|
InputPlugin g_plugin( "WiimoteNew", "Wiimote", "Wiimote" );
|
|
SWiimoteInitialize g_WiimoteInitialize;
|
|
|
|
#ifdef _WIN32
|
|
class wxDLLApp : public wxApp
|
|
{
|
|
bool OnInit()
|
|
{
|
|
return true;
|
|
};
|
|
};
|
|
IMPLEMENT_APP_NO_MAIN(wxDLLApp)
|
|
WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
|
|
|
|
// copied from GCPad
|
|
HINSTANCE g_hInstance;
|
|
#endif
|
|
|
|
// copied from GCPad
|
|
#if defined(HAVE_WX) && HAVE_WX
|
|
wxWindow* GetParentedWxWindow(HWND Parent)
|
|
{
|
|
#ifdef _WIN32
|
|
wxSetInstance((HINSTANCE)g_hInstance);
|
|
#endif
|
|
wxWindow *win = new wxWindow();
|
|
#ifdef _WIN32
|
|
win->SetHWND((WXHWND)Parent);
|
|
win->AdoptAttributesFromHWND();
|
|
#endif
|
|
return win;
|
|
}
|
|
#endif
|
|
// /
|
|
|
|
#ifdef _WIN32
|
|
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
|
|
{
|
|
switch (fdwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
wxSetInstance(hinstDLL);
|
|
wxInitialize();
|
|
break;
|
|
case DLL_PROCESS_DETACH:
|
|
wxUninitialize();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
g_hInstance = hinstDLL;
|
|
return TRUE;
|
|
}
|
|
#endif
|
|
|
|
void DeInitPlugin()
|
|
{
|
|
if (g_plugin.controller_interface.IsInit())
|
|
{
|
|
std::vector<ControllerEmu*>::const_iterator
|
|
i = g_plugin.controllers.begin(),
|
|
e = g_plugin.controllers.end();
|
|
for ( ; i!=e; ++i )
|
|
delete *i;
|
|
g_plugin.controllers.clear();
|
|
|
|
// true parameter to make SDL not quit in the wiimote plugin,
|
|
// the old wiimote plugin uses this hack as well, to prevent crash on stop
|
|
g_plugin.controller_interface.DeInit(true);
|
|
|
|
// real wiimotes
|
|
WiimoteReal::Shutdown();
|
|
}
|
|
}
|
|
|
|
// if plugin isn't initialized, init and load config
|
|
void InitPlugin( void* const hwnd )
|
|
{
|
|
if (false == g_plugin.controller_interface.IsInit())
|
|
{
|
|
// add 4 wiimotes
|
|
for ( unsigned int i = 0; i<4; ++i )
|
|
g_plugin.controllers.push_back( new WiimoteEmu::Wiimote(i) );
|
|
|
|
// needed for Xlib and exclusive dinput
|
|
g_plugin.controller_interface.SetHwnd(hwnd);
|
|
g_plugin.controller_interface.Init();
|
|
|
|
// load the saved controller config
|
|
g_plugin.LoadConfig();
|
|
|
|
// real wiimotes
|
|
WiimoteReal::LoadSettings();
|
|
WiimoteReal::Initialize();
|
|
}
|
|
}
|
|
|
|
// I N T E R F A C E
|
|
|
|
// __________________________________________________________________________________________________
|
|
// Function: Wiimote_Output
|
|
// Purpose: An L2CAP packet is passed from the Core to the Wiimote,
|
|
// on the HID CONTROL channel.
|
|
// input: Da pakket.
|
|
// output: none
|
|
//
|
|
void Wiimote_ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
|
|
{
|
|
switch (g_wiimote_sources[_number])
|
|
{
|
|
case WIIMOTE_SRC_REAL :
|
|
WiimoteReal::ControlChannel(_number, _channelID, _pData, _Size);
|
|
break;
|
|
case WIIMOTE_SRC_EMU :
|
|
((WiimoteEmu::Wiimote*)g_plugin.controllers[ _number ])->ControlChannel( _channelID, _pData, _Size );
|
|
break;
|
|
}
|
|
}
|
|
|
|
// __________________________________________________________________________________________________
|
|
// Function: Send keyboard input to the plugin
|
|
// Purpose:
|
|
// input: The key and if it's pressed or released
|
|
// output: None
|
|
//
|
|
void Wiimote_Input(u16 _Key, u8 _UpDown)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// __________________________________________________________________________________________________
|
|
// Function: Unpair real Wiimotes (just a dummy to be compliant)
|
|
// Purpose:
|
|
// input: None
|
|
// output: 0 Wiimotes disconnected
|
|
//
|
|
unsigned int Wiimote_UnPairWiimotes(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// __________________________________________________________________________________________________
|
|
// Function: Wiimote_InterruptChannel
|
|
// Purpose: An L2CAP packet is passed from the Core to the Wiimote,
|
|
// on the HID INTERRUPT channel.
|
|
// input: Da pakket.
|
|
// output: none
|
|
//
|
|
void Wiimote_InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
|
|
{
|
|
switch (g_wiimote_sources[_number])
|
|
{
|
|
case WIIMOTE_SRC_REAL :
|
|
WiimoteReal::InterruptChannel(_number, _channelID, _pData, _Size);
|
|
break;
|
|
case WIIMOTE_SRC_EMU :
|
|
((WiimoteEmu::Wiimote*)g_plugin.controllers[ _number ])->InterruptChannel( _channelID, _pData, _Size );
|
|
break;
|
|
}
|
|
}
|
|
|
|
// __________________________________________________________________________________________________
|
|
// Function: Wiimote_Update
|
|
// Purpose: This function is called periodically by the Core.
|
|
// input: none
|
|
// output: none
|
|
//
|
|
void Wiimote_Update(int _number)
|
|
{
|
|
//PanicAlert( "Wiimote_Update" );
|
|
|
|
// TODO: change this to a TryEnter, and make it give empty input on failure
|
|
g_plugin.controls_crit.Enter();
|
|
|
|
static int _last_number = 4;
|
|
if ( _number <= _last_number && g_plugin.interface_crit.TryEnter() )
|
|
{
|
|
g_plugin.controller_interface.UpdateOutput();
|
|
g_plugin.controller_interface.UpdateInput();
|
|
g_plugin.interface_crit.Leave();
|
|
}
|
|
_last_number = _number;
|
|
|
|
switch (g_wiimote_sources[_number])
|
|
{
|
|
case WIIMOTE_SRC_REAL :
|
|
WiimoteReal::Update(_number);
|
|
break;
|
|
case WIIMOTE_SRC_EMU :
|
|
((WiimoteEmu::Wiimote*)g_plugin.controllers[ _number ])->Update();
|
|
break;
|
|
}
|
|
|
|
g_plugin.controls_crit.Leave();
|
|
}
|
|
|
|
// __________________________________________________________________________________________________
|
|
// Function: PAD_GetAttachedPads
|
|
// Purpose: Get mask of attached pads (eg: controller 1 & 4 -> 0x9)
|
|
// input: none
|
|
// output: number of pads
|
|
//
|
|
unsigned int Wiimote_GetAttachedControllers()
|
|
{
|
|
unsigned int attached = 0;
|
|
for (unsigned int i=0; i<4; ++i)
|
|
if (g_wiimote_sources[i])
|
|
attached |= (1 << i);
|
|
return attached;
|
|
}
|
|
|
|
// GLOBAL I N T E R F A C E
|
|
// Function: GetDllInfo
|
|
// Purpose: This function allows the emulator to gather information
|
|
// about the DLL by filling in the PluginInfo structure.
|
|
// input: A pointer to a PLUGIN_INFO structure that needs to be
|
|
// filled by the function. (see def above)
|
|
// output: none
|
|
//
|
|
void GetDllInfo(PLUGIN_INFO* _pPluginInfo)
|
|
{
|
|
// don't feel like messing around with all those strcpy functions and warnings
|
|
//char *s1 = CIFACE_PLUGIN_FULL_NAME, *s2 = _pPluginInfo->Name;
|
|
//while ( *s2++ = *s1++ );
|
|
memcpy( _pPluginInfo->Name, PLUGIN_FULL_NAME, sizeof(PLUGIN_FULL_NAME) );
|
|
_pPluginInfo->Type = PLUGIN_TYPE_WIIMOTE;
|
|
_pPluginInfo->Version = PLUGIN_VERSION;
|
|
}
|
|
|
|
// ___________________________________________________________________________
|
|
// Function: DllConfig
|
|
// Purpose: This function is optional function that is provided
|
|
// to allow the user to configure the DLL
|
|
// input: A handle to the window that calls this function
|
|
// output: none
|
|
//
|
|
void DllConfig(HWND _hParent)
|
|
{
|
|
#if defined(HAVE_WX) && HAVE_WX
|
|
const bool was_init = g_plugin.controller_interface.IsInit();
|
|
|
|
if (false == was_init)
|
|
{
|
|
#if defined(HAVE_X11) && HAVE_X11
|
|
Window win = GDK_WINDOW_XID(GTK_WIDGET(_hParent)->window);
|
|
InitPlugin((void *)win);
|
|
#else
|
|
InitPlugin(_hParent);
|
|
#endif
|
|
}
|
|
|
|
wxWindow *frame = GetParentedWxWindow(_hParent);
|
|
WiimoteConfigDiag* const m_ConfigFrame = new WiimoteConfigDiag(frame, g_plugin);
|
|
//InputConfigDialog* const m_ConfigFrame = new InputConfigDialog(frame, g_plugin, PLUGIN_FULL_NAME);
|
|
|
|
#ifdef _WIN32
|
|
frame->Disable();
|
|
m_ConfigFrame->ShowModal();
|
|
frame->Enable();
|
|
#else
|
|
m_ConfigFrame->ShowModal();
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
wxMilliSleep(50); // hooray for hacks
|
|
frame->SetFocus();
|
|
frame->SetHWND(NULL);
|
|
#endif
|
|
|
|
m_ConfigFrame->Destroy();
|
|
frame->Destroy();
|
|
// /
|
|
|
|
if (false == was_init)
|
|
DeInitPlugin();
|
|
#endif
|
|
}
|
|
|
|
// ___________________________________________________________________________
|
|
// Function: DllDebugger
|
|
// Purpose: Open the debugger
|
|
// input: a handle to the window that calls this function
|
|
// output: none
|
|
//
|
|
void *DllDebugger(void *_hParent, bool Show)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// ___________________________________________________________________________
|
|
// Function: DllSetGlobals
|
|
// Purpose: Set the pointer for globals variables
|
|
// input: a pointer to the global struct
|
|
// output: none
|
|
//
|
|
void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
|
|
{
|
|
// wut?
|
|
}
|
|
|
|
// ___________________________________________________________________________
|
|
// Function: Initialize
|
|
// Purpose: Initialize the plugin
|
|
// input: Init
|
|
// output: none
|
|
//
|
|
void Initialize(void *init)
|
|
{
|
|
g_WiimoteInitialize = *(SWiimoteInitialize*)init;
|
|
if ( false == g_plugin.controller_interface.IsInit() )
|
|
InitPlugin( g_WiimoteInitialize.hWnd );
|
|
}
|
|
|
|
// ___________________________________________________________________________
|
|
// Function: Shutdown
|
|
// Purpose: This function is called when the emulator is shutting down
|
|
// a game allowing the dll to de-initialise.
|
|
// input: none
|
|
// output: none
|
|
//
|
|
void Shutdown(void)
|
|
{
|
|
if ( g_plugin.controller_interface.IsInit() )
|
|
DeInitPlugin();
|
|
}
|
|
|
|
// ___________________________________________________________________________
|
|
// Function: DoState
|
|
// Purpose: Saves/load state
|
|
// input/output: ptr
|
|
// input: mode
|
|
//
|
|
void DoState(unsigned char **ptr, int mode)
|
|
{
|
|
// TODO: this
|
|
|
|
//PointerWrap p(ptr, mode);
|
|
//for (unsigned int i=0; i<4; ++i)
|
|
// ((WiimoteEmu::Wiimote*)g_plugin.controllers[i])->DoState(p);
|
|
}
|
|
|
|
// ___________________________________________________________________________
|
|
// Function: EmuStateChange
|
|
// Purpose: Notifies the plugin of a change in emulation state
|
|
// input: newState
|
|
// output: none
|
|
//
|
|
void EmuStateChange(PLUGIN_EMUSTATE newState)
|
|
{
|
|
// maybe use this later
|
|
WiimoteReal::StateChange(newState);
|
|
}
|