Skip to content

Commit 1f2ec9a

Browse files
authored
Merge pull request #11052 from Tilka/shinkansen
Add emulated Shinkansen controller
2 parents e3e6c3d + f5670f8 commit 1f2ec9a

11 files changed

Lines changed: 209 additions & 0 deletions

File tree

Source/Core/Core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ add_library(core
296296
HW/WiimoteEmu/Extension/Guitar.h
297297
HW/WiimoteEmu/Extension/Nunchuk.cpp
298298
HW/WiimoteEmu/Extension/Nunchuk.h
299+
HW/WiimoteEmu/Extension/Shinkansen.cpp
300+
HW/WiimoteEmu/Extension/Shinkansen.h
299301
HW/WiimoteEmu/Extension/TaTaCon.cpp
300302
HW/WiimoteEmu/Extension/TaTaCon.h
301303
HW/WiimoteEmu/Extension/Turntable.cpp

Source/Core/Core/HW/Wiimote.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ ControllerEmu::ControlGroup* GetTaTaConGroup(int number, WiimoteEmu::TaTaConGrou
152152
return static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))->GetTaTaConGroup(group);
153153
}
154154

155+
ControllerEmu::ControlGroup* GetShinkansenGroup(int number, WiimoteEmu::ShinkansenGroup group)
156+
{
157+
return static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))
158+
->GetShinkansenGroup(group);
159+
}
160+
155161
void Shutdown()
156162
{
157163
s_config.UnregisterHotplugCallback();

Source/Core/Core/HW/Wiimote.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ enum class TurntableGroup;
2828
enum class UDrawTabletGroup;
2929
enum class DrawsomeTabletGroup;
3030
enum class TaTaConGroup;
31+
enum class ShinkansenGroup;
3132
} // namespace WiimoteEmu
3233

