all repos — mgba @ 74ac89a584b068b9d9c02e5117eddbe6da22d9c5

mGBA Game Boy Advance Emulator

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}