src/platform/qt/SensorView.cpp (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "SensorView.h"
7
8#include "GameController.h"
9#include "GamepadAxisEvent.h"
10#include "InputController.h"
11
12using namespace QGBA;
13
14SensorView::SensorView(GameController* controller, InputController* input, QWidget* parent)
15 : QWidget(parent)
16 , m_controller(controller)
17 , m_input(input)
18 , m_rotation(input->rotationSource())
19 {
20 m_ui.setupUi(this);
21
22 connect(m_ui.lightSpin, SIGNAL(valueChanged(int)), this, SLOT(setLuminanceValue(int)));
23 connect(m_ui.lightSlide, SIGNAL(valueChanged(int)), this, SLOT(setLuminanceValue(int)));
24
25 connect(m_ui.timeNoOverride, SIGNAL(clicked()), controller, SLOT(setRealTime()));
26 connect(m_ui.timeFixed, &QRadioButton::clicked, [controller, this] () {
27 controller->setFixedTime(m_ui.time->dateTime());
28 });
29 connect(m_ui.timeFakeEpoch, &QRadioButton::clicked, [controller, this] () {
30 controller->setFakeEpoch(m_ui.time->dateTime());
31 });
32 connect(m_ui.time, &QDateTimeEdit::dateTimeChanged, [controller, this] (const QDateTime&) {
33 m_ui.timeButtons->checkedButton()->clicked();
34 });
35 connect(m_ui.timeNow, &QPushButton::clicked, [controller, this] () {
36 m_ui.time->setDateTime(QDateTime::currentDateTime());
37 });
38
39 connect(m_controller, SIGNAL(luminanceValueChanged(int)), this, SLOT(luminanceValueChanged(int)));
40
41 m_timer.setInterval(2);
42 connect(&m_timer, SIGNAL(timeout()), this, SLOT(updateSensors()));
43 if (!m_rotation || !m_rotation->readTiltX || !m_rotation->readTiltY) {
44 m_ui.tilt->hide();
45 } else {
46 m_timer.start();
47 }
48
49 if (!m_rotation || !m_rotation->readGyroZ) {
50 m_ui.gyro->hide();
51 } else {
52 m_timer.start();
53 }
54
55 jiggerer(m_ui.tiltSetX, &InputController::registerTiltAxisX);
56 jiggerer(m_ui.tiltSetY, &InputController::registerTiltAxisY);
57 jiggerer(m_ui.gyroSetX, &InputController::registerGyroAxisX);
58 jiggerer(m_ui.gyroSetY, &InputController::registerGyroAxisY);
59
60 m_ui.gyroSensitivity->setValue(m_input->gyroSensitivity() / 1e8f);
61 connect(m_ui.gyroSensitivity, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [this](double value) {
62 m_input->setGyroSensitivity(value * 1e8f);
63 });
64}
65
66void SensorView::jiggerer(QAbstractButton* button, void (InputController::*setter)(int)) {
67 connect(button, &QAbstractButton::toggled, [this, button, setter](bool checked) {
68 if (!checked) {
69 m_jiggered = nullptr;
70 } else {
71 m_jiggered = [this, button, setter](int axis) {
72 (m_input->*setter)(axis);
73 button->setChecked(false);
74 };
75 }
76 });
77 button->installEventFilter(this);
78}
79
80bool SensorView::eventFilter(QObject*, QEvent* event) {
81 if (event->type() == GamepadAxisEvent::Type()) {
82 GamepadAxisEvent* gae = static_cast<GamepadAxisEvent*>(event);
83 gae->accept();
84 if (m_jiggered && gae->direction() != GamepadAxisEvent::NEUTRAL && gae->isNew()) {
85 m_jiggered(gae->axis());
86 }
87 return true;
88 }
89 return false;
90}
91
92void SensorView::updateSensors() {
93 m_controller->threadInterrupt();
94 if (m_rotation->sample &&
95 (!m_controller->isLoaded() || !(m_controller->thread()->gba->memory.hw.devices & (HW_GYRO | HW_TILT)))) {
96 m_rotation->sample(m_rotation);
97 m_rotation->sample(m_rotation);
98 m_rotation->sample(m_rotation);
99 m_rotation->sample(m_rotation);
100 m_rotation->sample(m_rotation);
101 m_rotation->sample(m_rotation);
102 m_rotation->sample(m_rotation);
103 m_rotation->sample(m_rotation);
104 }
105 if (m_rotation->readTiltX && m_rotation->readTiltY) {
106 float x = m_rotation->readTiltX(m_rotation);
107 float y = m_rotation->readTiltY(m_rotation);
108 m_ui.tiltX->setValue(x / 469762048.0f); // TODO: Document this value (0xE0 << 21)
109 m_ui.tiltY->setValue(y / 469762048.0f);
110 }
111 if (m_rotation->readGyroZ) {
112 m_ui.gyroView->setValue(m_rotation->readGyroZ(m_rotation));
113 }
114 m_controller->threadContinue();
115}
116
117void SensorView::setLuminanceValue(int value) {
118 value = std::max(0, std::min(value, 255));
119 m_controller->setLuminanceValue(value);
120}
121
122void SensorView::luminanceValueChanged(int value) {
123 bool oldState;
124 oldState = m_ui.lightSpin->blockSignals(true);
125 m_ui.lightSpin->setValue(value);
126 m_ui.lightSpin->blockSignals(oldState);
127
128 oldState = m_ui.lightSlide->blockSignals(true);
129 m_ui.lightSlide->setValue(value);
130 m_ui.lightSlide->blockSignals(oldState);
131}