3334
enum
@@ -92,6 +93,7 @@ ControllerEmu::ControlGroup* GetUDrawTabletGroup(int number, WiimoteEmu::UDrawTa
9293
ControllerEmu::ControlGroup* GetDrawsomeTabletGroup(int number,
9394
WiimoteEmu::DrawsomeTabletGroup group);
9495
ControllerEmu::ControlGroup* GetTaTaConGroup(int number, WiimoteEmu::TaTaConGroup group);
96+
ControllerEmu::ControlGroup* GetShinkansenGroup(int number, WiimoteEmu::ShinkansenGroup group);
9597

9698
bool NetPlay_GetButtonPress(int wiimote, bool pressed);
9799
} // namespace Wiimote
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Copyright 2022 Dolphin Emulator Project
2+
// SPDX-License-Identifier: GPL-2.0-or-later
3+
4+
#include "Core/HW/WiimoteEmu/Extension/Shinkansen.h"
5+
6+
#include <array>
7+
8+
#include "Common/Assert.h"
9+
#include "Common/Common.h"
10+
#include "Common/CommonTypes.h"
11+
#include "Core/HW/WiimoteEmu/WiimoteEmu.h"
12+
13+
#include "InputCommon/ControllerEmu/ControlGroup/Buttons.h"
14+
#include "InputCommon/ControllerEmu/ControlGroup/MixedTriggers.h"
15+
16+
namespace WiimoteEmu
17+
{
18+
// TODO: check this (only the last byte is known good)
19+
constexpr std::array<u8, 6> shinkansen_id{{0x00, 0x00, 0xa4, 0x20, 0x01, 0x10}};
20+
21+
Shinkansen::Shinkansen() : Extension3rdParty("Shinkansen", _trans("Shinkansen Controller"))
22+
{
23+
// Button layout on the controller:
24+
//
25+
// Up Select Start D
26+
// Left Right A C
27+
// Down B
28+
//
29+
groups.emplace_back(m_buttons = new ControllerEmu::Buttons(_trans("Buttons")));
30+
m_buttons->AddInput(ControllerEmu::Translate, _trans("Left"));
31+
m_buttons->AddInput(ControllerEmu::Translate, _trans("Down"));
32+
m_buttons->AddInput(ControllerEmu::Translate, _trans("Right"));
33+
m_buttons->AddInput(ControllerEmu::Translate, _trans("Up"));
34+
m_buttons->AddInput(ControllerEmu::DoNotTranslate, "A");
35+
m_buttons->AddInput(ControllerEmu::DoNotTranslate, "B");
36+
m_buttons->AddInput(ControllerEmu::DoNotTranslate, "C");
37+
m_buttons->AddInput(ControllerEmu::DoNotTranslate, "D");
38+
m_buttons->AddInput(ControllerEmu::Translate, _trans("Select"));
39+
m_buttons->AddInput(ControllerEmu::Translate, _trans("Start"));
40+
41+
// For easier axis mapping the right lever is inverted in Dolphin,
42+
// so that the train coasts when no trigger is squeezed.
43+
groups.emplace_back(m_levers = new ControllerEmu::MixedTriggers(_trans("Levers")));
44+
m_levers->AddInput(ControllerEmu::Translate, _trans("L"));
45+
m_levers->AddInput(ControllerEmu::Translate, _trans("R"));
46+
m_levers->AddInput(ControllerEmu::Translate, _trans("L-Analog"));
47+
m_levers->AddInput(ControllerEmu::Translate, _trans("R-Analog"));
48+
49+
groups.emplace_back(m_led = new ControllerEmu::ControlGroup(_trans("Light")));
50+
m_led->AddOutput(ControllerEmu::Translate, _trans("Doors Locked"));
51+
}
52+
53+
void Shinkansen::Update()
54+
{
55+
DataFormat ext_data = {};
56+
57+
u16 digital = 0;
58+
const u16 lever_bitmasks[2] = {};
59+
double analog[2] = {};
60+
m_levers->GetState(&digital, lever_bitmasks, analog);
61+
// The game requires these specific values, all other values are treated like 0/255 (which are
62+
// guesses).
63+
const u8 brake_values[] = {0, 53, 79, 105, 132, 159, 187, 217, 250};
64+
const u8 power_values[] = {255, 229, 208, 189, 170, 153, 135, 118, 101, 85, 68, 51, 35, 17};
65+
ext_data.brake = brake_values[size_t(analog[0] * (sizeof(brake_values) - 1))];
66+
ext_data.power = power_values[size_t(analog[1] * (sizeof(power_values) - 1))];
67+
68+
// Note: This currently assumes a little-endian host.
69+
const u16 button_bitmasks[] = {
70+
0x0200, // Left
71+
0x0040, // Down
72+
0x0080, // Right
73+
0x0100, // Up
74+
0x2000, // A
75+
0x4000, // B
76+
0x1000, // C
77+
0x0800, // D
78+
0x0010, // Select
79+
0x0004, // Start
80+
};
81+
m_buttons->GetState(&ext_data.buttons, button_bitmasks);
82+
ext_data.buttons ^= 0xFFFF;
83+
Common::BitCastPtr<DataFormat>(&m_reg.controller_data) = ext_data;
84+
85+
const auto lock = GetStateLock();
86+
m_led->controls[0]->control_ref->State(m_reg.identifier[1]);
87+
}
88+
89+
void Shinkansen::Reset()
90+
{
91+
EncryptedExtension::Reset();
92+
93+
m_reg = {};
94+
m_reg.identifier = shinkansen_id;
95+
m_reg.calibration.fill(0xff);
96+
}
97+
98+
ControllerEmu::ControlGroup* Shinkansen::GetGroup(ShinkansenGroup group)
99+
{
100+
switch (group)
101+
{
102+
case ShinkansenGroup::Levers:
103+
return m_levers;
104+
case ShinkansenGroup::Buttons:
105+
return m_buttons;
106+
case ShinkansenGroup::Light:
107+
return m_led;
108+
default:
109+
ASSERT(false);
110+
return nullptr;
111+
}
112+
}
113+
114+
} // namespace WiimoteEmu
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2022 Dolphin Emulator Project
2+
// SPDX-License-Identifier: GPL-2.0-or-later
3+
4+
#pragma once
5+
6+
#include "Core/HW/WiimoteEmu/Extension/Extension.h"
7+
8+
namespace ControllerEmu
9+
{
10+
class Buttons;
11+
class ControlGroup;
12+
class MixedTriggers;
13+
} // namespace ControllerEmu
14+
15+
namespace WiimoteEmu
16+
{
17+
enum class ShinkansenGroup
18+
{
19+
Buttons,
20+
Levers,
21+
Light,
22+
};
23+
24+
class Shinkansen : public Extension3rdParty
25+
{
26+
public:
27+
Shinkansen();
28+
29+
void Update() override;
30+
void Reset() override;
31+
ControllerEmu::ControlGroup* GetGroup(ShinkansenGroup group);
32+
33+
private:
34+
ControllerEmu::Buttons* m_buttons;
35+
ControllerEmu::MixedTriggers* m_levers;
36+
ControllerEmu::ControlGroup* m_led;
37+
38+
struct DataFormat
39+
{
40+
u8 unk0;
41+
u8 unk1;
42+
u8 brake;
43+
u8 power;
44+
u8 unk4;
45+
u8 unk5;
46+
u16 buttons;
47+
};
48+
};
49+
50+
} // namespace WiimoteEmu

