Merge pull request #604 from magcius/wip/emu-cleanup-2
Start cleaning up the input interface
This commit is contained in:
commit
ebd029973a
|
@ -150,6 +150,7 @@ void SConfig::SaveSettings()
|
|||
SaveCoreSettings(ini);
|
||||
SaveMovieSettings(ini);
|
||||
SaveDSPSettings(ini);
|
||||
SaveInputSettings(ini);
|
||||
SaveFifoPlayerSettings(ini);
|
||||
|
||||
ini.Save(File::GetUserPath(F_DOLPHINCONFIG_IDX));
|
||||
|
@ -329,6 +330,13 @@ void SConfig::SaveDSPSettings(IniFile& ini)
|
|||
dsp->Set("CaptureLog", m_DSPCaptureLog);
|
||||
}
|
||||
|
||||
void SConfig::SaveInputSettings(IniFile& ini)
|
||||
{
|
||||
IniFile::Section* input = ini.GetOrCreateSection("Input");
|
||||
|
||||
input->Set("BackgroundInput", m_BackgroundInput);
|
||||
}
|
||||
|
||||
void SConfig::SaveFifoPlayerSettings(IniFile& ini)
|
||||
{
|
||||
IniFile::Section* fifoplayer = ini.GetOrCreateSection("FifoPlayer");
|
||||
|
@ -350,6 +358,7 @@ void SConfig::LoadSettings()
|
|||
LoadCoreSettings(ini);
|
||||
LoadMovieSettings(ini);
|
||||
LoadDSPSettings(ini);
|
||||
LoadInputSettings(ini);
|
||||
LoadFifoPlayerSettings(ini);
|
||||
|
||||
m_SYSCONF = new SysConf();
|
||||
|
@ -556,6 +565,13 @@ void SConfig::LoadDSPSettings(IniFile& ini)
|
|||
dsp->Get("CaptureLog", &m_DSPCaptureLog, false);
|
||||
}
|
||||
|
||||
void SConfig::LoadInputSettings(IniFile& ini)
|
||||
{
|
||||
IniFile::Section* input = ini.GetOrCreateSection("Input");
|
||||
|
||||
input->Get("BackgroundInput", &m_BackgroundInput, false);
|
||||
}
|
||||
|
||||
void SConfig::LoadFifoPlayerSettings(IniFile& ini)
|
||||
{
|
||||
IniFile::Section* fifoplayer = ini.GetOrCreateSection("FifoPlayer");
|
||||
|
|
|
@ -97,6 +97,9 @@ struct SConfig : NonCopyable
|
|||
int m_Volume;
|
||||
std::string sBackend;
|
||||
|
||||
// Input settings
|
||||
bool m_BackgroundInput;
|
||||
|
||||
SysConf* m_SYSCONF;
|
||||
|
||||
// save settings
|
||||
|
@ -122,6 +125,7 @@ private:
|
|||
void SaveGameListSettings(IniFile& ini);
|
||||
void SaveCoreSettings(IniFile& ini);
|
||||
void SaveDSPSettings(IniFile& ini);
|
||||
void SaveInputSettings(IniFile& ini);
|
||||
void SaveMovieSettings(IniFile& ini);
|
||||
void SaveFifoPlayerSettings(IniFile& ini);
|
||||
|
||||
|
@ -132,6 +136,7 @@ private:
|
|||
void LoadGameListSettings(IniFile& ini);
|
||||
void LoadCoreSettings(IniFile& ini);
|
||||
void LoadDSPSettings(IniFile& ini);
|
||||
void LoadInputSettings(IniFile& ini);
|
||||
void LoadMovieSettings(IniFile& ini);
|
||||
void LoadFifoPlayerSettings(IniFile& ini);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
|
@ -357,7 +357,6 @@
|
|||
<ClInclude Include="HW\WiimoteEmu\Attachment\Turntable.h" />
|
||||
<ClInclude Include="HW\WiimoteEmu\Encryption.h" />
|
||||
<ClInclude Include="HW\WiimoteEmu\MatrixMath.h" />
|
||||
<ClInclude Include="HW\WiimoteEmu\UDPTLayer.h" />
|
||||
<ClInclude Include="HW\WiimoteEmu\WiimoteEmu.h" />
|
||||
<ClInclude Include="HW\WiimoteEmu\WiimoteHid.h" />
|
||||
<ClInclude Include="HW\WiimoteReal\WiimoteReal.h" />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="ActionReplay">
|
||||
|
@ -1005,9 +1005,6 @@
|
|||
<ClInclude Include="HW\WiimoteEmu\MatrixMath.h">
|
||||
<Filter>HW %28Flipper/Hollywood%29\Wiimote\Emu</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HW\WiimoteEmu\UDPTLayer.h">
|
||||
<Filter>HW %28Flipper/Hollywood%29\Wiimote\Emu</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HW\WiimoteEmu\WiimoteEmu.h">
|
||||
<Filter>HW %28Flipper/Hollywood%29\Wiimote\Emu</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -79,7 +79,7 @@ GCPad::GCPad(const unsigned int index) : m_index(index)
|
|||
|
||||
// options
|
||||
groups.emplace_back(m_options = new ControlGroup(_trans("Options")));
|
||||
m_options->settings.emplace_back(new ControlGroup::Setting(_trans("Background Input"), false));
|
||||
m_options->settings.emplace_back(new ControlGroup::BackgroundInputSetting(_trans("Background Input")));
|
||||
}
|
||||
|
||||
std::string GCPad::GetName() const
|
||||
|
@ -89,34 +89,31 @@ std::string GCPad::GetName() const
|
|||
|
||||
void GCPad::GetInput(GCPadStatus* const pad)
|
||||
{
|
||||
// if window has focus or background input enabled
|
||||
if (Host_RendererHasFocus() || m_options[0].settings[0]->value)
|
||||
{
|
||||
// buttons
|
||||
m_buttons->GetState(&pad->button, button_bitmasks);
|
||||
double x, y, triggers[2];
|
||||
|
||||
// set analog A/B analog to full or w/e, prolly not needed
|
||||
if (pad->button & PAD_BUTTON_A) pad->analogA = 0xFF;
|
||||
if (pad->button & PAD_BUTTON_B) pad->analogB = 0xFF;
|
||||
// buttons
|
||||
m_buttons->GetState(&pad->button, button_bitmasks);
|
||||
|
||||
// dpad
|
||||
m_dpad->GetState(&pad->button, dpad_bitmasks);
|
||||
// set analog A/B analog to full or w/e, prolly not needed
|
||||
if (pad->button & PAD_BUTTON_A) pad->analogA = 0xFF;
|
||||
if (pad->button & PAD_BUTTON_B) pad->analogB = 0xFF;
|
||||
|
||||
// sticks
|
||||
m_main_stick->GetState(&pad->stickX, &pad->stickY, 0x80, 127);
|
||||
m_c_stick->GetState(&pad->substickX, &pad->substickY, 0x80, 127);
|
||||
// dpad
|
||||
m_dpad->GetState(&pad->button, dpad_bitmasks);
|
||||
|
||||
// triggers
|
||||
m_triggers->GetState(&pad->button, trigger_bitmasks, &pad->triggerLeft, 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
// center sticks
|
||||
pad->stickX = 0x80;
|
||||
pad->stickY = 0x80;
|
||||
pad->substickX = 0x80;
|
||||
pad->substickY = 0x80;
|
||||
}
|
||||
// sticks
|
||||
m_main_stick->GetState(&x, &y);
|
||||
pad->stickX = 0x7F + (x * 0x80);
|
||||
pad->stickY = 0x7F + (y * 0x80);
|
||||
|
||||
m_c_stick->GetState(&x, &y);
|
||||
pad->substickX = 0x7F + (x * 0x80);
|
||||
pad->substickY = 0x7F + (y * 0x80);
|
||||
|
||||
// triggers
|
||||
m_triggers->GetState(&pad->button, trigger_bitmasks, triggers);
|
||||
pad->triggerLeft = triggers[0] * 0xFF;
|
||||
pad->triggerRight = triggers[1] * 0xFF;
|
||||
}
|
||||
|
||||
void GCPad::SetMotor(const u8 on)
|
||||
|
@ -126,17 +123,12 @@ void GCPad::SetMotor(const u8 on)
|
|||
if (state < 0.5)
|
||||
force = -force;
|
||||
|
||||
// only rumble if window has focus or background input is enabled
|
||||
if (Host_RendererHasFocus() || m_options[0].settings[0]->value)
|
||||
m_rumble->controls[0]->control_ref->State(force);
|
||||
else
|
||||
m_rumble->controls[0]->control_ref->State(0);
|
||||
m_rumble->controls[0]->control_ref->State(force);
|
||||
}
|
||||
|
||||
void GCPad::SetOutput(const u8 on)
|
||||
{
|
||||
// only rumble if window has focus or background input is enabled
|
||||
m_rumble->controls[0]->control_ref->State(on && (Host_RendererHasFocus() || m_options[0].settings[0]->value));
|
||||
m_rumble->controls[0]->control_ref->State(on);
|
||||
}
|
||||
|
||||
void GCPad::LoadDefaults(const ControllerInterface& ciface)
|
||||
|
|
|
@ -42,7 +42,7 @@ void Attachment::Reset()
|
|||
|
||||
}
|
||||
|
||||
void ControllerEmu::Extension::GetState(u8* const data, const bool focus)
|
||||
void ControllerEmu::Extension::GetState(u8* const data)
|
||||
{
|
||||
((WiimoteEmu::Attachment*)attachments[active_extension].get())->GetState(data, focus);
|
||||
((WiimoteEmu::Attachment*)attachments[active_extension].get())->GetState(data);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ class Attachment : public ControllerEmu
|
|||
public:
|
||||
Attachment(const char* const _name, WiimoteEmu::ExtensionReg& _reg);
|
||||
|
||||
virtual void GetState(u8* const data, const bool focus = true) {}
|
||||
virtual void GetState(u8* const data) {}
|
||||
void Reset();
|
||||
std::string GetName() const override;
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ Classic::Classic(WiimoteEmu::ExtensionReg& _reg) : Attachment(_trans("Classic"),
|
|||
memcpy(&id, classic_id, sizeof(classic_id));
|
||||
}
|
||||
|
||||
void Classic::GetState(u8* const data, const bool focus)
|
||||
void Classic::GetState(u8* const data)
|
||||
{
|
||||
wm_classic_extension* const ccdata = (wm_classic_extension*)data;
|
||||
ccdata->bt = 0;
|
||||
|
@ -89,41 +89,46 @@ void Classic::GetState(u8* const data, const bool focus)
|
|||
|
||||
// left stick
|
||||
{
|
||||
u8 x, y;
|
||||
m_left_stick->GetState(&x, &y, 0x20, focus ? 0x1F /*0x15*/ : 0);
|
||||
double x, y;
|
||||
m_left_stick->GetState(&x, &y);
|
||||
|
||||
ccdata->lx = x;
|
||||
ccdata->ly = y;
|
||||
ccdata->lx = (x * 0x1F) + 0x20;
|
||||
ccdata->ly = (y * 0x1F) + 0x20;
|
||||
}
|
||||
|
||||
// right stick
|
||||
{
|
||||
u8 x, y;
|
||||
m_right_stick->GetState(&x, &y, 0x10, focus ? 0x0F /*0x0C*/ : 0);
|
||||
double x, y;
|
||||
u8 x_, y_;
|
||||
m_right_stick->GetState(&x, &y);
|
||||
|
||||
ccdata->rx1 = x;
|
||||
ccdata->rx2 = x >> 1;
|
||||
ccdata->rx3 = x >> 3;
|
||||
ccdata->ry = y;
|
||||
x_ = (x * 0x1F) + 0x20;
|
||||
y_ = (y * 0x1F) + 0x20;
|
||||
|
||||
ccdata->rx1 = x_;
|
||||
ccdata->rx2 = x_ >> 1;
|
||||
ccdata->rx3 = x_ >> 3;
|
||||
ccdata->ry = y_;
|
||||
}
|
||||
|
||||
//triggers
|
||||
{
|
||||
u8 trigs[2];
|
||||
m_triggers->GetState(&ccdata->bt, classic_trigger_bitmasks, trigs, focus ? 0x1F : 0);
|
||||
double trigs[2] = { 0, 0 };
|
||||
u8 lt, rt;
|
||||
m_triggers->GetState(&ccdata->bt, classic_trigger_bitmasks, trigs);
|
||||
|
||||
ccdata->lt1 = trigs[0];
|
||||
ccdata->lt2 = trigs[0] >> 3;
|
||||
ccdata->rt = trigs[1];
|
||||
lt = trigs[0] * 0x1F;
|
||||
rt = trigs[1] * 0x1F;
|
||||
|
||||
ccdata->lt1 = lt;
|
||||
ccdata->lt2 = lt >> 3;
|
||||
ccdata->rt = rt;
|
||||
}
|
||||
|
||||
if (focus)
|
||||
{
|
||||
// buttons
|
||||
m_buttons->GetState(&ccdata->bt, classic_button_bitmasks);
|
||||
// dpad
|
||||
m_dpad->GetState(&ccdata->bt, classic_dpad_bitmasks);
|
||||
}
|
||||
// buttons
|
||||
m_buttons->GetState(&ccdata->bt, classic_button_bitmasks);
|
||||
// dpad
|
||||
m_dpad->GetState(&ccdata->bt, classic_dpad_bitmasks);
|
||||
|
||||
// flip button bits
|
||||
ccdata->bt ^= 0xFFFF;
|
||||
|
|
|
@ -13,7 +13,7 @@ class Classic : public Attachment
|
|||
{
|
||||
public:
|
||||
Classic(WiimoteEmu::ExtensionReg& _reg);
|
||||
void GetState(u8* const data, const bool focus) override;
|
||||
void GetState(u8* const data) override;
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -51,7 +51,7 @@ Drums::Drums(WiimoteEmu::ExtensionReg& _reg) : Attachment(_trans("Drums"), _reg)
|
|||
memcpy(&id, drums_id, sizeof(drums_id));
|
||||
}
|
||||
|
||||
void Drums::GetState(u8* const data, const bool focus)
|
||||
void Drums::GetState(u8* const data)
|
||||
{
|
||||
wm_drums_extension* const ddata = (wm_drums_extension*)data;
|
||||
ddata->bt = 0;
|
||||
|
@ -60,24 +60,21 @@ void Drums::GetState(u8* const data, const bool focus)
|
|||
|
||||
// stick
|
||||
{
|
||||
u8 x, y;
|
||||
m_stick->GetState(&x, &y, 0x20, focus ? 0x1F /*0x15*/ : 0);
|
||||
double x, y;
|
||||
m_stick->GetState(&x, &y);
|
||||
|
||||
ddata->sx = x;
|
||||
ddata->sy = y;
|
||||
ddata->sx = (x * 0x1F) + 0x20;
|
||||
ddata->sx = (y * 0x1F) + 0x20;
|
||||
}
|
||||
|
||||
// TODO: softness maybe
|
||||
data[2] = 0xFF;
|
||||
data[3] = 0xFF;
|
||||
|
||||
if (focus)
|
||||
{
|
||||
// buttons
|
||||
m_buttons->GetState(&ddata->bt, drum_button_bitmasks);
|
||||
// pads
|
||||
m_pads->GetState(&ddata->bt, drum_pad_bitmasks);
|
||||
}
|
||||
// buttons
|
||||
m_buttons->GetState(&ddata->bt, drum_button_bitmasks);
|
||||
// pads
|
||||
m_pads->GetState(&ddata->bt, drum_pad_bitmasks);
|
||||
|
||||
// flip button bits
|
||||
ddata->bt ^= 0xFFFF;
|
||||
|
|
|
@ -13,7 +13,7 @@ class Drums : public Attachment
|
|||
{
|
||||
public:
|
||||
Drums(WiimoteEmu::ExtensionReg& _reg);
|
||||
void GetState(u8* const data, const bool focus) override;
|
||||
void GetState(u8* const data) override;
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -64,7 +64,7 @@ Guitar::Guitar(WiimoteEmu::ExtensionReg& _reg) : Attachment(_trans("Guitar"), _r
|
|||
memcpy(&id, guitar_id, sizeof(guitar_id));
|
||||
}
|
||||
|
||||
void Guitar::GetState(u8* const data, const bool focus)
|
||||
void Guitar::GetState(u8* const data)
|
||||
{
|
||||
wm_guitar_extension* const gdata = (wm_guitar_extension*)data;
|
||||
gdata->bt = 0;
|
||||
|
@ -73,30 +73,27 @@ void Guitar::GetState(u8* const data, const bool focus)
|
|||
|
||||
// stick
|
||||
{
|
||||
u8 x, y;
|
||||
m_stick->GetState(&x, &y, 0x20, focus ? 0x1F /*0x15*/ : 0);
|
||||
double x, y;
|
||||
m_stick->GetState(&x, &y);
|
||||
|
||||
gdata->sx = x;
|
||||
gdata->sy = y;
|
||||
gdata->sx = (x * 0x1F) + 0x20;
|
||||
gdata->sy = (y * 0x1F) + 0x20;
|
||||
}
|
||||
|
||||
// TODO: touch bar, probably not
|
||||
gdata->tb = 0x0F; // not touched
|
||||
|
||||
// whammy bar
|
||||
u8 whammy;
|
||||
m_whammy->GetState(&whammy, 0x1F);
|
||||
gdata->whammy = whammy;
|
||||
double whammy;
|
||||
m_whammy->GetState(&whammy);
|
||||
gdata->whammy = whammy * 0x1F;
|
||||
|
||||
if (focus)
|
||||
{
|
||||
// buttons
|
||||
m_buttons->GetState(&gdata->bt, guitar_button_bitmasks);
|
||||
// frets
|
||||
m_frets->GetState(&gdata->bt, guitar_fret_bitmasks);
|
||||
// strum
|
||||
m_strum->GetState(&gdata->bt, guitar_strum_bitmasks);
|
||||
}
|
||||
// buttons
|
||||
m_buttons->GetState(&gdata->bt, guitar_button_bitmasks);
|
||||
// frets
|
||||
m_frets->GetState(&gdata->bt, guitar_fret_bitmasks);
|
||||
// strum
|
||||
m_strum->GetState(&gdata->bt, guitar_strum_bitmasks);
|
||||
|
||||
// flip button bits
|
||||
gdata->bt ^= 0xFFFF;
|
||||
|
|
|
@ -13,7 +13,7 @@ class Guitar : public Attachment
|
|||
{
|
||||
public:
|
||||
Guitar(WiimoteEmu::ExtensionReg& _reg);
|
||||
void GetState(u8* const data, const bool focus) override;
|
||||
void GetState(u8* const data) override;
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -4,9 +4,6 @@
|
|||
|
||||
#include "Core/HW/WiimoteEmu/Attachment/Nunchuk.h"
|
||||
|
||||
#include "InputCommon/UDPWiimote.h"
|
||||
#include "InputCommon/UDPWrapper.h"
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
|
||||
|
@ -31,8 +28,7 @@ static const u8 nunchuk_button_bitmasks[] =
|
|||
Nunchuk::BUTTON_Z,
|
||||
};
|
||||
|
||||
Nunchuk::Nunchuk(UDPWrapper *wrp, WiimoteEmu::ExtensionReg& _reg)
|
||||
: Attachment(_trans("Nunchuk"), _reg) , m_udpWrap(wrp)
|
||||
Nunchuk::Nunchuk(WiimoteEmu::ExtensionReg& _reg) : Attachment(_trans("Nunchuk"), _reg)
|
||||
{
|
||||
// buttons
|
||||
groups.emplace_back(m_buttons = new Buttons("Buttons"));
|
||||
|
@ -64,23 +60,23 @@ Nunchuk::Nunchuk(UDPWrapper *wrp, WiimoteEmu::ExtensionReg& _reg)
|
|||
memset(m_shake_step, 0, sizeof(m_shake_step));
|
||||
}
|
||||
|
||||
void Nunchuk::GetState(u8* const data, const bool focus)
|
||||
void Nunchuk::GetState(u8* const data)
|
||||
{
|
||||
wm_extension* const ncdata = (wm_extension*)data;
|
||||
ncdata->bt = 0;
|
||||
|
||||
// stick
|
||||
ControlState state[2];
|
||||
m_stick->GetState(&state[0], &state[1], 0, 1);
|
||||
double state[2];
|
||||
m_stick->GetState(&state[0], &state[1]);
|
||||
|
||||
nu_cal &cal = *(nu_cal*)®.calibration;
|
||||
nu_js cal_js[2];
|
||||
cal_js[0] = *&cal.jx;
|
||||
cal_js[1] = *&cal.jy;
|
||||
cal_js[0] = cal.jx;
|
||||
cal_js[1] = cal.jy;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ControlState &s = *&state[i];
|
||||
nu_js c = *&cal_js[i];
|
||||
double &s = state[i];
|
||||
nu_js c = cal_js[i];
|
||||
if (s < 0)
|
||||
s = s * abs(c.min - c.center) + c.center;
|
||||
else if (s > 0)
|
||||
|
@ -100,59 +96,21 @@ void Nunchuk::GetState(u8* const data, const bool focus)
|
|||
ncdata->jx = cal.jx.center + 1;
|
||||
}
|
||||
|
||||
if (!focus)
|
||||
{
|
||||
ncdata->jx = cal.jx.center;
|
||||
ncdata->jy = cal.jy.center;
|
||||
}
|
||||
|
||||
AccelData accel;
|
||||
|
||||
// tilt
|
||||
EmulateTilt(&accel, m_tilt, focus);
|
||||
EmulateTilt(&accel, m_tilt);
|
||||
|
||||
if (focus)
|
||||
{
|
||||
// swing
|
||||
EmulateSwing(&accel, m_swing);
|
||||
// shake
|
||||
EmulateShake(&accel, m_shake, m_shake_step);
|
||||
// buttons
|
||||
m_buttons->GetState(&ncdata->bt, nunchuk_button_bitmasks);
|
||||
}
|
||||
// swing
|
||||
EmulateSwing(&accel, m_swing);
|
||||
// shake
|
||||
EmulateShake(&accel, m_shake, m_shake_step);
|
||||
// buttons
|
||||
m_buttons->GetState(&ncdata->bt, nunchuk_button_bitmasks);
|
||||
|
||||
// flip the button bits :/
|
||||
ncdata->bt ^= 0x03;
|
||||
|
||||
if (m_udpWrap->inst)
|
||||
{
|
||||
if (m_udpWrap->updNun)
|
||||
{
|
||||
u8 mask;
|
||||
float x, y;
|
||||
m_udpWrap->inst->getNunchuck(&x, &y, &mask);
|
||||
// buttons
|
||||
if (mask & UDPWM_NC)
|
||||
ncdata->bt &= ~WiimoteEmu::Nunchuk::BUTTON_C;
|
||||
if (mask & UDPWM_NZ)
|
||||
ncdata->bt &= ~WiimoteEmu::Nunchuk::BUTTON_Z;
|
||||
// stick
|
||||
if (ncdata->jx == 0x80 && ncdata->jy == 0x80)
|
||||
{
|
||||
ncdata->jx = u8(0x80 + x*127);
|
||||
ncdata->jy = u8(0x80 + y*127);
|
||||
}
|
||||
}
|
||||
if (m_udpWrap->updNunAccel)
|
||||
{
|
||||
float x, y, z;
|
||||
m_udpWrap->inst->getNunchuckAccel(&x, &y, &z);
|
||||
accel.x = x;
|
||||
accel.y = y;
|
||||
accel.z = z;
|
||||
}
|
||||
}
|
||||
|
||||
FillRawAccelFromGForceData(*(wm_accel*)&ncdata->ax, *(accel_cal*)®.calibration, accel);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,17 +6,15 @@
|
|||
|
||||
#include "Core/HW/WiimoteEmu/Attachment/Attachment.h"
|
||||
|
||||
class UDPWrapper;
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
|
||||
class Nunchuk : public Attachment
|
||||
{
|
||||
public:
|
||||
Nunchuk(UDPWrapper * wrp, WiimoteEmu::ExtensionReg& _reg);
|
||||
Nunchuk(WiimoteEmu::ExtensionReg& _reg);
|
||||
|
||||
virtual void GetState(u8* const data, const bool focus) override;
|
||||
virtual void GetState(u8* const data) override;
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -36,8 +34,6 @@ private:
|
|||
AnalogStick* m_stick;
|
||||
|
||||
u8 m_shake_step[3];
|
||||
|
||||
UDPWrapper* const m_udpWrap;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -55,63 +55,68 @@ Turntable::Turntable(WiimoteEmu::ExtensionReg& _reg) : Attachment(_trans("Turnta
|
|||
memcpy(&id, turntable_id, sizeof(turntable_id));
|
||||
}
|
||||
|
||||
void Turntable::GetState(u8* const data, const bool focus)
|
||||
void Turntable::GetState(u8* const data)
|
||||
{
|
||||
wm_turntable_extension* const ttdata = (wm_turntable_extension*)data;
|
||||
ttdata->bt = 0;
|
||||
|
||||
// stick
|
||||
{
|
||||
u8 x, y;
|
||||
m_stick->GetState(&x, &y, 0x20, focus ? 0x1F /*0x15*/ : 0);
|
||||
double x, y;
|
||||
m_stick->GetState(&x, &y);
|
||||
|
||||
ttdata->sx = x;
|
||||
ttdata->sy = y;
|
||||
ttdata->sx = (x * 0x1F) + 0x20;
|
||||
ttdata->sy = (y * 0x1F) + 0x20;
|
||||
}
|
||||
|
||||
// left table
|
||||
{
|
||||
s8 tt = 0;
|
||||
m_left_table->GetState(&tt, focus ? 0x1F : 0);
|
||||
double tt;
|
||||
s8 tt_;
|
||||
m_left_table->GetState(&tt);
|
||||
|
||||
ttdata->ltable1 = tt;
|
||||
ttdata->ltable2 = tt >> 5;
|
||||
tt_ = tt * 0x1F;
|
||||
|
||||
ttdata->ltable1 = tt_;
|
||||
ttdata->ltable2 = tt_ >> 5;
|
||||
}
|
||||
|
||||
// right table
|
||||
{
|
||||
s8 tt = 0;
|
||||
m_right_table->GetState(&tt, focus ? 0x1F : 0);
|
||||
double tt;
|
||||
s8 tt_;
|
||||
m_right_table->GetState(&tt);
|
||||
|
||||
ttdata->rtable1 = tt;
|
||||
ttdata->rtable2 = tt >> 1;
|
||||
ttdata->rtable3 = tt >> 3;
|
||||
ttdata->rtable4 = tt >> 5;
|
||||
tt_ = tt * 0x1F;
|
||||
|
||||
ttdata->rtable1 = tt_;
|
||||
ttdata->rtable2 = tt_ >> 1;
|
||||
ttdata->rtable3 = tt_ >> 3;
|
||||
ttdata->rtable4 = tt_ >> 5;
|
||||
}
|
||||
|
||||
// effect dial
|
||||
{
|
||||
u8 dial = 0;
|
||||
m_effect_dial->GetState(&dial, focus ? 0xF : 0);
|
||||
double dial;
|
||||
u8 dial_;
|
||||
m_effect_dial->GetState(&dial);
|
||||
|
||||
ttdata->dial1 = dial;
|
||||
ttdata->dial2 = dial >> 3;
|
||||
dial_ = dial * 0x0F;
|
||||
|
||||
ttdata->dial1 = dial_;
|
||||
ttdata->dial2 = dial_ >> 3;
|
||||
}
|
||||
|
||||
// crossfade slider
|
||||
{
|
||||
s8 cfs = 0;
|
||||
m_crossfade->GetState(&cfs, focus ? 7 : 0);
|
||||
cfs += 8;
|
||||
double cfs;
|
||||
m_crossfade->GetState(&cfs);
|
||||
|
||||
ttdata->slider = cfs;
|
||||
ttdata->slider = (cfs * 0x07) + 0x08;
|
||||
}
|
||||
|
||||
if (focus)
|
||||
{
|
||||
// buttons
|
||||
m_buttons->GetState(&ttdata->bt, turntable_button_bitmasks);
|
||||
}
|
||||
// buttons
|
||||
m_buttons->GetState(&ttdata->bt, turntable_button_bitmasks);
|
||||
|
||||
// flip button bits :/
|
||||
ttdata->bt ^= (
|
||||
|
|
|
@ -13,7 +13,7 @@ class Turntable : public Attachment
|
|||
{
|
||||
public:
|
||||
Turntable(WiimoteEmu::ExtensionReg& _reg);
|
||||
void GetState(u8* const data, const bool focus) override;
|
||||
void GetState(u8* const data) override;
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
//UDP Wiimote Translation Layer
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Core/HW/WiimoteEmu/WiimoteEmu.h"
|
||||
#include "InputCommon/UDPWiimote.h"
|
||||
|
||||
namespace UDPTLayer
|
||||
{
|
||||
static void GetButtons(UDPWrapper * m , wm_core * butt)
|
||||
{
|
||||
if (!(m->inst)) return;
|
||||
if (!(m->updButt)) return;
|
||||
u32 mask = m->inst->getButtons();
|
||||
*butt |= (mask & UDPWM_BA) ? WiimoteEmu::Wiimote::BUTTON_A : 0;
|
||||
*butt |= (mask & UDPWM_BB) ? WiimoteEmu::Wiimote::BUTTON_B : 0;
|
||||
*butt |= (mask & UDPWM_B1) ? WiimoteEmu::Wiimote::BUTTON_ONE : 0;
|
||||
*butt |= (mask & UDPWM_B2) ? WiimoteEmu::Wiimote::BUTTON_TWO : 0;
|
||||
*butt |= (mask & UDPWM_BP) ? WiimoteEmu::Wiimote::BUTTON_PLUS : 0;
|
||||
*butt |= (mask & UDPWM_BM) ? WiimoteEmu::Wiimote::BUTTON_MINUS : 0;
|
||||
*butt |= (mask & UDPWM_BH) ? WiimoteEmu::Wiimote::BUTTON_HOME : 0;
|
||||
*butt |= (mask & UDPWM_BU) ? WiimoteEmu::Wiimote::PAD_UP : 0;
|
||||
*butt |= (mask & UDPWM_BD) ? WiimoteEmu::Wiimote::PAD_DOWN : 0;
|
||||
*butt |= (mask & UDPWM_BL) ? WiimoteEmu::Wiimote::PAD_LEFT : 0;
|
||||
*butt |= (mask & UDPWM_BR) ? WiimoteEmu::Wiimote::PAD_RIGHT : 0;
|
||||
}
|
||||
|
||||
static void GetAcceleration(UDPWrapper * m , WiimoteEmu::AccelData * const data)
|
||||
{
|
||||
if (!(m->inst)) return;
|
||||
if (!(m->updAccel)) return;
|
||||
float x, y, z;
|
||||
m->inst->getAccel(&x, &y, &z);
|
||||
data->x = x;
|
||||
data->y = y;
|
||||
data->z = z;
|
||||
}
|
||||
|
||||
static void GetIR( UDPWrapper * m, float * x, float * y, float * z)
|
||||
{
|
||||
if (!(m->inst)) return;
|
||||
if (!(m->updIR)) return;
|
||||
if ((*x >= -0.999) && (*x <= 0.999) && (*y >= -0.999) && (*y <= 0.999)) return; //the received values are used ONLY when the normal pointer is offscreen
|
||||
float _x, _y;
|
||||
m->inst->getIR(&_x, &_y);
|
||||
*x = _x * 2 - 1;
|
||||
*y = -(_y * 2 - 1);
|
||||
*z = 0;
|
||||
}
|
||||
}
|
|
@ -13,7 +13,6 @@
|
|||
#include "Core/NetPlayClient.h"
|
||||
|
||||
#include "Core/HW/WiimoteEmu/MatrixMath.h"
|
||||
#include "Core/HW/WiimoteEmu/UDPTLayer.h"
|
||||
#include "Core/HW/WiimoteEmu/WiimoteEmu.h"
|
||||
#include "Core/HW/WiimoteEmu/WiimoteHid.h"
|
||||
#include "Core/HW/WiimoteEmu/Attachment/Classic.h"
|
||||
|
@ -119,11 +118,14 @@ void EmulateShake(AccelData* const accel
|
|||
|
||||
void EmulateTilt(AccelData* const accel
|
||||
, ControllerEmu::Tilt* const tilt_group
|
||||
, const bool focus, const bool sideways, const bool upright)
|
||||
, const bool sideways, const bool upright)
|
||||
{
|
||||
float roll, pitch;
|
||||
double roll, pitch;
|
||||
// 180 degrees
|
||||
tilt_group->GetState(&roll, &pitch, 0, focus ? PI : 0);
|
||||
tilt_group->GetState(&roll, &pitch);
|
||||
|
||||
roll *= PI;
|
||||
pitch *= PI;
|
||||
|
||||
unsigned int ud = 0, lr = 0, fb = 0;
|
||||
|
||||
|
@ -145,7 +147,7 @@ void EmulateTilt(AccelData* const accel
|
|||
if (!sideways && upright)
|
||||
sgn[ud] *= -1;
|
||||
|
||||
(&accel->x)[ud] = (sin((PI / 2) - std::max(fabsf(roll), fabsf(pitch))))*sgn[ud];
|
||||
(&accel->x)[ud] = (sin((PI / 2) - std::max(fabs(roll), fabs(pitch))))*sgn[ud];
|
||||
(&accel->x)[lr] = -sin(roll)*sgn[lr];
|
||||
(&accel->x)[fb] = sin(pitch)*sgn[fb];
|
||||
}
|
||||
|
@ -156,8 +158,8 @@ void EmulateSwing(AccelData* const accel
|
|||
, ControllerEmu::Force* const swing_group
|
||||
, const bool sideways, const bool upright)
|
||||
{
|
||||
float swing[3];
|
||||
swing_group->GetState(swing, 0, SWING_INTENSITY);
|
||||
double swing[3];
|
||||
swing_group->GetState(swing);
|
||||
|
||||
s8 g_dir[3] = {-1, -1, -1};
|
||||
u8 axis_map[3];
|
||||
|
@ -175,7 +177,7 @@ void EmulateSwing(AccelData* const accel
|
|||
g_dir[axis_map[0]] *= -1;
|
||||
|
||||
for (unsigned int i=0; i<3; ++i)
|
||||
(&accel->x)[axis_map[i]] += swing[i] * g_dir[i];
|
||||
(&accel->x)[axis_map[i]] += swing[i] * g_dir[i] * SWING_INTENSITY;
|
||||
}
|
||||
|
||||
const u16 button_bitmasks[] =
|
||||
|
@ -266,9 +268,6 @@ Wiimote::Wiimote( const unsigned int index )
|
|||
for (auto& named_button : named_buttons)
|
||||
m_buttons->controls.emplace_back(new ControlGroup::Input( named_button));
|
||||
|
||||
// udp
|
||||
groups.emplace_back(m_udp = new UDPWrapper(m_index, _trans("UDP Wiimote")));
|
||||
|
||||
// ir
|
||||
groups.emplace_back(m_ir = new Cursor(_trans("IR")));
|
||||
|
||||
|
@ -287,7 +286,7 @@ Wiimote::Wiimote( const unsigned int index )
|
|||
// extension
|
||||
groups.emplace_back(m_extension = new Extension(_trans("Extension")));
|
||||
m_extension->attachments.emplace_back(new WiimoteEmu::None(m_reg_ext));
|
||||
m_extension->attachments.emplace_back(new WiimoteEmu::Nunchuk(m_udp, m_reg_ext));
|
||||
m_extension->attachments.emplace_back(new WiimoteEmu::Nunchuk(m_reg_ext));
|
||||
m_extension->attachments.emplace_back(new WiimoteEmu::Classic(m_reg_ext));
|
||||
m_extension->attachments.emplace_back(new WiimoteEmu::Guitar(m_reg_ext));
|
||||
m_extension->attachments.emplace_back(new WiimoteEmu::Drums(m_reg_ext));
|
||||
|
@ -306,7 +305,7 @@ Wiimote::Wiimote( const unsigned int index )
|
|||
|
||||
// options
|
||||
groups.emplace_back( m_options = new ControlGroup(_trans("Options")));
|
||||
m_options->settings.emplace_back(new ControlGroup::Setting(_trans("Background Input"), false));
|
||||
m_options->settings.emplace_back(new ControlGroup::BackgroundInputSetting(_trans("Background Input")));
|
||||
m_options->settings.emplace_back(new ControlGroup::Setting(_trans("Sideways Wiimote"), false));
|
||||
m_options->settings.emplace_back(new ControlGroup::Setting(_trans("Upright Wiimote"), false));
|
||||
|
||||
|
@ -322,26 +321,17 @@ std::string Wiimote::GetName() const
|
|||
return std::string("Wiimote") + char('1'+m_index);
|
||||
}
|
||||
|
||||
// if windows is focused or background input is enabled
|
||||
#define HAS_FOCUS (Host_RendererHasFocus() || (m_options->settings[0]->value != 0))
|
||||
|
||||
bool Wiimote::Step()
|
||||
{
|
||||
const bool has_focus = HAS_FOCUS;
|
||||
|
||||
// TODO: change this a bit
|
||||
m_motion_plus_present = m_extension->settings[0]->value != 0;
|
||||
|
||||
// no rumble if no focus
|
||||
if (false == has_focus)
|
||||
m_rumble_on = false;
|
||||
|
||||
m_rumble->controls[0]->control_ref->State(m_rumble_on);
|
||||
|
||||
// when a movie is active, this button status update is disabled (moved), because movies only record data reports.
|
||||
if (!(Movie::IsPlayingInput() || Movie::IsRecordingInput()) || NetPlay::IsNetPlayRunning())
|
||||
{
|
||||
UpdateButtonsStatus(has_focus);
|
||||
UpdateButtonsStatus();
|
||||
}
|
||||
|
||||
// check if there is a read data request
|
||||
|
@ -381,17 +371,13 @@ bool Wiimote::Step()
|
|||
return false;
|
||||
}
|
||||
|
||||
void Wiimote::UpdateButtonsStatus(bool has_focus)
|
||||
void Wiimote::UpdateButtonsStatus()
|
||||
{
|
||||
// update buttons in status struct
|
||||
m_status.buttons = 0;
|
||||
if (has_focus)
|
||||
{
|
||||
const bool is_sideways = m_options->settings[1]->value != 0;
|
||||
m_buttons->GetState(&m_status.buttons, button_bitmasks);
|
||||
m_dpad->GetState(&m_status.buttons, is_sideways ? dpad_sideways_bitmasks : dpad_bitmasks);
|
||||
UDPTLayer::GetButtons(m_udp, &m_status.buttons);
|
||||
}
|
||||
const bool is_sideways = m_options->settings[1]->value != 0;
|
||||
m_buttons->GetState(&m_status.buttons, button_bitmasks);
|
||||
m_dpad->GetState(&m_status.buttons, is_sideways ? dpad_sideways_bitmasks : dpad_bitmasks);
|
||||
}
|
||||
|
||||
void Wiimote::GetCoreData(u8* const data)
|
||||
|
@ -399,7 +385,7 @@ void Wiimote::GetCoreData(u8* const data)
|
|||
// when a movie is active, the button update happens here instead of Wiimote::Step, to avoid potential desync issues.
|
||||
if (Movie::IsPlayingInput() || Movie::IsRecordingInput() || NetPlay::IsNetPlayRunning())
|
||||
{
|
||||
UpdateButtonsStatus(HAS_FOCUS);
|
||||
UpdateButtonsStatus();
|
||||
}
|
||||
|
||||
*(wm_core*)data |= m_status.buttons;
|
||||
|
@ -407,21 +393,16 @@ void Wiimote::GetCoreData(u8* const data)
|
|||
|
||||
void Wiimote::GetAccelData(u8* const data)
|
||||
{
|
||||
const bool has_focus = HAS_FOCUS;
|
||||
const bool is_sideways = m_options->settings[1]->value != 0;
|
||||
const bool is_upright = m_options->settings[2]->value != 0;
|
||||
|
||||
// ----TILT----
|
||||
EmulateTilt(&m_accel, m_tilt, has_focus, is_sideways, is_upright);
|
||||
EmulateTilt(&m_accel, m_tilt, is_sideways, is_upright);
|
||||
|
||||
// ----SWING----
|
||||
// ----SHAKE----
|
||||
if (has_focus)
|
||||
{
|
||||
EmulateSwing(&m_accel, m_swing, is_sideways, is_upright);
|
||||
EmulateShake(&m_accel, m_shake, m_shake_step);
|
||||
UDPTLayer::GetAcceleration(m_udp, &m_accel);
|
||||
}
|
||||
EmulateSwing(&m_accel, m_swing, is_sideways, is_upright);
|
||||
EmulateShake(&m_accel, m_shake, m_shake_step);
|
||||
|
||||
FillRawAccelFromGForceData(*(wm_accel*)data, *(accel_cal*)&m_eeprom[0x16], m_accel);
|
||||
}
|
||||
|
@ -435,94 +416,89 @@ inline void LowPassFilter(double & var, double newval, double period)
|
|||
|
||||
void Wiimote::GetIRData(u8* const data, bool use_accel)
|
||||
{
|
||||
const bool has_focus = HAS_FOCUS;
|
||||
|
||||
u16 x[4], y[4];
|
||||
memset(x, 0xFF, sizeof(x));
|
||||
|
||||
if (has_focus)
|
||||
{
|
||||
float xx = 10000, yy = 0, zz = 0;
|
||||
double nsin,ncos;
|
||||
double xx = 10000, yy = 0, zz = 0;
|
||||
double nsin,ncos;
|
||||
|
||||
if (use_accel)
|
||||
if (use_accel)
|
||||
{
|
||||
double ax,az,len;
|
||||
ax=m_accel.x;
|
||||
az=m_accel.z;
|
||||
len=sqrt(ax*ax+az*az);
|
||||
if (len)
|
||||
{
|
||||
double ax,az,len;
|
||||
ax=m_accel.x;
|
||||
az=m_accel.z;
|
||||
len=sqrt(ax*ax+az*az);
|
||||
if (len)
|
||||
{
|
||||
ax/=len;
|
||||
az/=len; //normalizing the vector
|
||||
nsin=ax;
|
||||
ncos=az;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsin=0;
|
||||
ncos=1;
|
||||
}
|
||||
// PanicAlert("%d %d %d\nx:%f\nz:%f\nsin:%f\ncos:%f",accel->x,accel->y,accel->z,ax,az,sin,cos);
|
||||
// PanicAlert("%d %d %d\n%d %d %d\n%d %d %d",accel->x,accel->y,accel->z,calib->zero_g.x,calib->zero_g.y,calib->zero_g.z, calib->one_g.x,calib->one_g.y,calib->one_g.z);
|
||||
ax/=len;
|
||||
az/=len; //normalizing the vector
|
||||
nsin=ax;
|
||||
ncos=az;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsin=0; //m_tilt stuff here (can't figure it out yet....)
|
||||
nsin=0;
|
||||
ncos=1;
|
||||
}
|
||||
// PanicAlert("%d %d %d\nx:%f\nz:%f\nsin:%f\ncos:%f",accel->x,accel->y,accel->z,ax,az,sin,cos);
|
||||
// PanicAlert("%d %d %d\n%d %d %d\n%d %d %d",accel->x,accel->y,accel->z,calib->zero_g.x,calib->zero_g.y,calib->zero_g.z, calib->one_g.x,calib->one_g.y,calib->one_g.z);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsin=0; //m_tilt stuff here (can't figure it out yet....)
|
||||
ncos=1;
|
||||
}
|
||||
|
||||
LowPassFilter(ir_sin,nsin,1.0f/60);
|
||||
LowPassFilter(ir_cos,ncos,1.0f/60);
|
||||
LowPassFilter(ir_sin,nsin,1.0f/60);
|
||||
LowPassFilter(ir_cos,ncos,1.0f/60);
|
||||
|
||||
m_ir->GetState(&xx, &yy, &zz, true);
|
||||
UDPTLayer::GetIR(m_udp, &xx, &yy, &zz);
|
||||
m_ir->GetState(&xx, &yy, &zz, true);
|
||||
|
||||
Vertex v[4];
|
||||
Vertex v[4];
|
||||
|
||||
static const int camWidth=1024;
|
||||
static const int camHeight=768;
|
||||
static const double bndup=-0.315447;
|
||||
static const double bnddown=0.85;
|
||||
static const double bndleft=0.443364;
|
||||
static const double bndright=-0.443364;
|
||||
static const double dist1=100.f/camWidth; //this seems the optimal distance for zelda
|
||||
static const double dist2=1.2f*dist1;
|
||||
static const int camWidth=1024;
|
||||
static const int camHeight=768;
|
||||
static const double bndup=-0.315447;
|
||||
static const double bnddown=0.85;
|
||||
static const double bndleft=0.443364;
|
||||
static const double bndright=-0.443364;
|
||||
static const double dist1=100.f/camWidth; //this seems the optimal distance for zelda
|
||||
static const double dist2=1.2f*dist1;
|
||||
|
||||
for (auto& vtx : v)
|
||||
{
|
||||
vtx.x=xx*(bndright-bndleft)/2+(bndleft+bndright)/2;
|
||||
if (m_sensor_bar_on_top) vtx.y=yy*(bndup-bnddown)/2+(bndup+bnddown)/2;
|
||||
else vtx.y=yy*(bndup-bnddown)/2-(bndup+bnddown)/2;
|
||||
vtx.z=0;
|
||||
}
|
||||
for (auto& vtx : v)
|
||||
{
|
||||
vtx.x=xx*(bndright-bndleft)/2+(bndleft+bndright)/2;
|
||||
if (m_sensor_bar_on_top) vtx.y=yy*(bndup-bnddown)/2+(bndup+bnddown)/2;
|
||||
else vtx.y=yy*(bndup-bnddown)/2-(bndup+bnddown)/2;
|
||||
vtx.z=0;
|
||||
}
|
||||
|
||||
v[0].x-=(zz*0.5+1)*dist1;
|
||||
v[1].x+=(zz*0.5+1)*dist1;
|
||||
v[2].x-=(zz*0.5+1)*dist2;
|
||||
v[3].x+=(zz*0.5+1)*dist2;
|
||||
v[0].x-=(zz*0.5+1)*dist1;
|
||||
v[1].x+=(zz*0.5+1)*dist1;
|
||||
v[2].x-=(zz*0.5+1)*dist2;
|
||||
v[3].x+=(zz*0.5+1)*dist2;
|
||||
|
||||
#define printmatrix(m) PanicAlert("%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n",m[0][0],m[0][1],m[0][2],m[0][3],m[1][0],m[1][1],m[1][2],m[1][3],m[2][0],m[2][1],m[2][2],m[2][3],m[3][0],m[3][1],m[3][2],m[3][3])
|
||||
Matrix rot,tot;
|
||||
static Matrix scale;
|
||||
MatrixScale(scale,1,camWidth/camHeight,1);
|
||||
//MatrixIdentity(scale);
|
||||
MatrixRotationByZ(rot,ir_sin,ir_cos);
|
||||
//MatrixIdentity(rot);
|
||||
MatrixMultiply(tot,scale,rot);
|
||||
Matrix rot,tot;
|
||||
static Matrix scale;
|
||||
MatrixScale(scale,1,camWidth/camHeight,1);
|
||||
//MatrixIdentity(scale);
|
||||
MatrixRotationByZ(rot,ir_sin,ir_cos);
|
||||
//MatrixIdentity(rot);
|
||||
MatrixMultiply(tot,scale,rot);
|
||||
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
MatrixTransformVertex(tot,v[i]);
|
||||
if ((v[i].x<-1)||(v[i].x>1)||(v[i].y<-1)||(v[i].y>1))
|
||||
continue;
|
||||
x[i] = (u16)lround((v[i].x+1)/2*(camWidth-1));
|
||||
y[i] = (u16)lround((v[i].y+1)/2*(camHeight-1));
|
||||
}
|
||||
// PanicAlert("%f %f\n%f %f\n%f %f\n%f %f\n%d %d\n%d %d\n%d %d\n%d %d",
|
||||
// v[0].x,v[0].y,v[1].x,v[1].y,v[2].x,v[2].y,v[3].x,v[3].y,
|
||||
// x[0],y[0],x[1],y[1],x[2],y[2],x[3],y[38]);
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
MatrixTransformVertex(tot,v[i]);
|
||||
if ((v[i].x<-1)||(v[i].x>1)||(v[i].y<-1)||(v[i].y>1))
|
||||
continue;
|
||||
x[i] = (u16)lround((v[i].x+1)/2*(camWidth-1));
|
||||
y[i] = (u16)lround((v[i].y+1)/2*(camHeight-1));
|
||||
}
|
||||
// PanicAlert("%f %f\n%f %f\n%f %f\n%f %f\n%d %d\n%d %d\n%d %d\n%d %d",
|
||||
// v[0].x,v[0].y,v[1].x,v[1].y,v[2].x,v[2].y,v[3].x,v[3].y,
|
||||
// x[0],y[0],x[1],y[1],x[2],y[2],x[3],y[38]);
|
||||
|
||||
// Fill report with valid data when full handshake was done
|
||||
if (m_reg_ir.data[0x30])
|
||||
// ir mode
|
||||
|
@ -582,7 +558,7 @@ void Wiimote::GetIRData(u8* const data, bool use_accel)
|
|||
|
||||
void Wiimote::GetExtData(u8* const data)
|
||||
{
|
||||
m_extension->GetState(data, HAS_FOCUS);
|
||||
m_extension->GetState(data);
|
||||
|
||||
// i dont think anything accesses the extension data like this, but ill support it. Indeed, commercial games don't do this.
|
||||
// i think it should be unencrpyted in the register, encrypted when read.
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "Core/HW/WiimoteEmu/Encryption.h"
|
||||
#include "Core/HW/WiimoteEmu/WiimoteHid.h"
|
||||
#include "InputCommon/ControllerEmu.h"
|
||||
#include "InputCommon/UDPWrapper.h"
|
||||
|
||||
// Registry sizes
|
||||
#define WIIMOTE_EEPROM_SIZE (16*1024)
|
||||
|
@ -78,7 +77,7 @@ void EmulateShake(AccelData* const accel_data
|
|||
|
||||
void EmulateTilt(AccelData* const accel
|
||||
, ControllerEmu::Tilt* const tilt_group
|
||||
, const bool focus, const bool sideways = false, const bool upright = false);
|
||||
, const bool sideways = false, const bool upright = false);
|
||||
|
||||
void EmulateSwing(AccelData* const accel
|
||||
, ControllerEmu::Force* const tilt_group
|
||||
|
@ -129,7 +128,7 @@ protected:
|
|||
bool Step();
|
||||
void HidOutputReport(const wm_report* const sr, const bool send_ack = true);
|
||||
void HandleExtensionSwap();
|
||||
void UpdateButtonsStatus(bool has_focus);
|
||||
void UpdateButtonsStatus();
|
||||
|
||||
void GetCoreData(u8* const data);
|
||||
void GetAccelData(u8* const data);
|
||||
|
@ -175,8 +174,6 @@ private:
|
|||
|
||||
double ir_sin, ir_cos; //for the low pass filter
|
||||
|
||||
UDPWrapper* m_udp;
|
||||
|
||||
bool m_rumble_on;
|
||||
bool m_speaker_mute;
|
||||
bool m_motion_plus_present;
|
||||
|
|
|
@ -89,7 +89,6 @@ if(wxWidgets_FOUND)
|
|||
PHackSettings.cpp
|
||||
PatchAddEdit.cpp
|
||||
TASInputDlg.cpp
|
||||
UDPConfigDiag.cpp
|
||||
VideoConfigDiag.cpp
|
||||
WXInputBase.cpp
|
||||
WiimoteConfigDiag.cpp
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
|
@ -95,7 +95,6 @@
|
|||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TASInputDlg.cpp" />
|
||||
<ClCompile Include="UDPConfigDiag.cpp" />
|
||||
<ClCompile Include="VideoConfigDiag.cpp" />
|
||||
<ClCompile Include="WiimoteConfigDiag.cpp" />
|
||||
<ClCompile Include="WXInputBase.cpp" />
|
||||
|
@ -144,7 +143,6 @@
|
|||
<ClInclude Include="PHackSettings.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="TASInputDlg.h" />
|
||||
<ClInclude Include="UDPConfigDiag.h" />
|
||||
<ClInclude Include="VideoConfigDiag.h" />
|
||||
<ClInclude Include="WiimoteConfigDiag.h" />
|
||||
<ClInclude Include="WXInputBase.h" />
|
||||
|
@ -230,4 +228,4 @@
|
|||
<Message Text="Copy: @(BinaryFiles) -> $(BinaryOutputDir)" Importance="High" />
|
||||
<Copy SourceFiles="@(BinaryFiles)" DestinationFolder="$(BinaryOutputDir)" />
|
||||
</Target>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="GUI">
|
||||
|
@ -152,9 +152,6 @@
|
|||
<ClCompile Include="TASInputDlg.cpp">
|
||||
<Filter>GUI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UDPConfigDiag.cpp">
|
||||
<Filter>GUI</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="WiimoteConfigDiag.cpp">
|
||||
<Filter>GUI</Filter>
|
||||
</ClCompile>
|
||||
|
@ -280,9 +277,6 @@
|
|||
<ClInclude Include="TASInputDlg.h">
|
||||
<Filter>GUI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UDPConfigDiag.h">
|
||||
<Filter>GUI</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="WiimoteConfigDiag.h">
|
||||
<Filter>GUI</Filter>
|
||||
</ClInclude>
|
||||
|
@ -302,4 +296,4 @@
|
|||
<Filter>Resources</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -753,24 +753,15 @@ void CFrame::OnRenderWindowSizeRequest(int width, int height)
|
|||
|
||||
bool CFrame::RendererHasFocus()
|
||||
{
|
||||
if (m_RenderParent == nullptr)
|
||||
return false;
|
||||
#ifdef _WIN32
|
||||
if (m_RenderParent->GetParent()->GetHWND() == GetForegroundWindow())
|
||||
return true;
|
||||
#else
|
||||
wxWindow *window = wxWindow::FindFocus();
|
||||
if (window == nullptr)
|
||||
return false;
|
||||
// Why these different cases?
|
||||
if (m_RenderParent == window ||
|
||||
m_RenderParent == window->GetParent() ||
|
||||
m_RenderParent->GetParent() == window->GetParent())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
// RendererHasFocus should return true any time any one of our
|
||||
// windows has the focus, including any dialogs or other windows.
|
||||
//
|
||||
// wxGetActiveWindow() returns the current wxWindow which has
|
||||
// focus. If it's not one of our windows, then it will return
|
||||
// null.
|
||||
|
||||
wxWindow *focusWindow = wxGetActiveWindow();
|
||||
return (focusWindow != nullptr);
|
||||
}
|
||||
|
||||
void CFrame::OnGameListCtrl_ItemActivated(wxListEvent& WXUNUSED (event))
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
#include "Common/MsgHandler.h"
|
||||
#include "Core/HW/Wiimote.h"
|
||||
#include "DolphinWX/InputConfigDiag.h"
|
||||
#include "DolphinWX/UDPConfigDiag.h"
|
||||
#include "DolphinWX/WxUtils.h"
|
||||
#include "InputCommon/ControllerEmu.h"
|
||||
#include "InputCommon/InputConfig.h"
|
||||
|
@ -53,18 +52,10 @@
|
|||
#include "InputCommon/ControllerInterface/Device.h"
|
||||
#include "InputCommon/ControllerInterface/ExpressionParser.h"
|
||||
|
||||
class UDPWrapper;
|
||||
class wxWindow;
|
||||
|
||||
using namespace ciface::ExpressionParser;
|
||||
|
||||
void GamepadPage::ConfigUDPWii(wxCommandEvent &event)
|
||||
{
|
||||
UDPWrapper* const wrp = ((UDPConfigButton*)event.GetEventObject())->wrapper;
|
||||
UDPConfigDiag diag(this, wrp);
|
||||
diag.ShowModal();
|
||||
}
|
||||
|
||||
void GamepadPage::ConfigExtension(wxCommandEvent& event)
|
||||
{
|
||||
ControllerEmu::Extension* const ex = ((ExtensionButton*)event.GetEventObject())->extension;
|
||||
|
@ -113,32 +104,32 @@ void PadSettingExtension::UpdateValue()
|
|||
extension->switch_extension = ((wxChoice*)wxcontrol)->GetSelection();
|
||||
}
|
||||
|
||||
PadSettingCheckBox::PadSettingCheckBox(wxWindow* const parent, ControlState& _value, const std::string& label)
|
||||
: PadSetting(new wxCheckBox(parent, -1, wxGetTranslation(StrToWxStr(label))))
|
||||
, value(_value)
|
||||
PadSettingCheckBox::PadSettingCheckBox(wxWindow* const parent, ControllerEmu::ControlGroup::Setting* const _setting)
|
||||
: PadSetting(new wxCheckBox(parent, -1, wxGetTranslation(StrToWxStr(_setting->name))))
|
||||
, setting(_setting)
|
||||
{
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
void PadSettingCheckBox::UpdateGUI()
|
||||
{
|
||||
((wxCheckBox*)wxcontrol)->SetValue(value > 0);
|
||||
((wxCheckBox*)wxcontrol)->SetValue(setting->GetValue());
|
||||
}
|
||||
|
||||
void PadSettingCheckBox::UpdateValue()
|
||||
{
|
||||
// 0.01 so its saved to the ini file as just 1. :(
|
||||
value = 0.01 * ((wxCheckBox*)wxcontrol)->GetValue();
|
||||
setting->SetValue(0.01 * ((wxCheckBox*)wxcontrol)->GetValue());
|
||||
}
|
||||
|
||||
void PadSettingSpin::UpdateGUI()
|
||||
{
|
||||
((wxSpinCtrl*)wxcontrol)->SetValue((int)(value * 100));
|
||||
((wxSpinCtrl*)wxcontrol)->SetValue((int)(setting->GetValue() * 100));
|
||||
}
|
||||
|
||||
void PadSettingSpin::UpdateValue()
|
||||
{
|
||||
value = float(((wxSpinCtrl*)wxcontrol)->GetValue()) / 100;
|
||||
setting->SetValue(float(((wxSpinCtrl*)wxcontrol)->GetValue()) / 100);
|
||||
}
|
||||
|
||||
ControlDialog::ControlDialog(GamepadPage* const parent, InputPlugin& plugin, ControllerInterface::ControlReference* const ref)
|
||||
|
@ -883,19 +874,12 @@ ControlGroupBox::ControlGroupBox(ControllerEmu::ControlGroup* const group, wxWin
|
|||
Add(configure_btn, 0, wxALL|wxEXPAND, 3);
|
||||
}
|
||||
break;
|
||||
case GROUP_TYPE_UDPWII:
|
||||
{
|
||||
wxButton* const btn = new UDPConfigButton(parent, (UDPWrapper*)group);
|
||||
btn->Bind(wxEVT_BUTTON, &GamepadPage::ConfigUDPWii, eventsink);
|
||||
Add(btn, 0, wxALL|wxEXPAND, 3);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
//options
|
||||
for (auto& groupSetting : group->settings)
|
||||
{
|
||||
PadSettingCheckBox* setting_cbox = new PadSettingCheckBox(parent, groupSetting->value, groupSetting->name);
|
||||
PadSettingCheckBox* setting_cbox = new PadSettingCheckBox(parent, groupSetting.get());
|
||||
setting_cbox->wxcontrol->Bind(wxEVT_CHECKBOX, &GamepadPage::AdjustSetting, eventsink);
|
||||
options.push_back(setting_cbox);
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "InputCommon/ControllerInterface/Device.h"
|
||||
|
||||
class InputPlugin;
|
||||
class UDPWrapper;
|
||||
class wxComboBox;
|
||||
class wxCommandEvent;
|
||||
class wxEvent;
|
||||
|
@ -70,25 +69,25 @@ public:
|
|||
class PadSettingSpin : public PadSetting
|
||||
{
|
||||
public:
|
||||
PadSettingSpin(wxWindow* const parent, ControllerEmu::ControlGroup::Setting* const setting)
|
||||
: PadSetting(new wxSpinCtrl(parent, -1, wxEmptyString, wxDefaultPosition
|
||||
, wxSize(54, -1), 0, setting->low, setting->high, (int)(setting->value * 100)))
|
||||
, value(setting->value) {}
|
||||
PadSettingSpin(wxWindow* const parent, ControllerEmu::ControlGroup::Setting* const _setting)
|
||||
: PadSetting(new wxSpinCtrl(parent, -1, wxEmptyString, wxDefaultPosition,
|
||||
wxSize(54, -1), 0, _setting->low, _setting->high, (int)(_setting->value * 100)))
|
||||
, setting(_setting) {}
|
||||
|
||||
void UpdateGUI() override;
|
||||
void UpdateValue() override;
|
||||
|
||||
ControlState& value;
|
||||
ControllerEmu::ControlGroup::Setting* const setting;
|
||||
};
|
||||
|
||||
class PadSettingCheckBox : public PadSetting
|
||||
{
|
||||
public:
|
||||
PadSettingCheckBox(wxWindow* const parent, ControlState& _value, const std::string& label);
|
||||
PadSettingCheckBox(wxWindow* const parent, ControllerEmu::ControlGroup::Setting* const setting);
|
||||
void UpdateGUI() override;
|
||||
void UpdateValue() override;
|
||||
|
||||
ControlState& value;
|
||||
ControllerEmu::ControlGroup::Setting* const setting;
|
||||
};
|
||||
|
||||
class GamepadPage;
|
||||
|
@ -147,16 +146,6 @@ public:
|
|||
ControllerInterface::ControlReference* const control_reference;
|
||||
};
|
||||
|
||||
class UDPConfigButton : public wxButton
|
||||
{
|
||||
public:
|
||||
UDPWrapper* const wrapper;
|
||||
UDPConfigButton(wxWindow* const parent, UDPWrapper * udp)
|
||||
: wxButton(parent, -1, _("Configure"), wxDefaultPosition)
|
||||
, wrapper(udp)
|
||||
{}
|
||||
};
|
||||
|
||||
class ControlGroupBox : public wxBoxSizer
|
||||
{
|
||||
public:
|
||||
|
@ -200,8 +189,6 @@ public:
|
|||
|
||||
void ConfigExtension(wxCommandEvent& event);
|
||||
|
||||
void ConfigUDPWii(wxCommandEvent& event);
|
||||
|
||||
void SetDevice(wxCommandEvent& event);
|
||||
|
||||
void ClearAll(wxCommandEvent& event);
|
||||
|
|
|
@ -29,6 +29,360 @@
|
|||
|
||||
class wxTimerEvent;
|
||||
|
||||
static void DrawCenteredRectangle(wxDC &dc, int x, int y, int w, int h)
|
||||
{
|
||||
x -= w / 2;
|
||||
y -= h / 2;
|
||||
dc.DrawRectangle(x, y, w, h);
|
||||
}
|
||||
|
||||
#define VIS_BITMAP_SIZE 64
|
||||
|
||||
#define VIS_NORMALIZE(a) ((a / 2.0) + 0.5)
|
||||
#define VIS_COORD(a) ((VIS_NORMALIZE(a)) * VIS_BITMAP_SIZE)
|
||||
|
||||
#define COORD_VIS_SIZE 4
|
||||
|
||||
static void DrawCoordinate(wxDC &dc, double x, double y)
|
||||
{
|
||||
int xc = VIS_COORD(x);
|
||||
int yc = VIS_COORD(y);
|
||||
DrawCenteredRectangle(dc, xc, yc, COORD_VIS_SIZE, COORD_VIS_SIZE);
|
||||
}
|
||||
|
||||
static void DrawControlGroupBox(wxDC &dc, ControlGroupBox *g)
|
||||
{
|
||||
switch (g->control_group->type)
|
||||
{
|
||||
case GROUP_TYPE_TILT :
|
||||
case GROUP_TYPE_STICK :
|
||||
case GROUP_TYPE_CURSOR :
|
||||
{
|
||||
// this is starting to be a mess combining all these in one case
|
||||
|
||||
double x = 0, y = 0, z = 0;
|
||||
|
||||
switch (g->control_group->type)
|
||||
{
|
||||
case GROUP_TYPE_STICK :
|
||||
((ControllerEmu::AnalogStick*)g->control_group)->GetState(&x, &y);
|
||||
break;
|
||||
case GROUP_TYPE_TILT :
|
||||
((ControllerEmu::Tilt*)g->control_group)->GetState(&x, &y);
|
||||
break;
|
||||
case GROUP_TYPE_CURSOR :
|
||||
((ControllerEmu::Cursor*)g->control_group)->GetState(&x, &y, &z);
|
||||
break;
|
||||
}
|
||||
|
||||
// ir cursor forward movement
|
||||
if (GROUP_TYPE_CURSOR == g->control_group->type)
|
||||
{
|
||||
if (z)
|
||||
{
|
||||
dc.SetPen(*wxRED_PEN);
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
}
|
||||
else
|
||||
{
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
dc.SetBrush(*wxGREY_BRUSH);
|
||||
}
|
||||
dc.DrawRectangle(0, 31 - z*31, 64, 2);
|
||||
}
|
||||
|
||||
// octagon for visual aid for diagonal adjustment
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
dc.SetBrush(*wxWHITE_BRUSH);
|
||||
if (GROUP_TYPE_STICK == g->control_group->type)
|
||||
{
|
||||
// outline and fill colors
|
||||
wxBrush LightGrayBrush("#dddddd");
|
||||
wxPen LightGrayPen("#bfbfbf");
|
||||
dc.SetBrush(LightGrayBrush);
|
||||
dc.SetPen(LightGrayPen);
|
||||
|
||||
// polygon offset
|
||||
float max
|
||||
, diagonal
|
||||
, box = 64
|
||||
, d_of = box / 256.0
|
||||
, x_of = box / 2.0;
|
||||
|
||||
if (g->control_group->name == "Main Stick")
|
||||
{
|
||||
max = (87.0f / 127.0f) * 100;
|
||||
diagonal = (55.0f / 127.0f) * 100.0;
|
||||
}
|
||||
else if (g->control_group->name == "C-Stick")
|
||||
{
|
||||
max = (74.0f / 127.0f) * 100;
|
||||
diagonal = (46.0f / 127.0f) * 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
max = (82.0f / 127.0f) * 100;
|
||||
diagonal = (58.0f / 127.0f) * 100;
|
||||
}
|
||||
|
||||
// polygon corners
|
||||
wxPoint Points[8];
|
||||
Points[0].x = (int)(0.0 * d_of + x_of); Points[0].y = (int)(max * d_of + x_of);
|
||||
Points[1].x = (int)(diagonal * d_of + x_of); Points[1].y = (int)(diagonal * d_of + x_of);
|
||||
Points[2].x = (int)(max * d_of + x_of); Points[2].y = (int)(0.0 * d_of + x_of);
|
||||
Points[3].x = (int)(diagonal * d_of + x_of); Points[3].y = (int)(-diagonal * d_of + x_of);
|
||||
Points[4].x = (int)(0.0 * d_of + x_of); Points[4].y = (int)(-max * d_of + x_of);
|
||||
Points[5].x = (int)(-diagonal * d_of + x_of); Points[5].y = (int)(-diagonal * d_of + x_of);
|
||||
Points[6].x = (int)(-max * d_of + x_of); Points[6].y = (int)(0.0 * d_of + x_of);
|
||||
Points[7].x = (int)(-diagonal * d_of + x_of); Points[7].y = (int)(diagonal * d_of + x_of);
|
||||
|
||||
// draw polygon
|
||||
dc.DrawPolygon(8, Points);
|
||||
}
|
||||
else
|
||||
{
|
||||
dc.DrawRectangle(16, 16, 32, 32);
|
||||
}
|
||||
|
||||
if (GROUP_TYPE_CURSOR != g->control_group->type)
|
||||
{
|
||||
// deadzone circle
|
||||
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
|
||||
dc.DrawCircle(32, 32, g->control_group->settings[SETTING_DEADZONE]->value * 32);
|
||||
}
|
||||
|
||||
// raw dot
|
||||
{
|
||||
float xx, yy;
|
||||
xx = g->control_group->controls[3]->control_ref->State();
|
||||
xx -= g->control_group->controls[2]->control_ref->State();
|
||||
yy = g->control_group->controls[1]->control_ref->State();
|
||||
yy -= g->control_group->controls[0]->control_ref->State();
|
||||
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
dc.SetBrush(*wxGREY_BRUSH);
|
||||
DrawCoordinate(dc, xx, yy);
|
||||
}
|
||||
|
||||
// adjusted dot
|
||||
if (x != 0 && y != 0)
|
||||
{
|
||||
dc.SetPen(*wxRED_PEN);
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
// XXX: The adjusted values flip the Y axis to be in the format
|
||||
// the Wii expects. Should this be in WiimoteEmu.cpp instead?
|
||||
DrawCoordinate(dc, x, -y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GROUP_TYPE_FORCE :
|
||||
{
|
||||
double raw_dot[3];
|
||||
double adj_dot[3];
|
||||
const float deadzone = g->control_group->settings[0]->value;
|
||||
|
||||
// adjusted
|
||||
((ControllerEmu::Force*)g->control_group)->GetState(adj_dot);
|
||||
|
||||
// raw
|
||||
for (unsigned int i=0; i<3; ++i)
|
||||
{
|
||||
raw_dot[i] = (g->control_group->controls[i*2 + 1]->control_ref->State() -
|
||||
g->control_group->controls[i*2]->control_ref->State());
|
||||
}
|
||||
|
||||
// deadzone rect for forward/backward visual
|
||||
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
int deadzone_height = deadzone * VIS_BITMAP_SIZE;
|
||||
DrawCenteredRectangle(dc, 0, VIS_BITMAP_SIZE / 2, VIS_BITMAP_SIZE, deadzone_height);
|
||||
|
||||
#define LINE_HEIGHT 2
|
||||
int line_y;
|
||||
|
||||
// raw forward/background line
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
dc.SetBrush(*wxGREY_BRUSH);
|
||||
line_y = VIS_COORD(raw_dot[2]);
|
||||
DrawCenteredRectangle(dc, VIS_BITMAP_SIZE / 2, line_y, VIS_BITMAP_SIZE, LINE_HEIGHT);
|
||||
|
||||
// adjusted forward/background line
|
||||
if (adj_dot[2] != 0.0)
|
||||
{
|
||||
dc.SetPen(*wxRED_PEN);
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
line_y = VIS_COORD(adj_dot[2]);
|
||||
DrawCenteredRectangle(dc, VIS_BITMAP_SIZE / 2, line_y, VIS_BITMAP_SIZE, LINE_HEIGHT);
|
||||
}
|
||||
|
||||
#define DEADZONE_RECT_SIZE 32
|
||||
|
||||
// empty deadzone square
|
||||
dc.SetBrush(*wxWHITE_BRUSH);
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
DrawCenteredRectangle(dc, VIS_BITMAP_SIZE / 2, VIS_BITMAP_SIZE / 2, DEADZONE_RECT_SIZE, DEADZONE_RECT_SIZE);
|
||||
|
||||
// deadzone square
|
||||
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
|
||||
int dz_size = (deadzone * DEADZONE_RECT_SIZE);
|
||||
DrawCenteredRectangle(dc, VIS_BITMAP_SIZE / 2, VIS_BITMAP_SIZE / 2, dz_size, dz_size);
|
||||
|
||||
// raw dot
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
dc.SetBrush(*wxGREY_BRUSH);
|
||||
DrawCoordinate(dc, raw_dot[1], raw_dot[0]);
|
||||
|
||||
// adjusted dot
|
||||
if (adj_dot[1] != 0 && adj_dot[0] != 0)
|
||||
{
|
||||
dc.SetPen(*wxRED_PEN);
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
DrawCoordinate(dc, adj_dot[1], adj_dot[0]);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case GROUP_TYPE_BUTTONS :
|
||||
{
|
||||
const unsigned int button_count = ((unsigned int)g->control_group->controls.size());
|
||||
|
||||
// draw the shit
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
|
||||
unsigned int * const bitmasks = new unsigned int[ button_count ];
|
||||
for (unsigned int n = 0; n<button_count; ++n)
|
||||
bitmasks[n] = (1 << n);
|
||||
|
||||
unsigned int buttons = 0;
|
||||
((ControllerEmu::Buttons*)g->control_group)->GetState(&buttons, bitmasks);
|
||||
|
||||
for (unsigned int n = 0; n<button_count; ++n)
|
||||
{
|
||||
if (buttons & bitmasks[n])
|
||||
{
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char amt = 255 - g->control_group->controls[n]->control_ref->State() * 128;
|
||||
dc.SetBrush(wxBrush(wxColour(amt, amt, amt)));
|
||||
}
|
||||
dc.DrawRectangle(n * 12, 0, 14, 12);
|
||||
|
||||
// text
|
||||
const std::string name = g->control_group->controls[n]->name;
|
||||
// bit of hax so ZL, ZR show up as L, R
|
||||
dc.DrawText(StrToWxStr(std::string(1, (name[1] && name[1] < 'a') ? name[1] : name[0])), n*12 + 2, 1);
|
||||
}
|
||||
|
||||
delete[] bitmasks;
|
||||
|
||||
}
|
||||
break;
|
||||
case GROUP_TYPE_TRIGGERS :
|
||||
{
|
||||
const unsigned int trigger_count = ((unsigned int)(g->control_group->controls.size()));
|
||||
|
||||
// draw the shit
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
ControlState deadzone = g->control_group->settings[0]->value;
|
||||
|
||||
double* const trigs = new double[trigger_count];
|
||||
((ControllerEmu::Triggers*)g->control_group)->GetState(trigs);
|
||||
|
||||
for (unsigned int n = 0; n < trigger_count; ++n)
|
||||
{
|
||||
ControlState trig_r = g->control_group->controls[n]->control_ref->State();
|
||||
|
||||
// outline
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
dc.SetBrush(*wxWHITE_BRUSH);
|
||||
dc.DrawRectangle(0, n*12, 64, 14);
|
||||
|
||||
// raw
|
||||
dc.SetBrush(*wxGREY_BRUSH);
|
||||
dc.DrawRectangle(0, n*12, trig_r*64, 14);
|
||||
|
||||
// deadzone affected
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
dc.DrawRectangle(0, n*12, trigs[n]*64, 14);
|
||||
|
||||
// text
|
||||
dc.DrawText(StrToWxStr(g->control_group->controls[n]->name), 3, n*12 + 1);
|
||||
}
|
||||
|
||||
delete[] trigs;
|
||||
|
||||
// deadzone box
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||
dc.DrawRectangle(0, 0, deadzone*64, trigger_count*14);
|
||||
|
||||
}
|
||||
break;
|
||||
case GROUP_TYPE_MIXED_TRIGGERS :
|
||||
{
|
||||
const unsigned int trigger_count = ((unsigned int)(g->control_group->controls.size() / 2));
|
||||
|
||||
// draw the shit
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
ControlState thresh = g->control_group->settings[0]->value;
|
||||
|
||||
for (unsigned int n = 0; n < trigger_count; ++n)
|
||||
{
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
ControlState trig_d = g->control_group->controls[n]->control_ref->State();
|
||||
|
||||
ControlState trig_a = trig_d > thresh ? 1
|
||||
: g->control_group->controls[n+trigger_count]->control_ref->State();
|
||||
|
||||
dc.DrawRectangle(0, n*12, 64+20, 14);
|
||||
if (trig_d <= thresh)
|
||||
dc.SetBrush(*wxWHITE_BRUSH);
|
||||
dc.DrawRectangle(trig_a*64, n*12, 64+20, 14);
|
||||
dc.DrawRectangle(64, n*12, 32, 14);
|
||||
|
||||
// text
|
||||
dc.DrawText(StrToWxStr(g->control_group->controls[n+trigger_count]->name), 3, n*12 + 1);
|
||||
dc.DrawText(StrToWxStr(std::string(1, g->control_group->controls[n]->name[0])), 64 + 3, n*12 + 1);
|
||||
}
|
||||
|
||||
// threshold box
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||
dc.DrawRectangle(thresh*64, 0, 128, trigger_count*14);
|
||||
|
||||
}
|
||||
break;
|
||||
case GROUP_TYPE_SLIDER:
|
||||
{
|
||||
const ControlState deadzone = g->control_group->settings[0]->value;
|
||||
|
||||
ControlState state = g->control_group->controls[1]->control_ref->State() - g->control_group->controls[0]->control_ref->State();
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
dc.SetBrush(*wxGREY_BRUSH);
|
||||
dc.DrawRectangle(31 + state * 30, 0, 2, 14);
|
||||
|
||||
double adj_state;
|
||||
((ControllerEmu::Slider*)g->control_group)->GetState(&adj_state);
|
||||
if (state)
|
||||
{
|
||||
dc.SetPen(*wxRED_PEN);
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
dc.DrawRectangle(31 + adj_state * 30, 0, 2, 14);
|
||||
}
|
||||
|
||||
// deadzone box
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||
dc.DrawRectangle(32 - deadzone * 32, 0, deadzone * 64, 14);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InputConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event))
|
||||
{
|
||||
wxFont small_font(6, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
|
||||
|
@ -59,335 +413,7 @@ void InputConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event))
|
|||
if (64 == bitmap.GetHeight())
|
||||
dc.DrawText(StrToWxStr(g->control_group->name).Upper(), 4, 2);
|
||||
|
||||
switch (g->control_group->type)
|
||||
{
|
||||
case GROUP_TYPE_TILT :
|
||||
case GROUP_TYPE_STICK :
|
||||
case GROUP_TYPE_CURSOR :
|
||||
{
|
||||
// this is starting to be a mess combining all these in one case
|
||||
|
||||
float x = 0, y = 0, z = 0;
|
||||
float xx, yy;
|
||||
|
||||
switch (g->control_group->type)
|
||||
{
|
||||
case GROUP_TYPE_STICK :
|
||||
((ControllerEmu::AnalogStick*)g->control_group)->GetState(&x, &y, 32.0, 32-1.5);
|
||||
break;
|
||||
case GROUP_TYPE_TILT :
|
||||
((ControllerEmu::Tilt*)g->control_group)->GetState(&x, &y, 32.0, 32-1.5);
|
||||
break;
|
||||
case GROUP_TYPE_CURSOR :
|
||||
((ControllerEmu::Cursor*)g->control_group)->GetState(&x, &y, &z);
|
||||
x *= (32-1.5); x+= 32;
|
||||
y *= (32-1.5); y+= 32;
|
||||
break;
|
||||
}
|
||||
|
||||
xx = g->control_group->controls[3]->control_ref->State();
|
||||
xx -= g->control_group->controls[2]->control_ref->State();
|
||||
yy = g->control_group->controls[1]->control_ref->State();
|
||||
yy -= g->control_group->controls[0]->control_ref->State();
|
||||
xx *= 32 - 1; xx += 32;
|
||||
yy *= 32 - 1; yy += 32;
|
||||
|
||||
// draw the shit
|
||||
|
||||
// ir cursor forward movement
|
||||
if (GROUP_TYPE_CURSOR == g->control_group->type)
|
||||
{
|
||||
if (z)
|
||||
{
|
||||
dc.SetPen(*wxRED_PEN);
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
}
|
||||
else
|
||||
{
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
dc.SetBrush(*wxGREY_BRUSH);
|
||||
}
|
||||
dc.DrawRectangle(0, 31 - z*31, 64, 2);
|
||||
}
|
||||
|
||||
// octagon for visual aid for diagonal adjustment
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
dc.SetBrush(*wxWHITE_BRUSH);
|
||||
if (GROUP_TYPE_STICK == g->control_group->type)
|
||||
{
|
||||
// outline and fill colors
|
||||
wxBrush LightGrayBrush("#dddddd");
|
||||
wxPen LightGrayPen("#bfbfbf");
|
||||
dc.SetBrush(LightGrayBrush);
|
||||
dc.SetPen(LightGrayPen);
|
||||
|
||||
// polygon offset
|
||||
float max
|
||||
, diagonal
|
||||
, box = 64
|
||||
, d_of = box / 256.0
|
||||
, x_of = box / 2.0;
|
||||
|
||||
if (g->control_group->name == "Main Stick")
|
||||
{
|
||||
max = (87.0f / 127.0f) * 100;
|
||||
diagonal = (55.0f / 127.0f) * 100.0;
|
||||
}
|
||||
else if (g->control_group->name == "C-Stick")
|
||||
{
|
||||
max = (74.0f / 127.0f) * 100;
|
||||
diagonal = (46.0f / 127.0f) * 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
max = (82.0f / 127.0f) * 100;
|
||||
diagonal = (58.0f / 127.0f) * 100;
|
||||
}
|
||||
|
||||
// polygon corners
|
||||
wxPoint Points[8];
|
||||
Points[0].x = (int)(0.0 * d_of + x_of); Points[0].y = (int)(max * d_of + x_of);
|
||||
Points[1].x = (int)(diagonal * d_of + x_of); Points[1].y = (int)(diagonal * d_of + x_of);
|
||||
Points[2].x = (int)(max * d_of + x_of); Points[2].y = (int)(0.0 * d_of + x_of);
|
||||
Points[3].x = (int)(diagonal * d_of + x_of); Points[3].y = (int)(-diagonal * d_of + x_of);
|
||||
Points[4].x = (int)(0.0 * d_of + x_of); Points[4].y = (int)(-max * d_of + x_of);
|
||||
Points[5].x = (int)(-diagonal * d_of + x_of); Points[5].y = (int)(-diagonal * d_of + x_of);
|
||||
Points[6].x = (int)(-max * d_of + x_of); Points[6].y = (int)(0.0 * d_of + x_of);
|
||||
Points[7].x = (int)(-diagonal * d_of + x_of); Points[7].y = (int)(diagonal * d_of + x_of);
|
||||
|
||||
// draw polygon
|
||||
dc.DrawPolygon(8, Points);
|
||||
}
|
||||
else
|
||||
{
|
||||
dc.DrawRectangle(16, 16, 32, 32);
|
||||
}
|
||||
|
||||
if (GROUP_TYPE_CURSOR != g->control_group->type)
|
||||
{
|
||||
// deadzone circle
|
||||
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
|
||||
dc.DrawCircle(32, 32, g->control_group->settings[SETTING_DEADZONE]->value * 32);
|
||||
}
|
||||
|
||||
// raw dot
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
dc.SetBrush(*wxGREY_BRUSH);
|
||||
// i like the dot better than the cross i think
|
||||
dc.DrawRectangle(xx - 2, yy - 2, 4, 4);
|
||||
//dc.DrawRectangle(xx-1, 64-yy-4, 2, 8);
|
||||
//dc.DrawRectangle(xx-4, 64-yy-1, 8, 2);
|
||||
|
||||
// adjusted dot
|
||||
if (x!=32 || y!=32)
|
||||
{
|
||||
dc.SetPen(*wxRED_PEN);
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
dc.DrawRectangle(x-2, 64-y-2, 4, 4);
|
||||
// i like the dot better than the cross i think
|
||||
//dc.DrawRectangle(x-1, 64-y-4, 2, 8);
|
||||
//dc.DrawRectangle(x-4, 64-y-1, 8, 2);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case GROUP_TYPE_FORCE :
|
||||
{
|
||||
float raw_dot[3];
|
||||
float adj_dot[3];
|
||||
const float deadzone = 32 * g->control_group->settings[0]->value;
|
||||
|
||||
// adjusted
|
||||
((ControllerEmu::Force*)g->control_group)->GetState(adj_dot, 32.0, 32-1.5);
|
||||
|
||||
// raw
|
||||
for (unsigned int i=0; i<3; ++i)
|
||||
{
|
||||
raw_dot[i] = g->control_group->controls[i*2 + 1]->control_ref->State()
|
||||
- g->control_group->controls[i*2]->control_ref->State();
|
||||
raw_dot[i] *= 32 - 1; raw_dot[i] += 32;
|
||||
}
|
||||
|
||||
// deadzone rect for forward/backward visual
|
||||
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
dc.DrawRectangle(0, 32 - deadzone, 64, deadzone * 2);
|
||||
|
||||
// raw forward/background line
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
dc.SetBrush(*wxGREY_BRUSH);
|
||||
dc.DrawRectangle(0, raw_dot[2] - 1, 64, 2);
|
||||
|
||||
// adjusted forward/background line
|
||||
if (adj_dot[2]!=32)
|
||||
{
|
||||
dc.SetPen(*wxRED_PEN);
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
dc.DrawRectangle(0, adj_dot[2] - 1, 64, 2);
|
||||
}
|
||||
|
||||
// a rectangle, for looks i guess
|
||||
dc.SetBrush(*wxWHITE_BRUSH);
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
dc.DrawRectangle(16, 16, 32, 32);
|
||||
|
||||
// deadzone square
|
||||
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
|
||||
dc.DrawRectangle(32 - deadzone, 32 - deadzone, deadzone * 2, deadzone * 2);
|
||||
|
||||
// raw dot
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
dc.SetBrush(*wxGREY_BRUSH);
|
||||
dc.DrawRectangle(raw_dot[1] - 2, raw_dot[0] - 2, 4, 4);
|
||||
|
||||
// adjusted dot
|
||||
if (adj_dot[1]!=32 || adj_dot[0]!=32)
|
||||
{
|
||||
dc.SetPen(*wxRED_PEN);
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
dc.DrawRectangle(adj_dot[1]-2, adj_dot[0]-2, 4, 4);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case GROUP_TYPE_BUTTONS :
|
||||
{
|
||||
const unsigned int button_count = ((unsigned int)g->control_group->controls.size());
|
||||
|
||||
// draw the shit
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
|
||||
unsigned int * const bitmasks = new unsigned int[ button_count ];
|
||||
for (unsigned int n = 0; n<button_count; ++n)
|
||||
bitmasks[n] = (1 << n);
|
||||
|
||||
unsigned int buttons = 0;
|
||||
((ControllerEmu::Buttons*)g->control_group)->GetState(&buttons, bitmasks);
|
||||
|
||||
for (unsigned int n = 0; n<button_count; ++n)
|
||||
{
|
||||
if (buttons & bitmasks[n])
|
||||
{
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char amt = 255 - g->control_group->controls[n]->control_ref->State() * 128;
|
||||
dc.SetBrush(wxBrush(wxColour(amt, amt, amt)));
|
||||
}
|
||||
dc.DrawRectangle(n * 12, 0, 14, 12);
|
||||
|
||||
// text
|
||||
const std::string name = g->control_group->controls[n]->name;
|
||||
// bit of hax so ZL, ZR show up as L, R
|
||||
dc.DrawText(StrToWxStr(std::string(1, (name[1] && name[1] < 'a') ? name[1] : name[0])), n*12 + 2, 1);
|
||||
}
|
||||
|
||||
delete[] bitmasks;
|
||||
|
||||
}
|
||||
break;
|
||||
case GROUP_TYPE_TRIGGERS :
|
||||
{
|
||||
const unsigned int trigger_count = ((unsigned int)(g->control_group->controls.size()));
|
||||
|
||||
// draw the shit
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
ControlState deadzone = g->control_group->settings[0]->value;
|
||||
|
||||
unsigned int* const trigs = new unsigned int[trigger_count];
|
||||
((ControllerEmu::Triggers*)g->control_group)->GetState(trigs, 64);
|
||||
|
||||
for (unsigned int n = 0; n < trigger_count; ++n)
|
||||
{
|
||||
ControlState trig_r = g->control_group->controls[n]->control_ref->State();
|
||||
|
||||
// outline
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
dc.SetBrush(*wxWHITE_BRUSH);
|
||||
dc.DrawRectangle(0, n*12, 64, 14);
|
||||
|
||||
// raw
|
||||
dc.SetBrush(*wxGREY_BRUSH);
|
||||
dc.DrawRectangle(0, n*12, trig_r*64, 14);
|
||||
|
||||
// deadzone affected
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
dc.DrawRectangle(0, n*12, trigs[n], 14);
|
||||
|
||||
// text
|
||||
dc.DrawText(StrToWxStr(g->control_group->controls[n]->name), 3, n*12 + 1);
|
||||
}
|
||||
|
||||
delete[] trigs;
|
||||
|
||||
// deadzone box
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||
dc.DrawRectangle(0, 0, deadzone*64, trigger_count*14);
|
||||
|
||||
}
|
||||
break;
|
||||
case GROUP_TYPE_MIXED_TRIGGERS :
|
||||
{
|
||||
const unsigned int trigger_count = ((unsigned int)(g->control_group->controls.size() / 2));
|
||||
|
||||
// draw the shit
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
ControlState thresh = g->control_group->settings[0]->value;
|
||||
|
||||
for (unsigned int n = 0; n < trigger_count; ++n)
|
||||
{
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
ControlState trig_d = g->control_group->controls[n]->control_ref->State();
|
||||
|
||||
ControlState trig_a = trig_d > thresh ? 1
|
||||
: g->control_group->controls[n+trigger_count]->control_ref->State();
|
||||
|
||||
dc.DrawRectangle(0, n*12, 64+20, 14);
|
||||
if (trig_d <= thresh)
|
||||
dc.SetBrush(*wxWHITE_BRUSH);
|
||||
dc.DrawRectangle(trig_a*64, n*12, 64+20, 14);
|
||||
dc.DrawRectangle(64, n*12, 32, 14);
|
||||
|
||||
// text
|
||||
dc.DrawText(StrToWxStr(g->control_group->controls[n+trigger_count]->name), 3, n*12 + 1);
|
||||
dc.DrawText(StrToWxStr(std::string(1, g->control_group->controls[n]->name[0])), 64 + 3, n*12 + 1);
|
||||
}
|
||||
|
||||
// threshold box
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||
dc.DrawRectangle(thresh*64, 0, 128, trigger_count*14);
|
||||
|
||||
}
|
||||
break;
|
||||
case GROUP_TYPE_SLIDER:
|
||||
{
|
||||
const ControlState deadzone = g->control_group->settings[0]->value;
|
||||
|
||||
ControlState state = g->control_group->controls[1]->control_ref->State() - g->control_group->controls[0]->control_ref->State();
|
||||
dc.SetPen(*wxGREY_PEN);
|
||||
dc.SetBrush(*wxGREY_BRUSH);
|
||||
dc.DrawRectangle(31 + state * 30, 0, 2, 14);
|
||||
|
||||
((ControllerEmu::Slider*)g->control_group)->GetState(&state, 1);
|
||||
if (state)
|
||||
{
|
||||
dc.SetPen(*wxRED_PEN);
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
dc.DrawRectangle(31 + state * 30, 0, 2, 14);
|
||||
}
|
||||
|
||||
// deadzone box
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||
dc.DrawRectangle(32 - deadzone * 32, 0, deadzone * 64, 14);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
DrawControlGroupBox(dc, g);
|
||||
|
||||
// box outline
|
||||
// Windows XP color
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
#include <string>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/defs.h>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/translation.h>
|
||||
|
||||
#include "DolphinWX/UDPConfigDiag.h"
|
||||
#include "DolphinWX/WxUtils.h"
|
||||
#include "InputCommon/UDPWrapper.h"
|
||||
|
||||
class wxWindow;
|
||||
|
||||
UDPConfigDiag::UDPConfigDiag(wxWindow * const parent, UDPWrapper * _wrp) :
|
||||
wxDialog(parent, -1, _("UDP Wiimote")),
|
||||
wrp(_wrp)
|
||||
{
|
||||
wxBoxSizer *const outer_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer *const sizer1 = new wxBoxSizer(wxVERTICAL);
|
||||
wxStaticBoxSizer *const sizer2 = new wxStaticBoxSizer(wxVERTICAL, this, _("Update"));
|
||||
|
||||
outer_sizer->Add(sizer1, 0, wxTOP | wxLEFT | wxRIGHT | wxEXPAND, 5);
|
||||
outer_sizer->Add(sizer2, 1, wxLEFT | wxRIGHT | wxEXPAND, 10);
|
||||
|
||||
enable = new wxCheckBox(this, wxID_ANY, _("Enable"));
|
||||
butt = new wxCheckBox(this, wxID_ANY, _("Buttons"));
|
||||
accel = new wxCheckBox(this, wxID_ANY, _("Acceleration"));
|
||||
point = new wxCheckBox(this, wxID_ANY, _("IR Pointer"));
|
||||
nun = new wxCheckBox(this, wxID_ANY, _("Nunchuk"));
|
||||
nunaccel = new wxCheckBox(this, wxID_ANY, _("Nunchuk Acceleration"));
|
||||
|
||||
wxBoxSizer *const port_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
port_sizer->Add(new wxStaticText(this, wxID_ANY, _("UDP Port:")), 0, wxALIGN_CENTER);
|
||||
port_tbox = new wxTextCtrl(this, wxID_ANY, StrToWxStr(wrp->port));
|
||||
port_sizer->Add(port_tbox, 1, wxLEFT | wxEXPAND, 5);
|
||||
|
||||
enable->Bind(wxEVT_CHECKBOX, &UDPConfigDiag::ChangeState, this);
|
||||
butt->Bind(wxEVT_CHECKBOX, &UDPConfigDiag::ChangeUpdateFlags, this);
|
||||
accel->Bind(wxEVT_CHECKBOX, &UDPConfigDiag::ChangeUpdateFlags, this);
|
||||
point->Bind(wxEVT_CHECKBOX, &UDPConfigDiag::ChangeUpdateFlags, this);
|
||||
nun->Bind(wxEVT_CHECKBOX, &UDPConfigDiag::ChangeUpdateFlags, this);
|
||||
nunaccel->Bind(wxEVT_CHECKBOX, &UDPConfigDiag::ChangeUpdateFlags, this);
|
||||
port_tbox->Bind(wxEVT_TEXT, &UDPConfigDiag::ChangeState, this);
|
||||
|
||||
enable->SetValue(wrp->udpEn);
|
||||
butt->SetValue(wrp->updButt);
|
||||
accel->SetValue(wrp->updAccel);
|
||||
point->SetValue(wrp->updIR);
|
||||
nun->SetValue(wrp->updNun);
|
||||
nunaccel->SetValue(wrp->updNunAccel);
|
||||
|
||||
sizer1->Add(enable, 1, wxALL | wxEXPAND, 5);
|
||||
sizer1->Add(port_sizer, 1, wxBOTTOM | wxLEFT| wxRIGHT | wxEXPAND, 5);
|
||||
|
||||
sizer2->Add(butt, 1, wxALL | wxEXPAND, 5);
|
||||
sizer2->Add(accel, 1, wxALL | wxEXPAND, 5);
|
||||
sizer2->Add(point, 1, wxALL | wxEXPAND, 5);
|
||||
sizer2->Add(nun, 1, wxALL | wxEXPAND, 5);
|
||||
sizer2->Add(nunaccel, 1, wxALL | wxEXPAND, 5);
|
||||
|
||||
outer_sizer->Add(CreateButtonSizer(wxOK), 0, wxALL | wxALIGN_RIGHT, 5);
|
||||
|
||||
SetSizerAndFit(outer_sizer);
|
||||
Center();
|
||||
SetFocus();
|
||||
}
|
||||
|
||||
void UDPConfigDiag::ChangeUpdateFlags(wxCommandEvent & WXUNUSED(event))
|
||||
{
|
||||
wrp->updAccel=accel->GetValue();
|
||||
wrp->updButt=butt->GetValue();
|
||||
wrp->updIR=point->GetValue();
|
||||
wrp->updNun=nun->GetValue();
|
||||
wrp->updNunAccel=nunaccel->GetValue();
|
||||
}
|
||||
|
||||
void UDPConfigDiag::ChangeState(wxCommandEvent & WXUNUSED(event))
|
||||
{
|
||||
wrp->udpEn = enable->GetValue();
|
||||
wrp->port = WxStrToStr(port_tbox->GetValue());
|
||||
wrp->Refresh();
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <wx/dialog.h>
|
||||
|
||||
class UDPWrapper;
|
||||
class wxCheckBox;
|
||||
class wxCommandEvent;
|
||||
class wxTextCtrl;
|
||||
class wxWindow;
|
||||
|
||||
class UDPConfigDiag : public wxDialog
|
||||
{
|
||||
public:
|
||||
UDPConfigDiag(wxWindow * const parent, UDPWrapper * _wrp);
|
||||
private:
|
||||
UDPWrapper * wrp;
|
||||
void ChangeUpdateFlags(wxCommandEvent & event);
|
||||
void ChangeState(wxCommandEvent & event);
|
||||
void OKPressed(wxCommandEvent & event);
|
||||
wxCheckBox * enable;
|
||||
wxCheckBox * butt;
|
||||
wxCheckBox * accel;
|
||||
wxCheckBox * point;
|
||||
wxCheckBox * nun;
|
||||
wxCheckBox * nunaccel;
|
||||
wxTextCtrl * port_tbox;
|
||||
};
|
|
@ -1,7 +1,5 @@
|
|||
set(SRCS ControllerEmu.cpp
|
||||
InputConfig.cpp
|
||||
UDPWiimote.cpp
|
||||
UDPWrapper.cpp
|
||||
ControllerInterface/ControllerInterface.cpp
|
||||
ControllerInterface/Device.cpp
|
||||
ControllerInterface/ExpressionParser.cpp)
|
||||
|
|
|
@ -4,10 +4,6 @@
|
|||
|
||||
#include "InputCommon/ControllerEmu.h"
|
||||
|
||||
#if defined(HAVE_X11) && HAVE_X11
|
||||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
void ControllerEmu::UpdateReferences(ControllerInterface& devi)
|
||||
{
|
||||
for (auto& ctrlGroup : groups)
|
||||
|
@ -47,6 +43,8 @@ void ControllerEmu::ControlGroup::LoadConfig(IniFile::Section *sec, const std::s
|
|||
// settings
|
||||
for (auto& s : settings)
|
||||
{
|
||||
if (s->is_virtual)
|
||||
continue;
|
||||
sec->Get(group + s->name, &s->value, s->default_value * 100);
|
||||
s->value /= 100;
|
||||
}
|
||||
|
@ -103,7 +101,11 @@ void ControllerEmu::ControlGroup::SaveConfig(IniFile::Section *sec, const std::s
|
|||
std::string group(base + name); group += "/";
|
||||
|
||||
for (auto& s : settings)
|
||||
{
|
||||
if (s->is_virtual)
|
||||
continue;
|
||||
sec->Set(group + s->name, s->value*100.0f, s->default_value*100.0f);
|
||||
}
|
||||
|
||||
for (auto& c : controls)
|
||||
{
|
||||
|
@ -144,8 +146,6 @@ ControllerEmu::AnalogStick::AnalogStick(const char* const _name) : ControlGroup(
|
|||
|
||||
settings.emplace_back(new Setting(_trans("Radius"), 0.7f, 0, 100));
|
||||
settings.emplace_back(new Setting(_trans("Dead Zone"), 0, 0, 50));
|
||||
settings.emplace_back(new Setting(_trans("Square Stick"), 0));
|
||||
|
||||
}
|
||||
|
||||
ControllerEmu::Buttons::Buttons(const std::string& _name) : ControlGroup(_name, GROUP_TYPE_BUTTONS)
|
||||
|
@ -185,8 +185,7 @@ ControllerEmu::Force::Force(const std::string& _name) : ControlGroup(_name, GROU
|
|||
settings.emplace_back(new Setting(_trans("Dead Zone"), 0, 0, 50));
|
||||
}
|
||||
|
||||
ControllerEmu::Tilt::Tilt(const std::string& _name)
|
||||
: ControlGroup(_name, GROUP_TYPE_TILT)
|
||||
ControllerEmu::Tilt::Tilt(const std::string& _name) : ControlGroup(_name, GROUP_TYPE_TILT)
|
||||
{
|
||||
memset(m_tilt, 0, sizeof(m_tilt));
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "Common/IniFile.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "InputCommon/GCPadStatus.h"
|
||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||
|
||||
|
@ -30,7 +31,6 @@ enum
|
|||
GROUP_TYPE_TILT,
|
||||
GROUP_TYPE_CURSOR,
|
||||
GROUP_TYPE_TRIGGERS,
|
||||
GROUP_TYPE_UDPWII,
|
||||
GROUP_TYPE_SLIDER,
|
||||
};
|
||||
|
||||
|
@ -38,7 +38,6 @@ enum
|
|||
{
|
||||
SETTING_RADIUS,
|
||||
SETTING_DEADZONE,
|
||||
SETTING_SQUARE,
|
||||
};
|
||||
|
||||
const char* const named_directions[] =
|
||||
|
@ -96,12 +95,43 @@ public:
|
|||
, value(def_value)
|
||||
, default_value(def_value)
|
||||
, low(_low)
|
||||
, high(_high){}
|
||||
, high(_high)
|
||||
, is_virtual(false) {}
|
||||
|
||||
const std::string name;
|
||||
ControlState value;
|
||||
const ControlState default_value;
|
||||
const unsigned int low, high;
|
||||
bool is_virtual;
|
||||
|
||||
virtual void SetValue(ControlState new_value)
|
||||
{
|
||||
value = new_value;
|
||||
}
|
||||
|
||||
virtual ControlState GetValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
class BackgroundInputSetting : public Setting
|
||||
{
|
||||
public:
|
||||
BackgroundInputSetting(const std::string &_name) : Setting(_name, false)
|
||||
{
|
||||
is_virtual = true;
|
||||
}
|
||||
|
||||
void SetValue(ControlState new_value) override
|
||||
{
|
||||
SConfig::GetInstance().m_BackgroundInput = new_value;
|
||||
}
|
||||
|
||||
ControlState GetValue() override
|
||||
{
|
||||
return SConfig::GetInstance().m_BackgroundInput;
|
||||
}
|
||||
};
|
||||
|
||||
ControlGroup(const std::string& _name, const unsigned int _type = GROUP_TYPE_OTHER) : name(_name), type(_type) {}
|
||||
|
@ -121,66 +151,41 @@ public:
|
|||
class AnalogStick : public ControlGroup
|
||||
{
|
||||
public:
|
||||
AnalogStick(const char* const _name);
|
||||
|
||||
template <typename C>
|
||||
void GetState(C* const x, C* const y, const unsigned int base, const unsigned int range)
|
||||
void GetState(double* const x, double* const y)
|
||||
{
|
||||
// this is all a mess
|
||||
|
||||
ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State();
|
||||
ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State();
|
||||
|
||||
ControlState radius = settings[SETTING_RADIUS]->value;
|
||||
ControlState deadzone = settings[SETTING_DEADZONE]->value;
|
||||
ControlState square = settings[SETTING_SQUARE]->value;
|
||||
ControlState m = controls[4]->control_ref->State();
|
||||
|
||||
// modifier code
|
||||
ControlState ang = atan2(yy, xx);
|
||||
ControlState ang_sin = sin(ang);
|
||||
ControlState ang_cos = cos(ang);
|
||||
|
||||
ControlState dist = sqrt(xx*xx + yy*yy);
|
||||
|
||||
// dead zone code
|
||||
dist = std::max(0.0f, dist - deadzone);
|
||||
dist /= (1 - deadzone);
|
||||
|
||||
// radius
|
||||
dist *= radius;
|
||||
|
||||
// The modifier halves the distance by 50%, which is useful
|
||||
// for keyboard controls.
|
||||
if (m)
|
||||
{
|
||||
yy = (fabsf(yy)>deadzone) * sign(yy) * (m + deadzone/2);
|
||||
xx = (fabsf(xx)>deadzone) * sign(xx) * (m + deadzone/2);
|
||||
}
|
||||
dist *= 0.5;
|
||||
|
||||
// deadzone / square stick code
|
||||
if (radius != 1 || deadzone || square)
|
||||
{
|
||||
// this section might be all wrong, but its working good enough, I think
|
||||
yy = std::max(-1.0f, std::min(1.0f, ang_sin * dist));
|
||||
xx = std::max(-1.0f, std::min(1.0f, ang_cos * dist));
|
||||
|
||||
ControlState ang = atan2(yy, xx);
|
||||
ControlState ang_sin = sin(ang);
|
||||
ControlState ang_cos = cos(ang);
|
||||
|
||||
// the amt a full square stick would have at current angle
|
||||
ControlState square_full = std::min(ang_sin ? 1/fabsf(ang_sin) : 2, ang_cos ? 1/fabsf(ang_cos) : 2);
|
||||
|
||||
// the amt a full stick would have that was ( user setting squareness) at current angle
|
||||
// I think this is more like a pointed circle rather than a rounded square like it should be
|
||||
ControlState stick_full = (1 + (square_full - 1) * square);
|
||||
|
||||
ControlState dist = sqrt(xx*xx + yy*yy);
|
||||
|
||||
// dead zone code
|
||||
dist = std::max(0.0f, dist - deadzone * stick_full);
|
||||
dist /= (1 - deadzone);
|
||||
|
||||
// square stick code
|
||||
ControlState amt = dist / stick_full;
|
||||
dist -= ((square_full - 1) * amt * square);
|
||||
|
||||
// radius
|
||||
dist *= radius;
|
||||
|
||||
yy = std::max(-1.0f, std::min(1.0f, ang_sin * dist));
|
||||
xx = std::max(-1.0f, std::min(1.0f, ang_cos * dist));
|
||||
}
|
||||
|
||||
*y = C(yy * range + base);
|
||||
*x = C(xx * range + base);
|
||||
*y = yy;
|
||||
*x = xx;
|
||||
}
|
||||
|
||||
AnalogStick(const char* const _name);
|
||||
|
||||
};
|
||||
|
||||
class Buttons : public ControlGroup
|
||||
|
@ -205,64 +210,55 @@ public:
|
|||
class MixedTriggers : public ControlGroup
|
||||
{
|
||||
public:
|
||||
MixedTriggers(const std::string& _name);
|
||||
|
||||
template <typename C, typename S>
|
||||
void GetState(C* const digital, const C* bitmasks, S* analog, const unsigned int range)
|
||||
void GetState(u16 *const digital, const u16* bitmasks, double* analog)
|
||||
{
|
||||
const unsigned int trig_count = ((unsigned int) (controls.size() / 2));
|
||||
for (unsigned int i=0; i<trig_count; ++i,++bitmasks,++analog)
|
||||
{
|
||||
if (controls[i]->control_ref->State() > settings[0]->value) //threshold
|
||||
{
|
||||
*analog = range;
|
||||
*analog = 1.0;
|
||||
*digital |= *bitmasks;
|
||||
}
|
||||
else
|
||||
{
|
||||
*analog = S(controls[i+trig_count]->control_ref->State() * range);
|
||||
*analog = controls[i+trig_count]->control_ref->State();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MixedTriggers(const std::string& _name);
|
||||
|
||||
};
|
||||
|
||||
class Triggers : public ControlGroup
|
||||
{
|
||||
public:
|
||||
Triggers(const std::string& _name);
|
||||
|
||||
template <typename S>
|
||||
void GetState(S* analog, const unsigned int range)
|
||||
void GetState(double* analog)
|
||||
{
|
||||
const unsigned int trig_count = ((unsigned int) (controls.size()));
|
||||
const ControlState deadzone = settings[0]->value;
|
||||
for (unsigned int i=0; i<trig_count; ++i,++analog)
|
||||
*analog = S(std::max(controls[i]->control_ref->State() - deadzone, 0.0f) / (1 - deadzone) * range);
|
||||
*analog = std::max(controls[i]->control_ref->State() - deadzone, 0.0f) / (1 - deadzone);
|
||||
}
|
||||
|
||||
Triggers(const std::string& _name);
|
||||
|
||||
};
|
||||
|
||||
class Slider : public ControlGroup
|
||||
{
|
||||
public:
|
||||
Slider(const std::string& _name);
|
||||
|
||||
template <typename S>
|
||||
void GetState(S* const slider, const unsigned int range, const unsigned int base = 0)
|
||||
void GetState(double* const slider)
|
||||
{
|
||||
const float deadzone = settings[0]->value;
|
||||
const float state = controls[1]->control_ref->State() - controls[0]->control_ref->State();
|
||||
|
||||
if (fabsf(state) > deadzone)
|
||||
*slider = (S)((state - (deadzone * sign(state))) / (1 - deadzone) * range + base);
|
||||
*slider = (state - (deadzone * sign(state))) / (1 - deadzone);
|
||||
else
|
||||
*slider = 0;
|
||||
}
|
||||
|
||||
Slider(const std::string& _name);
|
||||
|
||||
};
|
||||
|
||||
class Force : public ControlGroup
|
||||
|
@ -270,8 +266,7 @@ public:
|
|||
public:
|
||||
Force(const std::string& _name);
|
||||
|
||||
template <typename C, typename R>
|
||||
void GetState(C* axis, const u8 base, const R range)
|
||||
void GetState(double* axis)
|
||||
{
|
||||
const float deadzone = settings[0]->value;
|
||||
for (unsigned int i=0; i<6; i+=2)
|
||||
|
@ -282,7 +277,7 @@ public:
|
|||
tmpf = ((state - (deadzone * sign(state))) / (1 - deadzone));
|
||||
|
||||
float &ax = m_swing[i >> 1];
|
||||
*axis++ = (C)((tmpf - ax) * range + base);
|
||||
*axis++ = (tmpf - ax);
|
||||
ax = tmpf;
|
||||
}
|
||||
}
|
||||
|
@ -296,8 +291,7 @@ public:
|
|||
public:
|
||||
Tilt(const std::string& _name);
|
||||
|
||||
template <typename C, typename R>
|
||||
void GetState(C* const x, C* const y, const unsigned int base, const R range, const bool step = true)
|
||||
void GetState(double* const x, double* const y, const bool step = true)
|
||||
{
|
||||
// this is all a mess
|
||||
|
||||
|
@ -309,42 +303,35 @@ public:
|
|||
auto const angle = settings[2]->value / 1.8f;
|
||||
ControlState m = controls[4]->control_ref->State();
|
||||
|
||||
// modifier code
|
||||
if (m)
|
||||
{
|
||||
yy = (fabsf(yy)>deadzone) * sign(yy) * (m + deadzone/2);
|
||||
xx = (fabsf(xx)>deadzone) * sign(xx) * (m + deadzone/2);
|
||||
}
|
||||
|
||||
// deadzone / circle stick code
|
||||
if (deadzone || circle)
|
||||
{
|
||||
// this section might be all wrong, but its working good enough, I think
|
||||
// this section might be all wrong, but its working good enough, I think
|
||||
|
||||
ControlState ang = atan2(yy, xx);
|
||||
ControlState ang_sin = sin(ang);
|
||||
ControlState ang_cos = cos(ang);
|
||||
ControlState ang = atan2(yy, xx);
|
||||
ControlState ang_sin = sin(ang);
|
||||
ControlState ang_cos = cos(ang);
|
||||
|
||||
// the amt a full square stick would have at current angle
|
||||
ControlState square_full = std::min(ang_sin ? 1/fabsf(ang_sin) : 2, ang_cos ? 1/fabsf(ang_cos) : 2);
|
||||
// the amt a full square stick would have at current angle
|
||||
ControlState square_full = std::min(ang_sin ? 1/fabsf(ang_sin) : 2, ang_cos ? 1/fabsf(ang_cos) : 2);
|
||||
|
||||
// the amt a full stick would have that was (user setting circular) at current angle
|
||||
// I think this is more like a pointed circle rather than a rounded square like it should be
|
||||
ControlState stick_full = (square_full * (1 - circle)) + (circle);
|
||||
// the amt a full stick would have that was (user setting circular) at current angle
|
||||
// I think this is more like a pointed circle rather than a rounded square like it should be
|
||||
ControlState stick_full = (square_full * (1 - circle)) + (circle);
|
||||
|
||||
ControlState dist = sqrt(xx*xx + yy*yy);
|
||||
ControlState dist = sqrt(xx*xx + yy*yy);
|
||||
|
||||
// dead zone code
|
||||
dist = std::max(0.0f, dist - deadzone * stick_full);
|
||||
dist /= (1 - deadzone);
|
||||
// dead zone code
|
||||
dist = std::max(0.0f, dist - deadzone * stick_full);
|
||||
dist /= (1 - deadzone);
|
||||
|
||||
// circle stick code
|
||||
ControlState amt = dist / stick_full;
|
||||
dist += (square_full - 1) * amt * circle;
|
||||
// circle stick code
|
||||
ControlState amt = dist / stick_full;
|
||||
dist += (square_full - 1) * amt * circle;
|
||||
|
||||
yy = std::max(-1.0f, std::min(1.0f, ang_sin * dist));
|
||||
xx = std::max(-1.0f, std::min(1.0f, ang_cos * dist));
|
||||
}
|
||||
if (m)
|
||||
dist *= 0.5;
|
||||
|
||||
yy = std::max(-1.0f, std::min(1.0f, ang_sin * dist));
|
||||
xx = std::max(-1.0f, std::min(1.0f, ang_cos * dist));
|
||||
|
||||
// this is kinda silly here
|
||||
// gui being open will make this happen 2x as fast, o well
|
||||
|
@ -363,8 +350,8 @@ public:
|
|||
m_tilt[1] = std::max(m_tilt[1] - 0.1f, yy);
|
||||
}
|
||||
|
||||
*y = C(m_tilt[1] * angle * range + base);
|
||||
*x = C(m_tilt[0] * angle * range + base);
|
||||
*y = m_tilt[1] * angle;
|
||||
*x = m_tilt[0] * angle;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -376,8 +363,7 @@ public:
|
|||
public:
|
||||
Cursor(const std::string& _name);
|
||||
|
||||
template <typename C>
|
||||
void GetState(C* const x, C* const y, C* const z, const bool adjusted = false)
|
||||
void GetState(double* const x, double* const y, double* const z, const bool adjusted = false)
|
||||
{
|
||||
const float zz = controls[4]->control_ref->State() - controls[5]->control_ref->State();
|
||||
|
||||
|
@ -425,7 +411,7 @@ public:
|
|||
|
||||
~Extension() {}
|
||||
|
||||
void GetState(u8* const data, const bool focus = true);
|
||||
void GetState(u8* const data);
|
||||
|
||||
std::vector<std::unique_ptr<ControllerEmu>> attachments;
|
||||
|
||||
|
|
|
@ -5,6 +5,12 @@
|
|||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
// For InputGateOn()
|
||||
// This is a really bad layering violation, but it's the cleanest
|
||||
// place I could find to put it.
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Host.h"
|
||||
|
||||
#include "InputCommon/ControllerInterface/Device.h"
|
||||
|
||||
namespace ciface
|
||||
|
@ -74,6 +80,16 @@ void Device::ClearInputState()
|
|||
// kinda slow but, w/e, should only happen when user unplugs a device while playing
|
||||
}
|
||||
|
||||
bool Device::Control::InputGateOn()
|
||||
{
|
||||
if (SConfig::GetInstance().m_BackgroundInput)
|
||||
return true;
|
||||
else if (Host_RendererHasFocus())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// DeviceQualifier :: ToString
|
||||
//
|
||||
|
|
|
@ -42,6 +42,8 @@ public:
|
|||
virtual std::string GetName() const = 0;
|
||||
virtual ~Control() {}
|
||||
|
||||
bool InputGateOn();
|
||||
|
||||
virtual Input* ToInput() { return nullptr; }
|
||||
virtual Output* ToOutput() { return nullptr; }
|
||||
};
|
||||
|
@ -59,6 +61,16 @@ public:
|
|||
|
||||
virtual ControlState GetState() const = 0;
|
||||
|
||||
bool ShouldHaveInput();
|
||||
|
||||
ControlState GetGatedState()
|
||||
{
|
||||
if (InputGateOn())
|
||||
return GetState();
|
||||
else
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
Input* ToInput() override { return this; }
|
||||
};
|
||||
|
||||
|
@ -74,6 +86,12 @@ public:
|
|||
|
||||
virtual void SetState(ControlState state) = 0;
|
||||
|
||||
void SetGatedState(ControlState state)
|
||||
{
|
||||
if (InputGateOn())
|
||||
SetState(state);
|
||||
}
|
||||
|
||||
Output* ToOutput() override { return this; }
|
||||
};
|
||||
|
||||
|
|
|
@ -228,12 +228,12 @@ public:
|
|||
|
||||
virtual ControlState GetValue() override
|
||||
{
|
||||
return control->ToInput()->GetState();
|
||||
return control->ToInput()->GetGatedState();
|
||||
}
|
||||
|
||||
virtual void SetValue(ControlState value) override
|
||||
{
|
||||
control->ToOutput()->SetState(value);
|
||||
control->ToOutput()->SetGatedState(value);
|
||||
}
|
||||
|
||||
virtual int CountNumControls() override
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
|
@ -48,8 +48,6 @@
|
|||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UDPWiimote.cpp" />
|
||||
<ClCompile Include="UDPWrapper.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ControllerEmu.h" />
|
||||
|
@ -64,8 +62,6 @@
|
|||
<ClInclude Include="GCPadStatus.h" />
|
||||
<ClInclude Include="InputConfig.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="UDPWiimote.h" />
|
||||
<ClInclude Include="UDPWrapper.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="CMakeLists.txt" />
|
||||
|
@ -78,4 +74,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="ControllerInterface">
|
||||
|
@ -17,8 +17,6 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="ControllerEmu.cpp" />
|
||||
<ClCompile Include="InputConfig.cpp" />
|
||||
<ClCompile Include="UDPWiimote.cpp" />
|
||||
<ClCompile Include="UDPWrapper.cpp" />
|
||||
<ClCompile Include="ControllerInterface\DInput\DInput.cpp">
|
||||
<Filter>ControllerInterface\DInput</Filter>
|
||||
</ClCompile>
|
||||
|
@ -49,8 +47,6 @@
|
|||
<ClInclude Include="ControllerEmu.h" />
|
||||
<ClInclude Include="GCPadStatus.h" />
|
||||
<ClInclude Include="InputConfig.h" />
|
||||
<ClInclude Include="UDPWiimote.h" />
|
||||
<ClInclude Include="UDPWrapper.h" />
|
||||
<ClInclude Include="ControllerInterface\DInput\DInput.h">
|
||||
<Filter>ControllerInterface\DInput</Filter>
|
||||
</ClInclude>
|
||||
|
@ -80,4 +76,4 @@
|
|||
<ItemGroup>
|
||||
<Text Include="CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -1,439 +0,0 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "Common/Thread.h"
|
||||
#include "Common/Timer.h"
|
||||
|
||||
#include "InputCommon/UDPWiimote.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#define sock_t SOCKET
|
||||
#define ERRNO WSAGetLastError()
|
||||
#undef EWOULDBLOCK
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#define BAD_SOCK INVALID_SOCKET
|
||||
#define close(x) closesocket(x)
|
||||
#define cleanup do {noinst--; if (noinst==0) WSACleanup();} while (0)
|
||||
#define blockingoff(sock) ioctlsocket(sock, FIONBIO, &iMode)
|
||||
#define dataz char*
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment (lib, "Ws2_32.lib")
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#define BAD_SOCK -1
|
||||
#define ERRNO errno
|
||||
#define cleanup noinst--
|
||||
#define blockingoff(sock) fcntl(sock, F_SETFL, O_NONBLOCK)
|
||||
#define dataz void*
|
||||
#define sock_t int
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
struct UDPWiimote::_d
|
||||
{
|
||||
std::thread thread;
|
||||
std::list<sock_t> sockfds;
|
||||
std::mutex termLock, mutex, nameMutex;
|
||||
volatile bool exit;
|
||||
sock_t bipv4_fd, bipv6_fd;
|
||||
};
|
||||
|
||||
int UDPWiimote::noinst = 0;
|
||||
|
||||
UDPWiimote::UDPWiimote(const std::string& _port, const std::string& name, int _index) :
|
||||
port(_port), displayName(name), d(new _d),
|
||||
waX(0), waY(0), waZ(1), naX(0), naY(0), naZ(-1), nunX(0), nunY(0),
|
||||
pointerX(1001.0f / 2), pointerY(0), nunMask(0), wiimoteMask(0), index(_index), int_port(atoi(_port.c_str()))
|
||||
{
|
||||
|
||||
static bool sranded=false;
|
||||
if (!sranded)
|
||||
{
|
||||
srand((unsigned int)time(nullptr));
|
||||
sranded=true;
|
||||
}
|
||||
bcastMagic=rand() & 0xFFFF;
|
||||
|
||||
#ifdef _WIN32
|
||||
u_long iMode = 1;
|
||||
#endif
|
||||
struct addrinfo hints, *servinfo, *p;
|
||||
int rv;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (noinst==0)
|
||||
{
|
||||
WORD sockVersion;
|
||||
WSADATA wsaData;
|
||||
sockVersion = MAKEWORD(2, 2);
|
||||
WSAStartup(sockVersion, &wsaData);
|
||||
}
|
||||
#endif
|
||||
|
||||
noinst++;
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_flags = AI_PASSIVE; // use my IP
|
||||
|
||||
if (!int_port)
|
||||
{
|
||||
cleanup;
|
||||
err=-1;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((rv = getaddrinfo(nullptr, _port.c_str(), &hints, &servinfo)) != 0)
|
||||
{
|
||||
cleanup;
|
||||
err=-1;
|
||||
return;
|
||||
}
|
||||
|
||||
// loop through all the results and bind to everything we can
|
||||
for (p = servinfo; p != nullptr; p = p->ai_next)
|
||||
{
|
||||
sock_t sock;
|
||||
if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == BAD_SOCK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bind(sock, p->ai_addr, (int)p->ai_addrlen) == -1)
|
||||
{
|
||||
close(sock);
|
||||
continue;
|
||||
}
|
||||
d->sockfds.push_back(sock);
|
||||
}
|
||||
|
||||
if (d->sockfds.empty())
|
||||
{
|
||||
cleanup;
|
||||
err=-2;
|
||||
return;
|
||||
}
|
||||
|
||||
freeaddrinfo(servinfo);
|
||||
err=0;
|
||||
d->exit=false;
|
||||
initBroadcastIPv4();
|
||||
initBroadcastIPv6();
|
||||
|
||||
std::lock_guard<std::mutex> lk(d->termLock);
|
||||
d->thread = std::thread(std::mem_fn(&UDPWiimote::mainThread), this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void UDPWiimote::mainThread()
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(d->termLock);
|
||||
|
||||
Common::Timer time;
|
||||
fd_set fds;
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec=0;
|
||||
timeout.tv_usec=0;
|
||||
time.Update();
|
||||
do
|
||||
{
|
||||
int maxfd=0;
|
||||
FD_ZERO(&fds);
|
||||
for (auto& fd : d->sockfds)
|
||||
{
|
||||
FD_SET(fd,&fds);
|
||||
#ifndef _WIN32
|
||||
if (fd>=maxfd)
|
||||
maxfd=(fd)+1;
|
||||
#endif
|
||||
}
|
||||
|
||||
u64 tleft=timeout.tv_sec*1000+timeout.tv_usec/1000;
|
||||
u64 telapsed=time.GetTimeDifference();
|
||||
time.Update();
|
||||
if (tleft<=telapsed)
|
||||
{
|
||||
timeout.tv_sec=1;
|
||||
timeout.tv_usec=500000;
|
||||
broadcastPresence();
|
||||
}
|
||||
else
|
||||
{
|
||||
tleft-=telapsed;
|
||||
timeout.tv_sec=(long)(tleft/1000);
|
||||
timeout.tv_usec=(tleft%1000)*1000;
|
||||
}
|
||||
|
||||
lk.unlock(); //VERY hacky. don't like it
|
||||
if (d->exit) return;
|
||||
int rt=select(maxfd,&fds,nullptr,nullptr,&timeout);
|
||||
if (d->exit) return;
|
||||
lk.lock();
|
||||
if (d->exit) return;
|
||||
|
||||
if (rt)
|
||||
{
|
||||
for (sock_t fd : d->sockfds)
|
||||
{
|
||||
if (FD_ISSET(fd,&fds))
|
||||
{
|
||||
u8 bf[64];
|
||||
int size=60;
|
||||
size_t addr_len;
|
||||
struct sockaddr_storage their_addr;
|
||||
addr_len = sizeof their_addr;
|
||||
if ((size = recvfrom(fd,
|
||||
(dataz)bf,
|
||||
size , 0,(struct sockaddr *)&their_addr, (socklen_t*)&addr_len)) == -1)
|
||||
{
|
||||
ERROR_LOG(WIIMOTE,"UDPWii Packet error");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::lock_guard<std::mutex> lkm(d->mutex);
|
||||
if (pharsePacket(bf,size)==0)
|
||||
{
|
||||
//NOTICE_LOG(WIIMOTE,"UDPWII New pack");
|
||||
}
|
||||
else
|
||||
{
|
||||
//NOTICE_LOG(WIIMOTE,"UDPWII Wrong pack format... ignoring");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!(d->exit));
|
||||
}
|
||||
|
||||
UDPWiimote::~UDPWiimote()
|
||||
{
|
||||
d->exit = true;
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(d->termLock);
|
||||
d->thread.join();
|
||||
}
|
||||
for (auto& elem : d->sockfds)
|
||||
close(elem);
|
||||
close(d->bipv4_fd);
|
||||
close(d->bipv6_fd);
|
||||
cleanup;
|
||||
delete d;
|
||||
}
|
||||
|
||||
#define ACCEL_FLAG (1 << 0)
|
||||
#define BUTT_FLAG (1 << 1)
|
||||
#define IR_FLAG (1 << 2)
|
||||
#define NUN_FLAG (1 << 3)
|
||||
#define NUNACCEL_FLAG (1 << 4)
|
||||
|
||||
int UDPWiimote::pharsePacket(u8 * bf, size_t size)
|
||||
{
|
||||
if (size < 3)
|
||||
return -1;
|
||||
|
||||
if (bf[0] != 0xde)
|
||||
return -1;
|
||||
//if (bf[1]==0)
|
||||
// time=0;
|
||||
//if (bf[1]<time) //NOT LONGER NEEDED TO ALLOW MULTIPLE IPHONES ON A SINGLE PORT
|
||||
// return -1;
|
||||
//time=bf[1];
|
||||
u32 *p=(u32*)(&bf[3]);
|
||||
if (bf[2] & ACCEL_FLAG)
|
||||
{
|
||||
if ((size-(((u8*)p)-bf)) < 12)
|
||||
return -1;
|
||||
|
||||
double ux,uy,uz;
|
||||
ux=(double)((s32)ntohl(*p)); p++;
|
||||
uy=(double)((s32)ntohl(*p)); p++;
|
||||
uz=(double)((s32)ntohl(*p)); p++;
|
||||
waX=ux/1048576; //packet accel data
|
||||
waY=uy/1048576;
|
||||
waZ=uz/1048576;
|
||||
}
|
||||
|
||||
if (bf[2] & BUTT_FLAG)
|
||||
{
|
||||
if ((size-(((u8*)p)-bf)) < 4)
|
||||
return -1;
|
||||
|
||||
wiimoteMask = ntohl(*p); p++;
|
||||
}
|
||||
|
||||
if (bf[2] & IR_FLAG)
|
||||
{
|
||||
if ((size-(((u8*)p)-bf)) < 8)
|
||||
return -1;
|
||||
|
||||
pointerX=((double)((s32)ntohl(*p)))/1048576; p++;
|
||||
pointerY=((double)((s32)ntohl(*p)))/1048576; p++;
|
||||
}
|
||||
|
||||
if (bf[2] & NUN_FLAG)
|
||||
{
|
||||
if ((size-(((u8*)p)-bf)) < 9)
|
||||
return -1;
|
||||
|
||||
nunMask=*((u8*)p); p=(u32*)(((u8*)p)+1);
|
||||
nunX=((double)((s32)ntohl(*p)))/1048576; p++;
|
||||
nunY=((double)((s32)ntohl(*p)))/1048576; p++;
|
||||
}
|
||||
|
||||
if (bf[2] & NUNACCEL_FLAG)
|
||||
{
|
||||
if ((size-(((u8*)p)-bf)) < 12)
|
||||
return -1;
|
||||
|
||||
double ux,uy,uz;
|
||||
ux=(double)((s32)ntohl(*p)); p++;
|
||||
uy=(double)((s32)ntohl(*p)); p++;
|
||||
uz=(double)((s32)ntohl(*p)); p++;
|
||||
naX=ux/1048576; //packet accel data
|
||||
naY=uy/1048576;
|
||||
naZ=uz/1048576;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UDPWiimote::initBroadcastIPv4()
|
||||
{
|
||||
d->bipv4_fd=socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (d->bipv4_fd == BAD_SOCK)
|
||||
{
|
||||
WARN_LOG(WIIMOTE,"socket() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
int broad=1;
|
||||
if (setsockopt(d->bipv4_fd,SOL_SOCKET,SO_BROADCAST, (const dataz)(&broad), sizeof broad) == -1)
|
||||
{
|
||||
WARN_LOG(WIIMOTE,"setsockopt(SO_BROADCAST) failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void UDPWiimote::broadcastIPv4(const void * data, size_t size)
|
||||
{
|
||||
|
||||
struct sockaddr_in their_addr;
|
||||
their_addr.sin_family = AF_INET;
|
||||
their_addr.sin_port = htons(4431);
|
||||
their_addr.sin_addr.s_addr = INADDR_BROADCAST;
|
||||
memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);
|
||||
|
||||
int num;
|
||||
if ((num=sendto(d->bipv4_fd,(const dataz)data,(int)size,0,(struct sockaddr *) &their_addr, sizeof their_addr)) == -1)
|
||||
{
|
||||
WARN_LOG(WIIMOTE,"sendto() failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void UDPWiimote::initBroadcastIPv6()
|
||||
{
|
||||
//TODO: IPv6 support
|
||||
}
|
||||
|
||||
void UDPWiimote::broadcastIPv6(const void * data, size_t size)
|
||||
{
|
||||
//TODO: IPv6 support
|
||||
}
|
||||
|
||||
void UDPWiimote::broadcastPresence()
|
||||
{
|
||||
size_t slen;
|
||||
u8 bf[512];
|
||||
bf[0]=0xdf; //magic number
|
||||
*((u16*)(&(bf[1])))=htons(bcastMagic); //unique per-wiimote 16-bit ID
|
||||
bf[3]=(u8)index; //wiimote index
|
||||
*((u16*)(&(bf[4])))=htons(int_port); //port
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(d->nameMutex);
|
||||
slen=displayName.size();
|
||||
if (slen>=256)
|
||||
slen=255;
|
||||
bf[6]=(u8)slen; //display name size (max 255)
|
||||
memcpy(&(bf[7]),displayName.c_str(),slen); //display name
|
||||
}
|
||||
broadcastIPv4(bf,7+slen);
|
||||
broadcastIPv6(bf,7+slen);
|
||||
}
|
||||
|
||||
void UDPWiimote::getAccel(float* x, float* y, float* z)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(d->mutex);
|
||||
*x = (float)waX;
|
||||
*y = (float)waY;
|
||||
*z = (float)waZ;
|
||||
}
|
||||
|
||||
u32 UDPWiimote::getButtons()
|
||||
{
|
||||
u32 msk;
|
||||
std::lock_guard<std::mutex> lk(d->mutex);
|
||||
msk = wiimoteMask;
|
||||
return msk;
|
||||
}
|
||||
|
||||
void UDPWiimote::getIR(float* x, float* y)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(d->mutex);
|
||||
*x = (float)pointerX;
|
||||
*y = (float)pointerY;
|
||||
}
|
||||
|
||||
void UDPWiimote::getNunchuck(float* x, float* y, u8* mask)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(d->mutex);
|
||||
*x = (float)nunX;
|
||||
*y = (float)nunY;
|
||||
*mask = nunMask;
|
||||
}
|
||||
|
||||
void UDPWiimote::getNunchuckAccel(float* x, float* y, float* z)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(d->mutex);
|
||||
*x = (float)naX;
|
||||
*y = (float)naY;
|
||||
*z = (float)naZ;
|
||||
}
|
||||
|
||||
const std::string& UDPWiimote::getPort()
|
||||
{
|
||||
return port;
|
||||
}
|
||||
|
||||
void UDPWiimote::changeName(const std::string& name)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(d->nameMutex);
|
||||
displayName = name;
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "Common/Common.h"
|
||||
|
||||
#define UDPWM_B1 (1<<0)
|
||||
#define UDPWM_B2 (1<<1)
|
||||
#define UDPWM_BA (1<<2)
|
||||
#define UDPWM_BB (1<<3)
|
||||
#define UDPWM_BP (1<<4)
|
||||
#define UDPWM_BM (1<<5)
|
||||
#define UDPWM_BH (1<<6)
|
||||
#define UDPWM_BU (1<<7)
|
||||
#define UDPWM_BD (1<<8)
|
||||
#define UDPWM_BL (1<<9)
|
||||
#define UDPWM_BR (1<<10)
|
||||
#define UDPWM_SK (1<<11)
|
||||
#define UDPWM_NC (1<<0)
|
||||
#define UDPWM_NZ (1<<1)
|
||||
|
||||
class UDPWiimote
|
||||
{
|
||||
public:
|
||||
UDPWiimote(const std::string& port, const std::string& name, int index);
|
||||
virtual ~UDPWiimote();
|
||||
void getAccel(float* x, float* y, float* z);
|
||||
u32 getButtons();
|
||||
void getNunchuck(float* x, float* y, u8* mask);
|
||||
void getIR(float* x, float* y);
|
||||
void getNunchuckAccel(float* x, float* y, float* z);
|
||||
int getErrNo()
|
||||
{
|
||||
return err;
|
||||
}
|
||||
const std::string& getPort();
|
||||
void changeName(const std::string& name);
|
||||
|
||||
void mainThread();
|
||||
private:
|
||||
std::string port,displayName;
|
||||
int pharsePacket(u8* data, size_t size);
|
||||
struct _d; //using pimpl because Winsock2.h doesn't have include guards -_-
|
||||
_d* d;
|
||||
double waX, waY, waZ;
|
||||
double naX, naY, naZ;
|
||||
double nunX, nunY;
|
||||
double pointerX, pointerY;
|
||||
u8 nunMask;
|
||||
u32 wiimoteMask;
|
||||
u16 bcastMagic;
|
||||
int err;
|
||||
int index;
|
||||
int int_port;
|
||||
static int noinst;
|
||||
void broadcastPresence();
|
||||
void broadcastIPv4(const void* data, size_t size);
|
||||
void broadcastIPv6(const void* data, size_t size);
|
||||
void initBroadcastIPv4();
|
||||
void initBroadcastIPv6();
|
||||
};
|
|
@ -1,96 +0,0 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "InputCommon/UDPWrapper.h"
|
||||
|
||||
static const std::string DefaultPort(const int index)
|
||||
{
|
||||
static std::string s;
|
||||
s = "443";
|
||||
s += (char)('2' + index);
|
||||
return s;
|
||||
}
|
||||
|
||||
UDPWrapper::UDPWrapper(int indx, const char* const _name) :
|
||||
ControllerEmu::ControlGroup(_name,GROUP_TYPE_UDPWII),
|
||||
inst(nullptr), index(indx),
|
||||
updIR(false),updAccel(false),
|
||||
updButt(false),udpEn(false)
|
||||
, port(DefaultPort(indx))
|
||||
{
|
||||
//PanicAlert("UDPWrapper #%d ctor",index);
|
||||
}
|
||||
|
||||
void UDPWrapper::LoadConfig(IniFile::Section *sec, const std::string& defdev, const std::string& base )
|
||||
{
|
||||
ControlGroup::LoadConfig(sec,defdev,base);
|
||||
|
||||
std::string group( base + name ); group += "/";
|
||||
|
||||
int _updAccel,_updIR,_updButt,_udpEn,_updNun,_updNunAccel;
|
||||
sec->Get(group + "Enable",&_udpEn, 0);
|
||||
sec->Get(group + "Port", &port, DefaultPort(index));
|
||||
sec->Get(group + "Update_Accel", &_updAccel, 1);
|
||||
sec->Get(group + "Update_IR", &_updIR, 1);
|
||||
sec->Get(group + "Update_Butt", &_updButt, 1);
|
||||
sec->Get(group + "Update_Nunchuk", &_updNun, 1);
|
||||
sec->Get(group + "Update_NunchukAccel", &_updNunAccel, 0);
|
||||
|
||||
udpEn=(_udpEn>0);
|
||||
updAccel=(_updAccel>0);
|
||||
updIR=(_updIR>0);
|
||||
updButt=(_updButt>0);
|
||||
updNun=(_updNun>0);
|
||||
updNunAccel=(_updNunAccel>0);
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
void UDPWrapper::SaveConfig(IniFile::Section *sec, const std::string& defdev, const std::string& base )
|
||||
{
|
||||
ControlGroup::SaveConfig(sec,defdev,base);
|
||||
std::string group( base + name ); group += "/";
|
||||
sec->Set(group + "Enable", (int)udpEn, 0);
|
||||
sec->Set(group + "Port", port, DefaultPort(index));
|
||||
sec->Set(group + "Update_Accel", (int)updAccel, 1);
|
||||
sec->Set(group + "Update_IR", (int)updIR, 1);
|
||||
sec->Set(group + "Update_Butt", (int)updButt, 1);
|
||||
sec->Set(group + "Update_Nunchuk", (int)updNun, 1);
|
||||
sec->Set(group + "Update_NunchukAccel", (int)updNunAccel, 0);
|
||||
}
|
||||
|
||||
|
||||
void UDPWrapper::Refresh()
|
||||
{
|
||||
bool udpAEn=(inst!=nullptr);
|
||||
if (udpEn && udpAEn)
|
||||
{
|
||||
if (inst->getPort() == port)
|
||||
{
|
||||
delete inst;
|
||||
inst = new UDPWiimote(port, "Dolphin-Emu", index); //TODO: Changeable display name
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!udpEn)
|
||||
{
|
||||
if (inst)
|
||||
delete inst;
|
||||
inst = nullptr;
|
||||
return;
|
||||
}
|
||||
//else
|
||||
inst = new UDPWiimote(port, "Dolphin-Emu", index);
|
||||
}
|
||||
|
||||
UDPWrapper::~UDPWrapper()
|
||||
{
|
||||
if (inst)
|
||||
delete inst;
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Common/Common.h"
|
||||
#include "Common/IniFile.h"
|
||||
#include "InputCommon/ControllerEmu.h"
|
||||
#include "InputCommon/UDPWiimote.h"
|
||||
|
||||
class UDPWrapper : public ControllerEmu::ControlGroup
|
||||
{
|
||||
public:
|
||||
UDPWiimote * inst;
|
||||
int index;
|
||||
bool updIR, updAccel, updButt, updNun, updNunAccel, udpEn; //upd from update and udp from... well... UDP
|
||||
std::string port;
|
||||
|
||||
UDPWrapper(int index, const char* const _name);
|
||||
virtual void LoadConfig(IniFile::Section *sec, const std::string& defdev = "", const std::string& base = "") override;
|
||||
virtual void SaveConfig(IniFile::Section *sec, const std::string& defdev = "", const std::string& base = "") override;
|
||||
void Refresh();
|
||||
virtual ~UDPWrapper();
|
||||
};
|
Loading…
Reference in New Issue