diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index 3ca82051a7..4a9a0e7b74 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -144,6 +144,7 @@ add_library(core
HW/WiimoteEmu/MotionPlus.cpp
HW/WiimoteEmu/Speaker.cpp
HW/WiimoteEmu/Extension/Classic.cpp
+ HW/WiimoteEmu/Extension/DrawsomeTablet.cpp
HW/WiimoteEmu/Extension/Extension.cpp
HW/WiimoteEmu/Extension/Nunchuk.cpp
HW/WiimoteEmu/Extension/Drums.cpp
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index b12485dafc..82709080f4 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -178,6 +178,7 @@
+
@@ -448,6 +449,7 @@
+
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index 2420db532a..62091ccacd 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -895,6 +895,9 @@
HW %28Flipper/Hollywood%29\Wiimote\Emu\Extension
+
+ HW %28Flipper/Hollywood%29\Wiimote\Emu\Extension
+
HW %28Flipper/Hollywood%29\Wiimote\Emu\Extension
@@ -1616,6 +1619,9 @@
HW %28Flipper/Hollywood%29\Wiimote\Emu\Extension
+
+ HW %28Flipper/Hollywood%29\Wiimote\Emu\Extension
+
HW %28Flipper/Hollywood%29\Wiimote\Emu\Extension
diff --git a/Source/Core/Core/HW/Wiimote.cpp b/Source/Core/Core/HW/Wiimote.cpp
index 5d6f1a2286..95fe6f122b 100644
--- a/Source/Core/Core/HW/Wiimote.cpp
+++ b/Source/Core/Core/HW/Wiimote.cpp
@@ -72,6 +72,13 @@ ControllerEmu::ControlGroup* GetUDrawTabletGroup(int number, WiimoteEmu::UDrawTa
->GetUDrawTabletGroup(group);
}
+ControllerEmu::ControlGroup* GetDrawsomeTabletGroup(int number,
+ WiimoteEmu::DrawsomeTabletGroup group)
+{
+ return static_cast(s_config.GetController(number))
+ ->GetDrawsomeTabletGroup(group);
+}
+
ControllerEmu::ControlGroup* GetTaTaConGroup(int number, WiimoteEmu::TaTaConGroup group)
{
return static_cast(s_config.GetController(number))->GetTaTaConGroup(group);
diff --git a/Source/Core/Core/HW/Wiimote.h b/Source/Core/Core/HW/Wiimote.h
index af87e0e0c7..0d23637563 100644
--- a/Source/Core/Core/HW/Wiimote.h
+++ b/Source/Core/Core/HW/Wiimote.h
@@ -27,6 +27,7 @@ enum class GuitarGroup;
enum class DrumsGroup;
enum class TurntableGroup;
enum class UDrawTabletGroup;
+enum class DrawsomeTabletGroup;
enum class TaTaConGroup;
} // namespace WiimoteEmu
@@ -81,6 +82,8 @@ ControllerEmu::ControlGroup* GetGuitarGroup(int number, WiimoteEmu::GuitarGroup
ControllerEmu::ControlGroup* GetDrumsGroup(int number, WiimoteEmu::DrumsGroup group);
ControllerEmu::ControlGroup* GetTurntableGroup(int number, WiimoteEmu::TurntableGroup group);
ControllerEmu::ControlGroup* GetUDrawTabletGroup(int number, WiimoteEmu::UDrawTabletGroup group);
+ControllerEmu::ControlGroup* GetDrawsomeTabletGroup(int number,
+ WiimoteEmu::DrawsomeTabletGroup group);
ControllerEmu::ControlGroup* GetTaTaConGroup(int number, WiimoteEmu::TaTaConGroup group);
void ControlChannel(int number, u16 channel_id, const void* data, u32 size);
diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.cpp b/Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.cpp
new file mode 100644
index 0000000000..eb1eb77d56
--- /dev/null
+++ b/Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.cpp
@@ -0,0 +1,116 @@
+// Copyright 2019 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "Core/HW/WiimoteEmu/Extension/DrawsomeTablet.h"
+
+#include
+#include
+
+#include "Common/BitUtils.h"
+#include "Common/Common.h"
+#include "Common/CommonTypes.h"
+#include "Core/HW/WiimoteEmu/WiimoteEmu.h"
+
+#include "InputCommon/ControllerEmu/Control/Input.h"
+#include "InputCommon/ControllerEmu/ControlGroup/AnalogStick.h"
+#include "InputCommon/ControllerEmu/ControlGroup/Triggers.h"
+
+namespace WiimoteEmu
+{
+constexpr std::array drawsome_tablet_id{{0xff, 0x00, 0xa4, 0x20, 0x00, 0x13}};
+
+// i18n: The "Drawsome" (combination of "Draw" and "Awesome") tablet wiimote extension by Ubisoft.
+DrawsomeTablet::DrawsomeTablet() : Extension3rdParty("Drawsome", _trans("Drawsome Tablet"))
+{
+ // Stylus
+ groups.emplace_back(m_stylus = new ControllerEmu::AnalogStick(
+ _trans("Stylus"), std::make_unique(1.0)));
+
+ // Touch
+ groups.emplace_back(m_touch = new ControllerEmu::Triggers(_trans("Touch")));
+ m_touch->controls.emplace_back(
+ new ControllerEmu::Input(ControllerEmu::Translate, _trans("Pressure")));
+}
+
+void DrawsomeTablet::Update()
+{
+ DataFormat tablet_data = {};
+
+ // Stylus X/Y (calibrated values):
+ constexpr u16 MIN_X = 0x0000;
+ constexpr u16 MAX_X = 0x27ff;
+ // Note: While 0x15ff seems to be the ideal calibrated value,
+ // the "Drawsome" game expects you to go "off screen" a bit to access some menu items.
+ constexpr u16 MIN_Y = 0x15ff + 0x100;
+ constexpr u16 MAX_Y = 0x00;
+ constexpr double CENTER_X = (MAX_X + MIN_X) / 2.0;
+ constexpr double CENTER_Y = (MAX_Y + MIN_Y) / 2.0;
+
+ const auto stylus_state = m_stylus->GetState();
+ const auto stylus_x = u16(std::lround(CENTER_X + stylus_state.x * (MAX_X - CENTER_X)));
+ const auto stylus_y = u16(std::lround(CENTER_Y + stylus_state.y * (MAX_Y - CENTER_Y)));
+
+ tablet_data.stylus_x1 = u8(stylus_x);
+ tablet_data.stylus_x2 = u8(stylus_x >> 8);
+
+ tablet_data.stylus_y1 = u8(stylus_y);
+ tablet_data.stylus_y2 = u8(stylus_y >> 8);
+
+ // TODO: Expose the lifted stylus state in the UI.
+ // Note: Pen X/Y holds the last value when the pen is lifted.
+ const bool is_stylus_lifted = false;
+
+ constexpr u8 NEUTRAL_STATUS = 0x8;
+ constexpr u8 PEN_LIFTED_BIT = 0x10;
+
+ u8 status = NEUTRAL_STATUS;
+
+ if (is_stylus_lifted)
+ status |= PEN_LIFTED_BIT;
+
+ tablet_data.status = status;
+
+ // Pressure (0 - 0x7ff):
+ constexpr u16 MAX_PRESSURE = 0x7ff;
+
+ const auto touch_state = m_touch->GetState();
+ const auto pressure = u16(std::lround(touch_state.data[0] * MAX_PRESSURE));
+
+ tablet_data.pressure1 = u8(pressure);
+ tablet_data.pressure2 = u8(pressure >> 8);
+
+ Common::BitCastPtr(&m_reg.controller_data) = tablet_data;
+}
+
+void DrawsomeTablet::Reset()
+{
+ EncryptedExtension::Reset();
+
+ m_reg.identifier = drawsome_tablet_id;
+
+ // Assuming calibration data is 0xff filled.
+ m_reg.calibration.fill(0xff);
+}
+
+bool DrawsomeTablet::IsButtonPressed() const
+{
+ // Device has no buttons.
+ return false;
+}
+
+ControllerEmu::ControlGroup* DrawsomeTablet::GetGroup(DrawsomeTabletGroup group)
+{
+ switch (group)
+ {
+ case DrawsomeTabletGroup::Stylus:
+ return m_stylus;
+ case DrawsomeTabletGroup::Touch:
+ return m_touch;
+ default:
+ assert(false);
+ return nullptr;
+ }
+}
+
+} // namespace WiimoteEmu
diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.h b/Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.h
new file mode 100644
index 0000000000..32b38d2d16
--- /dev/null
+++ b/Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.h
@@ -0,0 +1,61 @@
+// Copyright 2019 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "Common/BitField.h"
+#include "Common/Swap.h"
+#include "Core/HW/WiimoteEmu/Extension/Extension.h"
+
+namespace ControllerEmu
+{
+class AnalogStick;
+class Triggers;
+class ControlGroup;
+} // namespace ControllerEmu
+
+namespace WiimoteEmu
+{
+enum class DrawsomeTabletGroup
+{
+ Stylus,
+ Touch,
+};
+
+class DrawsomeTablet : public Extension3rdParty
+{
+public:
+ DrawsomeTablet();
+
+ void Update() override;
+ bool IsButtonPressed() const override;
+ void Reset() override;
+
+ ControllerEmu::ControlGroup* GetGroup(DrawsomeTabletGroup group);
+
+ struct DataFormat
+ {
+ // Pen X/Y is little endian.
+ u8 stylus_x1;
+ u8 stylus_x2;
+
+ u8 stylus_y1;
+ u8 stylus_y2;
+
+ u8 pressure1;
+
+ union
+ {
+ BitField<0, 3, u8> pressure2;
+ BitField<3, 5, u8> status;
+ };
+ };
+
+ static_assert(6 == sizeof(DataFormat), "Wrong size.");
+
+private:
+ ControllerEmu::AnalogStick* m_stylus;
+ ControllerEmu::Triggers* m_touch;
+};
+} // namespace WiimoteEmu
diff --git a/Source/Core/Core/HW/WiimoteEmu/ExtensionPort.h b/Source/Core/Core/HW/WiimoteEmu/ExtensionPort.h
index 7f4f5c979c..3a266bcc07 100644
--- a/Source/Core/Core/HW/WiimoteEmu/ExtensionPort.h
+++ b/Source/Core/Core/HW/WiimoteEmu/ExtensionPort.h
@@ -20,6 +20,7 @@ enum ExtensionNumber : u8
DRUMS,
TURNTABLE,
UDRAW_TABLET,
+ DRAWSOME_TABLET,
TATACON,
};
diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp
index f8034901a2..87f64e14bf 100644
--- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp
+++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp
@@ -26,6 +26,7 @@
#include "Core/HW/WiimoteCommon/WiimoteConstants.h"
#include "Core/HW/WiimoteCommon/WiimoteHid.h"
#include "Core/HW/WiimoteEmu/Extension/Classic.h"
+#include "Core/HW/WiimoteEmu/Extension/DrawsomeTablet.h"
#include "Core/HW/WiimoteEmu/Extension/Drums.h"
#include "Core/HW/WiimoteEmu/Extension/Guitar.h"
#include "Core/HW/WiimoteEmu/Extension/Nunchuk.h"
@@ -168,6 +169,7 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index)
m_attachments->AddAttachment(std::make_unique());
m_attachments->AddAttachment(std::make_unique());
m_attachments->AddAttachment(std::make_unique());
+ m_attachments->AddAttachment(std::make_unique());
m_attachments->AddAttachment(std::make_unique());
m_attachments->AddSetting(&m_motion_plus_setting, {_trans("Attach MotionPlus")}, true);
@@ -293,7 +295,13 @@ ControllerEmu::ControlGroup* Wiimote::GetUDrawTabletGroup(UDrawTabletGroup group
return static_cast(
m_attachments->GetAttachmentList()[ExtensionNumber::UDRAW_TABLET].get())
->GetGroup(group);
- ;
+}
+
+ControllerEmu::ControlGroup* Wiimote::GetDrawsomeTabletGroup(DrawsomeTabletGroup group)
+{
+ return static_cast(
+ m_attachments->GetAttachmentList()[ExtensionNumber::DRAWSOME_TABLET].get())
+ ->GetGroup(group);
}
ControllerEmu::ControlGroup* Wiimote::GetTaTaConGroup(TaTaConGroup group)
diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h
index 495a25ce0a..d90bc65d64 100644
--- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h
+++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h
@@ -56,6 +56,7 @@ enum class GuitarGroup;
enum class DrumsGroup;
enum class TurntableGroup;
enum class UDrawTabletGroup;
+enum class DrawsomeTabletGroup;
enum class TaTaConGroup;
template
@@ -116,6 +117,7 @@ public:
ControllerEmu::ControlGroup* GetDrumsGroup(DrumsGroup group);
ControllerEmu::ControlGroup* GetTurntableGroup(TurntableGroup group);
ControllerEmu::ControlGroup* GetUDrawTabletGroup(UDrawTabletGroup group);
+ ControllerEmu::ControlGroup* GetDrawsomeTabletGroup(DrawsomeTabletGroup group);
ControllerEmu::ControlGroup* GetTaTaConGroup(TaTaConGroup group);
void Update();
diff --git a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp
index 7d68d7da27..27a94ed5b5 100644
--- a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp
+++ b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp
@@ -11,6 +11,7 @@
#include "Core/HW/Wiimote.h"
#include "Core/HW/WiimoteEmu/Extension/Classic.h"
+#include "Core/HW/WiimoteEmu/Extension/DrawsomeTablet.h"
#include "Core/HW/WiimoteEmu/Extension/Drums.h"
#include "Core/HW/WiimoteEmu/Extension/Guitar.h"
#include "Core/HW/WiimoteEmu/Extension/Nunchuk.h"
@@ -30,6 +31,7 @@ WiimoteEmuExtension::WiimoteEmuExtension(MappingWindow* window) : MappingWidget(
CreateNunchukLayout();
CreateTurntableLayout();
CreateUDrawTabletLayout();
+ CreateDrawsomeTabletLayout();
CreateTaTaConLayout();
CreateMainLayout();
@@ -203,6 +205,22 @@ void WiimoteEmuExtension::CreateUDrawTabletLayout()
m_udraw_tablet_box->setLayout(hbox);
}
+void WiimoteEmuExtension::CreateDrawsomeTabletLayout()
+{
+ const auto hbox = new QHBoxLayout();
+ m_drawsome_tablet_box = new QGroupBox(tr("Drawsome Tablet"), this);
+
+ hbox->addWidget(CreateGroupBox(
+ tr("Stylus"),
+ Wiimote::GetDrawsomeTabletGroup(GetPort(), WiimoteEmu::DrawsomeTabletGroup::Stylus)));
+
+ hbox->addWidget(CreateGroupBox(
+ tr("Touch"),
+ Wiimote::GetDrawsomeTabletGroup(GetPort(), WiimoteEmu::DrawsomeTabletGroup::Touch)));
+
+ m_drawsome_tablet_box->setLayout(hbox);
+}
+
void WiimoteEmuExtension::CreateTaTaConLayout()
{
auto* hbox = new QHBoxLayout();
@@ -227,6 +245,7 @@ void WiimoteEmuExtension::CreateMainLayout()
m_main_layout->addWidget(m_nunchuk_box);
m_main_layout->addWidget(m_turntable_box);
m_main_layout->addWidget(m_udraw_tablet_box);
+ m_main_layout->addWidget(m_drawsome_tablet_box);
m_main_layout->addWidget(m_tatacon_box);
setLayout(m_main_layout);
@@ -258,5 +277,6 @@ void WiimoteEmuExtension::ChangeExtensionType(u32 type)
m_drums_box->setHidden(type != ExtensionNumber::DRUMS);
m_turntable_box->setHidden(type != ExtensionNumber::TURNTABLE);
m_udraw_tablet_box->setHidden(type != ExtensionNumber::UDRAW_TABLET);
+ m_drawsome_tablet_box->setHidden(type != ExtensionNumber::DRAWSOME_TABLET);
m_tatacon_box->setHidden(type != ExtensionNumber::TATACON);
}
diff --git a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.h b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.h
index b1c97339b3..dec935aae7 100644
--- a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.h
+++ b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.h
@@ -32,6 +32,7 @@ private:
void CreateNunchukLayout();
void CreateTurntableLayout();
void CreateUDrawTabletLayout();
+ void CreateDrawsomeTabletLayout();
void CreateTaTaConLayout();
void CreateMainLayout();
@@ -44,5 +45,6 @@ private:
QGroupBox* m_nunchuk_box;
QGroupBox* m_turntable_box;
QGroupBox* m_udraw_tablet_box;
+ QGroupBox* m_drawsome_tablet_box;
QGroupBox* m_tatacon_box;
};