Source/Core/Core/HW/WiimoteEmu/ExtensionPort.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ enum ExtensionNumber : u8
2121
UDRAW_TABLET,
2222
DRAWSOME_TABLET,
2323
TATACON,
24+
SHINKANSEN,
2425

2526
MAX
2627
};

Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "Core/HW/WiimoteEmu/Extension/Drums.h"
3131
#include "Core/HW/WiimoteEmu/Extension/Guitar.h"
3232
#include "Core/HW/WiimoteEmu/Extension/Nunchuk.h"
33+
#include "Core/HW/WiimoteEmu/Extension/Shinkansen.h"
3334
#include "Core/HW/WiimoteEmu/Extension/TaTaCon.h"
3435
#include "Core/HW/WiimoteEmu/Extension/Turntable.h"
3536
#include "Core/HW/WiimoteEmu/Extension/UDrawTablet.h"
@@ -247,6 +248,7 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index)
247248
m_attachments->AddAttachment(std::make_unique<WiimoteEmu::UDrawTablet>());
248249
m_attachments->AddAttachment(std::make_unique<WiimoteEmu::DrawsomeTablet>());
249250
m_attachments->AddAttachment(std::make_unique<WiimoteEmu::TaTaCon>());
251+
m_attachments->AddAttachment(std::make_unique<WiimoteEmu::Shinkansen>());
250252

251253
m_attachments->AddSetting(&m_motion_plus_setting, {_trans("Attach MotionPlus")}, true);
252254

@@ -400,6 +402,13 @@ ControllerEmu::ControlGroup* Wiimote::GetTaTaConGroup(TaTaConGroup group) const
400402
->GetGroup(group);
401403
}
402404

