Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Merge pull request #11052 from Tilka/shinkansen
Add emulated Shinkansen controller
- Loading branch information
Showing
11 changed files
with
209 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| // Copyright 2022 Dolphin Emulator Project | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| #include "Core/HW/WiimoteEmu/Extension/Shinkansen.h" | ||
|
|
||
| #include <array> | ||
|
|
||
| #include "Common/Assert.h" | ||
| #include "Common/Common.h" | ||
| #include "Common/CommonTypes.h" | ||
| #include "Core/HW/WiimoteEmu/WiimoteEmu.h" | ||
|
|
||
| #include "InputCommon/ControllerEmu/ControlGroup/Buttons.h" | ||
| #include "InputCommon/ControllerEmu/ControlGroup/MixedTriggers.h" | ||
|
|
||
| namespace WiimoteEmu | ||
| { | ||
| // TODO: check this (only the last byte is known good) | ||
| constexpr std::array<u8, 6> shinkansen_id{{0x00, 0x00, 0xa4, 0x20, 0x01, 0x10}}; | ||
|
|
||
| Shinkansen::Shinkansen() : Extension3rdParty("Shinkansen", _trans("Shinkansen Controller")) | ||
| { | ||
| // Button layout on the controller: | ||
| // | ||
| // Up Select Start D | ||
| // Left Right A C | ||
| // Down B | ||
| // | ||
| groups.emplace_back(m_buttons = new ControllerEmu::Buttons(_trans("Buttons"))); | ||
| m_buttons->AddInput(ControllerEmu::Translate, _trans("Left")); | ||
| m_buttons->AddInput(ControllerEmu::Translate, _trans("Down")); | ||
| m_buttons->AddInput(ControllerEmu::Translate, _trans("Right")); | ||
| m_buttons->AddInput(ControllerEmu::Translate, _trans("Up")); | ||
| m_buttons->AddInput(ControllerEmu::DoNotTranslate, "A"); | ||
| m_buttons->AddInput(ControllerEmu::DoNotTranslate, "B"); | ||
| m_buttons->AddInput(ControllerEmu::DoNotTranslate, "C"); | ||
| m_buttons->AddInput(ControllerEmu::DoNotTranslate, "D"); | ||
| m_buttons->AddInput(ControllerEmu::Translate, _trans("Select")); | ||
| m_buttons->AddInput(ControllerEmu::Translate, _trans("Start")); | ||
|
|
||
| // For easier axis mapping the right lever is inverted in Dolphin, | ||
| // so that the train coasts when no trigger is squeezed. | ||
| groups.emplace_back(m_levers = new ControllerEmu::MixedTriggers(_trans("Levers"))); | ||
| m_levers->AddInput(ControllerEmu::Translate, _trans("L")); | ||
| m_levers->AddInput(ControllerEmu::Translate, _trans("R")); | ||
| m_levers->AddInput(ControllerEmu::Translate, _trans("L-Analog")); | ||
| m_levers->AddInput(ControllerEmu::Translate, _trans("R-Analog")); | ||
|
|
||
| groups.emplace_back(m_led = new ControllerEmu::ControlGroup(_trans("Light"))); | ||
| m_led->AddOutput(ControllerEmu::Translate, _trans("Doors Locked")); | ||
| } | ||
|
|
||
| void Shinkansen::Update() | ||
| { | ||
| DataFormat ext_data = {}; | ||
|
|
||
| u16 digital = 0; | ||
| const u16 lever_bitmasks[2] = {}; | ||
| double analog[2] = {}; | ||
| m_levers->GetState(&digital, lever_bitmasks, analog); | ||
| // The game requires these specific values, all other values are treated like 0/255 (which are | ||
| // guesses). | ||
| const u8 brake_values[] = {0, 53, 79, 105, 132, 159, 187, 217, 250}; | ||
| const u8 power_values[] = {255, 229, 208, 189, 170, 153, 135, 118, 101, 85, 68, 51, 35, 17}; | ||
| ext_data.brake = brake_values[size_t(analog[0] * (sizeof(brake_values) - 1))]; | ||
| ext_data.power = power_values[size_t(analog[1] * (sizeof(power_values) - 1))]; | ||
|
|
||
| // Note: This currently assumes a little-endian host. | ||
| const u16 button_bitmasks[] = { | ||
| 0x0200, // Left | ||
| 0x0040, // Down | ||
| 0x0080, // Right | ||
| 0x0100, // Up | ||
| 0x2000, // A | ||
| 0x4000, // B | ||
| 0x1000, // C | ||
| 0x0800, // D | ||
| 0x0010, // Select | ||
| 0x0004, // Start | ||
| }; | ||
| m_buttons->GetState(&ext_data.buttons, button_bitmasks); | ||
| ext_data.buttons ^= 0xFFFF; | ||
| Common::BitCastPtr<DataFormat>(&m_reg.controller_data) = ext_data; | ||
|
|
||
| const auto lock = GetStateLock(); | ||
| m_led->controls[0]->control_ref->State(m_reg.identifier[1]); | ||
| } | ||
|
|
||
| void Shinkansen::Reset() | ||
| { | ||
| EncryptedExtension::Reset(); | ||
|
|
||
| m_reg = {}; | ||
| m_reg.identifier = shinkansen_id; | ||
| m_reg.calibration.fill(0xff); | ||
| } | ||
|
|
||
| ControllerEmu::ControlGroup* Shinkansen::GetGroup(ShinkansenGroup group) | ||
| { | ||
| switch (group) | ||
| { | ||
| case ShinkansenGroup::Levers: | ||
| return m_levers; | ||
| case ShinkansenGroup::Buttons: | ||
| return m_buttons; | ||
| case ShinkansenGroup::Light: | ||
| return m_led; | ||
| default: | ||
| ASSERT(false); | ||
| return nullptr; | ||
| } | ||
| } | ||
|
|
||
| } // namespace WiimoteEmu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| // Copyright 2022 Dolphin Emulator Project | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| #pragma once | ||
|
|
||
| #include "Core/HW/WiimoteEmu/Extension/Extension.h" | ||
|
|
||
| namespace ControllerEmu | ||
| { | ||
| class Buttons; | ||
| class ControlGroup; | ||
| class MixedTriggers; | ||
| } // namespace ControllerEmu | ||
|
|
||
| namespace WiimoteEmu | ||
| { | ||
| enum class ShinkansenGroup | ||
| { | ||
| Buttons, | ||
| Levers, | ||
| Light, | ||
| }; | ||
|
|
||
| class Shinkansen : public Extension3rdParty | ||
| { | ||
| public: | ||
| Shinkansen(); | ||
|
|
||
| void Update() override; | ||
| void Reset() override; | ||
| ControllerEmu::ControlGroup* GetGroup(ShinkansenGroup group); | ||
|
|
||
| private: | ||
| ControllerEmu::Buttons* m_buttons; | ||
| ControllerEmu::MixedTriggers* m_levers; | ||
| ControllerEmu::ControlGroup* m_led; | ||
|
|
||
| struct DataFormat | ||
| { | ||
| u8 unk0; | ||
| u8 unk1; | ||
| u8 brake; | ||
| u8 power; | ||
| u8 unk4; | ||
| u8 unk5; | ||
| u16 buttons; | ||
| }; | ||
| }; | ||
|
|
||
| } // namespace WiimoteEmu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -21,6 +21,7 @@ enum ExtensionNumber : u8 | ||
| UDRAW_TABLET, | ||
| DRAWSOME_TABLET, | ||
| TATACON, | ||
| SHINKANSEN, | ||
|
|
||
| MAX | ||
| }; | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters