1
// Copyright 2013 Dolphin Emulator Project
2
// Licensed under GPLv2
3
// Refer to the license.txt file included.
5
#include "InputConfigDiag.h"
8
void InputConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event))
10
wxFont small_font(6, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
12
g_controller_interface.UpdateInput();
14
// don't want game thread updating input when we are using it here
15
std::unique_lock<std::recursive_mutex> lk(g_controller_interface.update_lock, std::try_to_lock);
19
GamepadPage* const current_page = (GamepadPage*)m_pad_notebook->GetPage(m_pad_notebook->GetSelection());
21
std::vector< ControlGroupBox* >::iterator
22
g = current_page->control_groups.begin(),
23
ge = current_page->control_groups.end();
24
for ( ; g != ge; ++g )
26
// if this control group has a bitmap
27
if ( (*g)->static_bitmap )
30
wxBitmap bitmap((*g)->static_bitmap->GetBitmap());
31
dc.SelectObject(bitmap);
34
dc.SetFont(small_font);
35
dc.SetTextForeground(0xC0C0C0);
37
// label for sticks and stuff
38
if (64 == bitmap.GetHeight())
39
dc.DrawText(StrToWxStr((*g)->control_group->name).Upper(), 4, 2);
41
switch ( (*g)->control_group->type )
43
case GROUP_TYPE_TILT :
44
case GROUP_TYPE_STICK :
45
case GROUP_TYPE_CURSOR :
47
// this is starting to be a mess combining all these in one case
49
float x = 0, y = 0, z = 0;
52
switch ((*g)->control_group->type)
54
case GROUP_TYPE_STICK :
55
((ControllerEmu::AnalogStick*)(*g)->control_group)->GetState( &x, &y, 32.0, 32-1.5 );
57
case GROUP_TYPE_TILT :
58
((ControllerEmu::Tilt*)(*g)->control_group)->GetState( &x, &y, 32.0, 32-1.5 );
60
case GROUP_TYPE_CURSOR :
61
((ControllerEmu::Cursor*)(*g)->control_group)->GetState( &x, &y, &z );
62
x *= (32-1.5); x+= 32;
63
y *= (32-1.5); y+= 32;
67
xx = (*g)->control_group->controls[3]->control_ref->State();
68
xx -= (*g)->control_group->controls[2]->control_ref->State();
69
yy = (*g)->control_group->controls[1]->control_ref->State();
70
yy -= (*g)->control_group->controls[0]->control_ref->State();
71
xx *= 32 - 1; xx += 32;
72
yy *= 32 - 1; yy += 32;
76
// ir cursor forward movement
77
if (GROUP_TYPE_CURSOR == (*g)->control_group->type)
81
dc.SetPen(*wxRED_PEN);
82
dc.SetBrush(*wxRED_BRUSH);
86
dc.SetPen(*wxGREY_PEN);
87
dc.SetBrush(*wxGREY_BRUSH);
89
dc.DrawRectangle( 0, 31 - z*31, 64, 2);
92
// octagon for visual aid for diagonal adjustment
93
dc.SetPen(*wxLIGHT_GREY_PEN);
94
dc.SetBrush(*wxWHITE_BRUSH);
95
if ( GROUP_TYPE_STICK == (*g)->control_group->type )
97
// outline and fill colors
98
wxBrush LightGrayBrush(_T("#dddddd"));
99
wxPen LightGrayPen(_T("#bfbfbf"));
100
dc.SetBrush(LightGrayBrush);
101
dc.SetPen(LightGrayPen);
110
if (strcmp((*g)->control_group->name, "Main Stick") == 0)
112
max = (87.0f / 127.0f) * 100;
113
diagonal = (55.0f / 127.0f) * 100.0;
115
else if (strcmp((*g)->control_group->name,"C-Stick") == 0)
117
max = (74.0f / 127.0f) * 100;
118
diagonal = (46.0f / 127.0f) * 100;
122
max = (82.0f / 127.0f) * 100;
123
diagonal = (58.0f / 127.0f) * 100;
128
Points[0].x = (int)(0.0 * d_of + x_of); Points[0].y = (int)(max * d_of + x_of);
129
Points[1].x = (int)(diagonal * d_of + x_of); Points[1].y = (int)(diagonal * d_of + x_of);
130
Points[2].x = (int)(max * d_of + x_of); Points[2].y = (int)(0.0 * d_of + x_of);
131
Points[3].x = (int)(diagonal * d_of + x_of); Points[3].y = (int)(-diagonal * d_of + x_of);
132
Points[4].x = (int)(0.0 * d_of + x_of); Points[4].y = (int)(-max * d_of + x_of);
133
Points[5].x = (int)(-diagonal * d_of + x_of); Points[5].y = (int)(-diagonal * d_of + x_of);
134
Points[6].x = (int)(-max * d_of + x_of); Points[6].y = (int)(0.0 * d_of + x_of);
135
Points[7].x = (int)(-diagonal * d_of + x_of); Points[7].y = (int)(diagonal * d_of + x_of);
138
dc.DrawPolygon(8, Points);
142
dc.DrawRectangle( 16, 16, 32, 32 );
145
if ( GROUP_TYPE_CURSOR != (*g)->control_group->type )
148
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
149
dc.DrawCircle( 32, 32, ((*g)->control_group)->settings[SETTING_DEADZONE]->value * 32 );
153
dc.SetPen(*wxGREY_PEN);
154
dc.SetBrush(*wxGREY_BRUSH);
155
// i like the dot better than the cross i think
156
dc.DrawRectangle( xx - 2, yy - 2, 4, 4 );
157
//dc.DrawRectangle( xx-1, 64-yy-4, 2, 8 );
158
//dc.DrawRectangle( xx-4, 64-yy-1, 8, 2 );
163
dc.SetPen(*wxRED_PEN);
164
dc.SetBrush(*wxRED_BRUSH);
165
dc.DrawRectangle( x-2, 64-y-2, 4, 4 );
166
// i like the dot better than the cross i think
167
//dc.DrawRectangle( x-1, 64-y-4, 2, 8 );
168
//dc.DrawRectangle( x-4, 64-y-1, 8, 2 );
173
case GROUP_TYPE_FORCE :
177
const float deadzone = 32 * ((*g)->control_group)->settings[0]->value;
180
((ControllerEmu::Force*)(*g)->control_group)->GetState( adj_dot, 32.0, 32-1.5 );
183
for ( unsigned int i=0; i<3; ++i )
185
raw_dot[i] = (*g)->control_group->controls[i*2 + 1]->control_ref->State()
186
- (*g)->control_group->controls[i*2]->control_ref->State();
187
raw_dot[i] *= 32 - 1; raw_dot[i] += 32;
190
// deadzone rect for forward/backward visual
191
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
192
dc.SetPen(*wxLIGHT_GREY_PEN);
193
dc.DrawRectangle( 0, 32 - deadzone, 64, deadzone * 2 );
195
// raw forward/background line
196
dc.SetPen(*wxGREY_PEN);
197
dc.SetBrush(*wxGREY_BRUSH);
198
dc.DrawRectangle( 0, raw_dot[2] - 1, 64, 2 );
200
// adjusted forward/background line
201
if ( adj_dot[2]!=32 )
203
dc.SetPen(*wxRED_PEN);
204
dc.SetBrush(*wxRED_BRUSH);
205
dc.DrawRectangle( 0, adj_dot[2] - 1, 64, 2 );
208
// a rectangle, for looks i guess
209
dc.SetBrush(*wxWHITE_BRUSH);
210
dc.SetPen(*wxLIGHT_GREY_PEN);
211
dc.DrawRectangle( 16, 16, 32, 32 );
214
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
215
dc.DrawRectangle( 32 - deadzone, 32 - deadzone, deadzone * 2, deadzone * 2 );
218
dc.SetPen(*wxGREY_PEN);
219
dc.SetBrush(*wxGREY_BRUSH);
220
dc.DrawRectangle( raw_dot[1] - 2, raw_dot[0] - 2, 4, 4 );
223
if ( adj_dot[1]!=32 || adj_dot[0]!=32 )
225
dc.SetPen(*wxRED_PEN);
226
dc.SetBrush(*wxRED_BRUSH);
227
dc.DrawRectangle( adj_dot[1]-2, adj_dot[0]-2, 4, 4 );
232
case GROUP_TYPE_BUTTONS :
234
const unsigned int button_count = ((unsigned int)(*g)->control_group->controls.size());
237
dc.SetPen(*wxGREY_PEN);
239
unsigned int * const bitmasks = new unsigned int[ button_count ];
240
for (unsigned int n = 0; n<button_count; ++n)
241
bitmasks[n] = (1 << n);
243
unsigned int buttons = 0;
244
((ControllerEmu::Buttons*)(*g)->control_group)->GetState( &buttons, bitmasks );
246
for (unsigned int n = 0; n<button_count; ++n)
248
if ( buttons & bitmasks[n] )
250
dc.SetBrush( *wxRED_BRUSH );
254
unsigned char amt = 255 - (*g)->control_group->controls[n]->control_ref->State() * 128;
255
dc.SetBrush(wxBrush(wxColor(amt, amt, amt)));
257
dc.DrawRectangle(n * 12, 0, 14, 12);
260
const char* const name = (*g)->control_group->controls[n]->name;
261
// bit of hax so ZL, ZR show up as L, R
262
dc.DrawText(StrToWxStr(std::string(1, (name[1] && name[1] < 'a') ? name[1] : name[0])), n*12 + 2, 1);
269
case GROUP_TYPE_TRIGGERS :
271
const unsigned int trigger_count = ((unsigned int)((*g)->control_group->controls.size()));
274
dc.SetPen(*wxGREY_PEN);
275
ControlState deadzone = (*g)->control_group->settings[0]->value;
277
unsigned int* const trigs = new unsigned int[trigger_count];
278
((ControllerEmu::Triggers*)(*g)->control_group)->GetState( trigs, 64 );
280
for ( unsigned int n = 0; n < trigger_count; ++n )
282
ControlState trig_r = (*g)->control_group->controls[n]->control_ref->State();
285
dc.SetPen(*wxGREY_PEN);
286
dc.SetBrush(*wxWHITE_BRUSH);
287
dc.DrawRectangle(0, n*12, 64, 14);
290
dc.SetBrush(*wxGREY_BRUSH);
291
dc.DrawRectangle(0, n*12, trig_r*64, 14);
294
dc.SetBrush(*wxRED_BRUSH);
295
dc.DrawRectangle(0, n*12, trigs[n], 14);
298
dc.DrawText(StrToWxStr((*g)->control_group->controls[n]->name), 3, n*12 + 1);
304
dc.SetPen(*wxLIGHT_GREY_PEN);
305
dc.SetBrush(*wxTRANSPARENT_BRUSH);
306
dc.DrawRectangle(0, 0, deadzone*64, trigger_count*14);
310
case GROUP_TYPE_MIXED_TRIGGERS :
312
const unsigned int trigger_count = ((unsigned int)((*g)->control_group->controls.size() / 2));
315
dc.SetPen(*wxGREY_PEN);
316
ControlState thresh = (*g)->control_group->settings[0]->value;
318
for ( unsigned int n = 0; n < trigger_count; ++n )
320
dc.SetBrush(*wxRED_BRUSH);
321
ControlState trig_d = (*g)->control_group->controls[n]->control_ref->State();
323
ControlState trig_a = trig_d > thresh ? 1
324
: (*g)->control_group->controls[n+trigger_count]->control_ref->State();
326
dc.DrawRectangle(0, n*12, 64+20, 14);
327
if ( trig_d <= thresh )
328
dc.SetBrush(*wxWHITE_BRUSH);
329
dc.DrawRectangle(trig_a*64, n*12, 64+20, 14);
330
dc.DrawRectangle(64, n*12, 32, 14);
333
dc.DrawText(StrToWxStr((*g)->control_group->controls[n+trigger_count]->name), 3, n*12 + 1);
334
dc.DrawText(StrToWxStr(std::string(1, (*g)->control_group->controls[n]->name[0])), 64 + 3, n*12 + 1);
338
dc.SetPen(*wxLIGHT_GREY_PEN);
339
dc.SetBrush(*wxTRANSPARENT_BRUSH);
340
dc.DrawRectangle(thresh*64, 0, 128, trigger_count*14);
344
case GROUP_TYPE_SLIDER:
346
const ControlState deadzone = (*g)->control_group->settings[0]->value;
348
ControlState state = (*g)->control_group->controls[1]->control_ref->State() - (*g)->control_group->controls[0]->control_ref->State();
349
dc.SetPen(*wxGREY_PEN);
350
dc.SetBrush(*wxGREY_BRUSH);
351
dc.DrawRectangle(31 + state * 30, 0, 2, 14);
353
((ControllerEmu::Slider*)(*g)->control_group)->GetState(&state, 1);
356
dc.SetPen(*wxRED_PEN);
357
dc.SetBrush(*wxRED_BRUSH);
358
dc.DrawRectangle(31 + state * 30, 0, 2, 14);
362
dc.SetPen(*wxLIGHT_GREY_PEN);
363
dc.SetBrush(*wxTRANSPARENT_BRUSH);
364
dc.DrawRectangle(32 - deadzone * 32, 0, deadzone * 64, 14);
373
dc.SetPen(wxPen(_T("#7f9db9")));
374
dc.SetBrush(*wxTRANSPARENT_BRUSH);
375
dc.DrawRectangle(0, 0, bitmap.GetWidth(), bitmap.GetHeight());
377
dc.SelectObject(wxNullBitmap);
378
(*g)->static_bitmap->SetBitmap(bitmap);