405+
ControllerEmu::ControlGroup* Wiimote::GetShinkansenGroup(ShinkansenGroup group) const
406+
{
407+
return static_cast<Shinkansen*>(
408+
m_attachments->GetAttachmentList()[ExtensionNumber::SHINKANSEN].get())
409+
->GetGroup(group);
410+
}
411+
403412
bool Wiimote::ProcessExtensionPortEvent()
404413
{
405414
// WiiBrew: Following a connection or disconnection event on the Extension Port,

Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ enum class TurntableGroup;
6262
enum class UDrawTabletGroup;
6363
enum class DrawsomeTabletGroup;
6464
enum class TaTaConGroup;
65+
enum class ShinkansenGroup;
6566

6667
template <typename T>
6768
void UpdateCalibrationDataChecksum(T& data, int cksum_bytes)
@@ -123,6 +124,7 @@ class Wiimote : public ControllerEmu::EmulatedController, public WiimoteCommon::
123124
ControllerEmu::ControlGroup* GetUDrawTabletGroup(UDrawTabletGroup group) const;
124125
ControllerEmu::ControlGroup* GetDrawsomeTabletGroup(DrawsomeTabletGroup group) const;
125126
ControllerEmu::ControlGroup* GetTaTaConGroup(TaTaConGroup group) const;
127+
ControllerEmu::ControlGroup* GetShinkansenGroup(ShinkansenGroup group) const;
126128

127129
void Update() override;
128130
void EventLinked() override;

Source/Core/DolphinLib.props

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@
322322
<ClInclude Include="Core\HW\WiimoteEmu\Extension\Extension.h" />
323323
<ClInclude Include="Core\HW\WiimoteEmu\Extension\Guitar.h" />
324324
<ClInclude Include="Core\HW\WiimoteEmu\Extension\Nunchuk.h" />
325+
<ClInclude Include="Core\HW\WiimoteEmu\Extension\Shinkansen.h" />
325326
<ClInclude Include="Core\HW\WiimoteEmu\Extension\TaTaCon.h" />
326327
<ClInclude Include="Core\HW\WiimoteEmu\Extension\Turntable.h" />
327328
<ClInclude Include="Core\HW\WiimoteEmu\Extension\UDrawTablet.h" />
@@ -939,6 +940,7 @@
939940
<ClCompile Include="Core\HW\WiimoteEmu\Extension\Extension.cpp" />
940941
<ClCompile Include="Core\HW\WiimoteEmu\Extension\Guitar.cpp" />
941942
<ClCompile Include="Core\HW\WiimoteEmu\Extension\Nunchuk.cpp" />
943+
<ClCompile Include="Core\HW\WiimoteEmu\Extension\Shinkansen.cpp" />
942944
<ClCompile Include="Core\HW\WiimoteEmu\Extension\TaTaCon.cpp" />
943945
<ClCompile Include="Core\HW\WiimoteEmu\Extension\Turntable.cpp" />
944946
<ClCompile Include="Core\HW\WiimoteEmu\Extension\UDrawTablet.cpp" />

Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "Core/HW/WiimoteEmu/Extension/Drums.h"
1515
#include "Core/HW/WiimoteEmu/Extension/Guitar.h"
1616
#include "Core/HW/WiimoteEmu/Extension/Nunchuk.h"
17+
#include "Core/HW/WiimoteEmu/Extension/Shinkansen.h"
1718
#include "Core/HW/WiimoteEmu/Extension/TaTaCon.h"
1819
#include "Core/HW/WiimoteEmu/Extension/Turntable.h"
1920
#include "Core/HW/WiimoteEmu/Extension/UDrawTablet.h"
@@ -32,6 +33,7 @@ WiimoteEmuExtension::WiimoteEmuExtension(MappingWindow* window) : MappingWidget(
3233
CreateUDrawTabletLayout();
3334
CreateDrawsomeTabletLayout();
3435
CreateTaTaConLayout();
36+
CreateShinkansenLayout();
3537
CreateMainLayout();
3638

3739
ChangeExtensionType(WiimoteEmu::ExtensionNumber::NONE);
@@ -224,6 +226,21 @@ void WiimoteEmuExtension::CreateTaTaConLayout()
224226
m_tatacon_box->setLayout(hbox);
225227
}
226228

229+
void WiimoteEmuExtension::CreateShinkansenLayout()
230+
{
231+
auto* hbox = new QHBoxLayout();
232+
m_shinkansen_box = new QGroupBox(tr("Shinkansen"), this);
233+
234+
hbox->addWidget(CreateGroupBox(
235+
tr("Levers"), Wiimote::GetShinkansenGroup(GetPort(), WiimoteEmu::ShinkansenGroup::Levers)));
236+
hbox->addWidget(CreateGroupBox(
237+
tr("Buttons"), Wiimote::GetShinkansenGroup(GetPort(), WiimoteEmu::ShinkansenGroup::Buttons)));
238+
hbox->addWidget(CreateGroupBox(
239+
tr("Light"), Wiimote::GetShinkansenGroup(GetPort(), WiimoteEmu::ShinkansenGroup::Light)));
240+
241+
m_shinkansen_box->setLayout(hbox);
242+
}
243+
227244
void WiimoteEmuExtension::CreateMainLayout()
228245
{
229246
m_main_layout = new QHBoxLayout();
@@ -237,6 +254,7 @@ void WiimoteEmuExtension::CreateMainLayout()
237254
m_main_layout->addWidget(m_udraw_tablet_box);
238255
m_main_layout->addWidget(m_drawsome_tablet_box);
239256
m_main_layout->addWidget(m_tatacon_box);
257+
m_main_layout->addWidget(m_shinkansen_box);
240258

241259
setLayout(m_main_layout);
242260
}
@@ -269,4 +287,5 @@ void WiimoteEmuExtension::ChangeExtensionType(u32 type)
269287
m_udraw_tablet_box->setHidden(type != ExtensionNumber::UDRAW_TABLET);
270288
m_drawsome_tablet_box->setHidden(type != ExtensionNumber::DRAWSOME_TABLET);
271289
m_tatacon_box->setHidden(type != ExtensionNumber::TATACON);
290+
m_shinkansen_box->setHidden(type != ExtensionNumber::SHINKANSEN);
272291
}

0 commit comments

Comments
 (0)