dolphin/Source/Core/Core/HW/GCPad.cpp
2014-07-11 16:07:23 +02:00

144 lines
3.6 KiB
C++

// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#include "Common/Common.h"
#include "Core/ConfigManager.h"
#include "Core/HW/GCPad.h"
#include "Core/HW/GCPadEmu.h"
#include "InputCommon/GCPadStatus.h"
#include "InputCommon/InputConfig.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h"
namespace Pad
{
static InputPlugin g_plugin("GCPadNew", _trans("Pad"), "GCPad");
InputPlugin *GetPlugin()
{
return &g_plugin;
}
void Shutdown()
{
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();
g_controller_interface.Shutdown();
}
// if plugin isn't initialized, init and load config
void Initialize(void* const hwnd)
{
// add 4 gcpads
for (unsigned int i=0; i<4; ++i)
g_plugin.controllers.push_back(new GCPad(i));
g_controller_interface.SetHwnd(hwnd);
g_controller_interface.Initialize();
// load the saved controller config
g_plugin.LoadConfig(true);
}
void GetStatus(u8 _numPAD, GCPadStatus* _pPADStatus)
{
memset(_pPADStatus, 0, sizeof(*_pPADStatus));
_pPADStatus->err = PAD_ERR_NONE;
std::unique_lock<std::recursive_mutex> lk(g_plugin.controls_lock, std::try_to_lock);
if (!lk.owns_lock())
{
// if gui has lock (messing with controls), skip this input cycle
// center axes and return
_pPADStatus->stickX = 0x80;
_pPADStatus->stickY = 0x80;
_pPADStatus->substickX = 0x80;
_pPADStatus->substickY = 0x80;
return;
}
// if we are on the next input cycle, update output and input
// if we can get a lock
static int _last_numPAD = 4;
if (_numPAD <= _last_numPAD)
{
g_controller_interface.UpdateOutput();
g_controller_interface.UpdateInput();
}
_last_numPAD = _numPAD;
// get input
((GCPad*)g_plugin.controllers[_numPAD])->GetInput(_pPADStatus);
}
// __________________________________________________________________________________________________
// Function: Rumble
// Purpose: Pad rumble!
// input: _numPad - Which pad to rumble.
// _uType - Command type (Stop=0, Rumble=1, Stop Hard=2).
// _uStrength - Strength of the Rumble
// output: none
//
void Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength)
{
std::unique_lock<std::recursive_mutex> lk(g_plugin.controls_lock, std::try_to_lock);
if (lk.owns_lock())
{
// TODO: this has potential to not stop rumble if user is messing with GUI at the perfect time
// set rumble
if (1 == _uType && _uStrength > 2)
{
((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput(255);
}
else
{
((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput(0);
}
}
}
// __________________________________________________________________________________________________
// Function: Motor
// Purpose: For devices with constant Force feedback
// input: _numPAD - The pad to operate on
// _uType - 06 = Motor On, 04 = Motor Off
// _uStrength - 00 = Left Strong, 127 = Left Weak, 128 = Right Weak, 255 = Right Strong
// output: none
//
void Motor(u8 _numPAD, unsigned int _uType, unsigned int _uStrength)
{
std::unique_lock<std::recursive_mutex> lk(g_plugin.controls_lock, std::try_to_lock);
if (lk.owns_lock())
{
// TODO: this has potential to not stop rumble if user is messing with GUI at the perfect time
// set rumble
if (_uType == 6)
{
((GCPad*)g_plugin.controllers[ _numPAD ])->SetMotor(_uStrength);
}
}
}
bool GetMicButton(u8 pad)
{
std::unique_lock<std::recursive_mutex> lk(g_plugin.controls_lock, std::try_to_lock);
if (!lk.owns_lock())
return false;
return ((GCPad*)g_plugin.controllers[pad])->GetMicButton();
}
}