2013-04-18 03:43:35 +00:00
|
|
|
// Copyright 2013 Dolphin Emulator Project
|
|
|
|
// Licensed under GPLv2
|
|
|
|
// Refer to the license.txt file included.
|
2010-04-02 02:48:24 +00:00
|
|
|
|
2010-10-12 19:42:29 +00:00
|
|
|
#include "InputConfigDiag.h"
|
2013-02-28 04:37:38 +00:00
|
|
|
#include "WxUtils.h"
|
2010-04-02 02:48:24 +00:00
|
|
|
|
2010-06-12 18:45:39 +00:00
|
|
|
void InputConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event))
|
2010-04-02 02:48:24 +00:00
|
|
|
{
|
2010-07-10 06:48:24 +00:00
|
|
|
wxFont small_font(6, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
|
|
|
|
|
2010-10-12 19:42:29 +00:00
|
|
|
g_controller_interface.UpdateInput();
|
2011-03-05 06:11:26 +00:00
|
|
|
|
2010-10-09 07:24:33 +00:00
|
|
|
// don't want game thread updating input when we are using it here
|
2011-03-07 00:16:38 +00:00
|
|
|
std::unique_lock<std::recursive_mutex> lk(g_controller_interface.update_lock, std::try_to_lock);
|
2011-03-05 06:11:26 +00:00
|
|
|
if (!lk.owns_lock())
|
2010-10-09 07:24:33 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
GamepadPage* const current_page = (GamepadPage*)m_pad_notebook->GetPage(m_pad_notebook->GetSelection());
|
|
|
|
|
2010-07-10 06:48:24 +00:00
|
|
|
std::vector< ControlGroupBox* >::iterator
|
|
|
|
g = current_page->control_groups.begin(),
|
|
|
|
ge = current_page->control_groups.end();
|
2010-04-02 02:48:24 +00:00
|
|
|
for ( ; g != ge; ++g )
|
|
|
|
{
|
2010-04-29 18:51:04 +00:00
|
|
|
// if this control group has a bitmap
|
2010-04-02 02:48:24 +00:00
|
|
|
if ( (*g)->static_bitmap )
|
|
|
|
{
|
2010-04-29 18:51:04 +00:00
|
|
|
wxMemoryDC dc;
|
|
|
|
wxBitmap bitmap((*g)->static_bitmap->GetBitmap());
|
|
|
|
dc.SelectObject(bitmap);
|
|
|
|
dc.Clear();
|
|
|
|
|
2010-07-10 06:48:24 +00:00
|
|
|
dc.SetFont(small_font);
|
|
|
|
dc.SetTextForeground(0xC0C0C0);
|
|
|
|
|
2010-04-29 18:51:04 +00:00
|
|
|
// label for sticks and stuff
|
|
|
|
if (64 == bitmap.GetHeight())
|
2013-02-28 04:37:38 +00:00
|
|
|
dc.DrawText(StrToWxStr((*g)->control_group->name).Upper(), 4, 2);
|
2010-04-29 18:51:04 +00:00
|
|
|
|
2010-04-02 02:48:24 +00:00
|
|
|
switch ( (*g)->control_group->type )
|
|
|
|
{
|
2010-04-13 05:15:38 +00:00
|
|
|
case GROUP_TYPE_TILT :
|
2010-04-02 02:48:24 +00:00
|
|
|
case GROUP_TYPE_STICK :
|
2010-04-22 07:11:49 +00:00
|
|
|
case GROUP_TYPE_CURSOR :
|
2010-04-02 02:48:24 +00:00
|
|
|
{
|
2010-04-22 07:11:49 +00:00
|
|
|
// this is starting to be a mess combining all these in one case
|
|
|
|
|
|
|
|
float x = 0, y = 0, z = 0;
|
2010-04-02 02:48:24 +00:00
|
|
|
float xx, yy;
|
2010-04-22 07:11:49 +00:00
|
|
|
|
|
|
|
switch ((*g)->control_group->type)
|
|
|
|
{
|
|
|
|
case GROUP_TYPE_STICK :
|
2010-04-13 05:15:38 +00:00
|
|
|
((ControllerEmu::AnalogStick*)(*g)->control_group)->GetState( &x, &y, 32.0, 32-1.5 );
|
2010-04-22 07:11:49 +00:00
|
|
|
break;
|
|
|
|
case GROUP_TYPE_TILT :
|
2010-04-13 05:15:38 +00:00
|
|
|
((ControllerEmu::Tilt*)(*g)->control_group)->GetState( &x, &y, 32.0, 32-1.5 );
|
2010-04-22 07:11:49 +00:00
|
|
|
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;
|
|
|
|
}
|
2010-04-13 05:15:38 +00:00
|
|
|
|
|
|
|
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();
|
2010-04-02 02:48:24 +00:00
|
|
|
xx *= 32 - 1; xx += 32;
|
|
|
|
yy *= 32 - 1; yy += 32;
|
|
|
|
|
|
|
|
// draw the shit
|
|
|
|
|
2010-04-22 07:11:49 +00:00
|
|
|
// ir cursor forward movement
|
2010-06-12 02:08:01 +00:00
|
|
|
if (GROUP_TYPE_CURSOR == (*g)->control_group->type)
|
2010-04-22 07:11:49 +00:00
|
|
|
{
|
2010-06-12 02:08:01 +00:00
|
|
|
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);
|
2010-04-22 07:11:49 +00:00
|
|
|
}
|
|
|
|
|
2010-04-02 02:48:24 +00:00
|
|
|
// circle for visual aid for diagonal adjustment
|
|
|
|
dc.SetPen(*wxLIGHT_GREY_PEN);
|
2010-04-22 07:11:49 +00:00
|
|
|
dc.SetBrush(*wxWHITE_BRUSH);
|
2010-04-13 05:15:38 +00:00
|
|
|
if ( GROUP_TYPE_STICK == (*g)->control_group->type )
|
2010-04-29 18:51:04 +00:00
|
|
|
{
|
|
|
|
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
2010-04-13 05:15:38 +00:00
|
|
|
dc.DrawCircle( 32, 32, 32);
|
2010-04-29 18:51:04 +00:00
|
|
|
}
|
2010-04-13 05:15:38 +00:00
|
|
|
else
|
2013-04-08 05:16:50 +00:00
|
|
|
{
|
2010-04-13 05:15:38 +00:00
|
|
|
dc.DrawRectangle( 16, 16, 32, 32 );
|
2013-04-08 05:16:50 +00:00
|
|
|
}
|
2010-04-02 02:48:24 +00:00
|
|
|
|
2010-04-22 07:11:49 +00:00
|
|
|
if ( GROUP_TYPE_CURSOR != (*g)->control_group->type )
|
|
|
|
{
|
2010-04-24 00:44:10 +00:00
|
|
|
// deadzone circle
|
2010-04-22 07:11:49 +00:00
|
|
|
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
|
|
|
|
dc.DrawCircle( 32, 32, ((*g)->control_group)->settings[0]->value * 32 );
|
|
|
|
}
|
2010-04-02 02:48:24 +00:00
|
|
|
|
2010-06-12 02:08:01 +00:00
|
|
|
// 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 );
|
|
|
|
|
2010-04-02 02:48:24 +00:00
|
|
|
// adjusted dot
|
2010-06-12 02:08:01 +00:00
|
|
|
if (x!=32 || y!=32)
|
2010-04-02 02:48:24 +00:00
|
|
|
{
|
|
|
|
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 );
|
|
|
|
}
|
|
|
|
|
2010-04-29 18:51:04 +00:00
|
|
|
}
|
|
|
|
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 );
|
2010-04-02 02:48:24 +00:00
|
|
|
|
2010-04-29 18:51:04 +00:00
|
|
|
// 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 );
|
|
|
|
}
|
2010-04-02 02:48:24 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
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 ];
|
2010-07-10 06:48:24 +00:00
|
|
|
for (unsigned int n = 0; n<button_count; ++n)
|
|
|
|
bitmasks[n] = (1 << n);
|
2010-04-02 02:48:24 +00:00
|
|
|
|
|
|
|
unsigned int buttons = 0;
|
|
|
|
((ControllerEmu::Buttons*)(*g)->control_group)->GetState( &buttons, bitmasks );
|
|
|
|
|
2010-07-10 06:48:24 +00:00
|
|
|
for (unsigned int n = 0; n<button_count; ++n)
|
2010-04-02 02:48:24 +00:00
|
|
|
{
|
|
|
|
if ( buttons & bitmasks[n] )
|
2013-04-08 05:16:50 +00:00
|
|
|
{
|
2010-04-02 02:48:24 +00:00
|
|
|
dc.SetBrush( *wxRED_BRUSH );
|
2013-04-08 05:16:50 +00:00
|
|
|
}
|
2010-04-02 02:48:24 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
unsigned char amt = 255 - (*g)->control_group->controls[n]->control_ref->State() * 128;
|
2010-07-10 06:48:24 +00:00
|
|
|
dc.SetBrush(wxBrush(wxColor(amt, amt, amt)));
|
2010-04-02 02:48:24 +00:00
|
|
|
}
|
2010-07-10 06:48:24 +00:00
|
|
|
dc.DrawRectangle(n * 12, 0, 14, 12);
|
|
|
|
|
|
|
|
// text
|
|
|
|
const char* const name = (*g)->control_group->controls[n]->name;
|
|
|
|
// bit of hax so ZL, ZR show up as L, R
|
2013-02-28 08:39:06 +00:00
|
|
|
dc.DrawText(StrToWxStr(std::string(1, (name[1] && name[1] < 'a') ? name[1] : name[0])), n*12 + 2, 1);
|
2010-04-02 02:48:24 +00:00
|
|
|
}
|
|
|
|
|
2010-05-24 14:53:27 +00:00
|
|
|
delete[] bitmasks;
|
2010-04-29 18:51:04 +00:00
|
|
|
|
2010-04-02 02:48:24 +00:00
|
|
|
}
|
|
|
|
break;
|
2010-04-24 00:44:10 +00:00
|
|
|
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();
|
|
|
|
|
2010-06-12 02:08:01 +00:00
|
|
|
// outline
|
|
|
|
dc.SetPen(*wxGREY_PEN);
|
|
|
|
dc.SetBrush(*wxWHITE_BRUSH);
|
|
|
|
dc.DrawRectangle(0, n*12, 64, 14);
|
|
|
|
|
|
|
|
// raw
|
2010-04-24 00:44:10 +00:00
|
|
|
dc.SetBrush(*wxGREY_BRUSH);
|
|
|
|
dc.DrawRectangle(0, n*12, trig_r*64, 14);
|
|
|
|
|
2010-06-12 02:08:01 +00:00
|
|
|
// deadzone affected
|
2010-04-24 00:44:10 +00:00
|
|
|
dc.SetBrush(*wxRED_BRUSH);
|
|
|
|
dc.DrawRectangle(0, n*12, trigs[n], 14);
|
2010-07-10 06:48:24 +00:00
|
|
|
|
|
|
|
// text
|
2013-02-28 04:37:38 +00:00
|
|
|
dc.DrawText(StrToWxStr((*g)->control_group->controls[n]->name), 3, n*12 + 1);
|
2010-04-24 00:44:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
delete[] trigs;
|
2010-04-02 02:48:24 +00:00
|
|
|
|
2010-04-24 00:44:10 +00:00
|
|
|
// deadzone box
|
|
|
|
dc.SetPen(*wxLIGHT_GREY_PEN);
|
|
|
|
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
|
|
|
dc.DrawRectangle(0, 0, deadzone*64, trigger_count*14);
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
2010-04-02 02:48:24 +00:00
|
|
|
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);
|
2010-07-10 06:48:24 +00:00
|
|
|
|
|
|
|
// text
|
2013-02-28 04:37:38 +00:00
|
|
|
dc.DrawText(StrToWxStr((*g)->control_group->controls[n+trigger_count]->name), 3, n*12 + 1);
|
2013-02-28 08:39:06 +00:00
|
|
|
dc.DrawText(StrToWxStr(std::string(1, (*g)->control_group->controls[n]->name[0])), 64 + 3, n*12 + 1);
|
2010-04-02 02:48:24 +00:00
|
|
|
}
|
2010-04-24 00:44:10 +00:00
|
|
|
|
|
|
|
// threshold box
|
|
|
|
dc.SetPen(*wxLIGHT_GREY_PEN);
|
2010-04-02 02:48:24 +00:00
|
|
|
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
|
|
|
dc.DrawRectangle(thresh*64, 0, 128, trigger_count*14);
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
2010-10-05 21:43:51 +00:00
|
|
|
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;
|
2010-04-02 02:48:24 +00:00
|
|
|
default :
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-04-29 18:51:04 +00:00
|
|
|
// box outline
|
|
|
|
// Windows XP color
|
|
|
|
dc.SetPen(wxPen(_T("#7f9db9")));
|
|
|
|
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
|
|
|
dc.DrawRectangle(0, 0, bitmap.GetWidth(), bitmap.GetHeight());
|
|
|
|
|
|
|
|
dc.SelectObject(wxNullBitmap);
|
|
|
|
(*g)->static_bitmap->SetBitmap(bitmap);
|
2010-04-02 02:48:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|