Untabified previous commits, Added preliminary binding support in citra_qt, renamed USER_INPUT to HID

This commit is contained in:
inspuration 2014-05-29 12:06:45 -04:00
parent daf2bace25
commit 5dc4223a62
22 changed files with 459 additions and 155 deletions

View file

@ -3,11 +3,13 @@
#include "common/common.h"
#include "bootmanager.hxx"
#include "key_bindings.hxx"
#include "core/core.h"
#include "core/loader.h"
#include "core/hw/hw.h"
#include "core/hw/user_input.h"
#include "core/hw/hid.h"
#include "video_core/video_core.h"
@ -203,23 +205,9 @@ void GRenderWindow::keyPressEvent(QKeyEvent* event)
*/
if (event->key() == Qt::Key_W)
{
buttonReg |= USER_INPUT::PAD_UP;
}
else if (event->key() == Qt::Key_A)
{
buttonReg |= USER_INPUT::PAD_LEFT;
}
else if (event->key() == Qt::Key_S)
{
buttonReg |= USER_INPUT::PAD_DOWN;
}
else if (event->key() == Qt::Key_D)
{
buttonReg |= USER_INPUT::PAD_RIGHT;
}
USER_INPUT::setButtonReg(buttonReg);
buttonReg |= GetKeyBinding(event);
HID::setButtonReg(buttonReg);
return;
}
void GRenderWindow::keyReleaseEvent(QKeyEvent* event)
@ -234,22 +222,6 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event)
QWidget::keyPressEvent(event);
*/
if (event->key() == Qt::Key_W)
{
buttonReg &= 0xffffffff ^ USER_INPUT::PAD_UP;
}
else if (event->key() == Qt::Key_A)
{
buttonReg &= 0xffffffff ^ USER_INPUT::PAD_LEFT;
}
else if (event->key() == Qt::Key_S)
{
buttonReg &= 0xffffffff ^ USER_INPUT::PAD_DOWN;
}
else if (event->key() == Qt::Key_D)
{
buttonReg &= 0xffffffff ^ USER_INPUT::PAD_RIGHT;
}
USER_INPUT::setButtonReg(buttonReg);
buttonReg &= 0xffffffff ^ GetKeyBinding(event);
HID::setButtonReg(buttonReg);
}

View file

@ -1,5 +1,6 @@
#include <QThread>
#include <QGLWidget>
#include <map>
#include "common/common.h"
#include "common/emu_window.h"

View file

@ -135,6 +135,7 @@
<ClCompile Include="debugger\ramview.cpp" />
<ClCompile Include="bootmanager.cpp" />
<ClCompile Include="hotkeys.cpp" />
<ClCompile Include="key_bindings.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
@ -148,6 +149,7 @@
<MOC Include="debugger\ramview.hxx" />
<MOC Include="bootmanager.hxx" />
<MOC Include="hotkeys.hxx" />
<MOC Include="key_bindings.hxx" />
<MOC Include="main.hxx" />
</ItemGroup>
<ItemGroup>
@ -173,6 +175,7 @@
<UIC Include="debugger\registers.ui" />
<UIC Include="debugger\disassembler.ui" />
<UIC Include="hotkeys.ui" />
<UIC Include="key_bindings.ui" />
<UIC Include="main.ui" />
</ItemGroup>
<ItemGroup>

View file

@ -45,6 +45,7 @@
<ClCompile Include="debugger\registers.cpp">
<Filter>debugger</Filter>
</ClCompile>
<ClCompile Include="key_bindings.cpp" />
</ItemGroup>
<ItemGroup>
<MOC Include="..\..\externals\qhexedit\commands.h">
@ -74,6 +75,7 @@
<MOC Include="debugger\registers.hxx">
<Filter>debugger</Filter>
</MOC>
<MOC Include="key_bindings.hxx" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="version.h" />
@ -102,6 +104,7 @@
<UIC Include="debugger\registers.ui">
<Filter>debugger</Filter>
</UIC>
<UIC Include="key_bindings.ui" />
</ItemGroup>
<ItemGroup>
<Text Include="CMakeLists.txt" />

View file

@ -0,0 +1,78 @@
#include <QKeySequence>
#include <QSettings>
#include <QKeyEvent>
#include "key_bindings.hxx"
#include <map>
#include "core/hw/hid.h"
typedef std::map<QKeySequence, HID::PAD> BindingsMap;
BindingsMap bindings;
std::map<HID::PAD, QString> nameMap;
void SaveKeyBindings(QSettings& settings)
{
settings.beginGroup("KeyBindings");
for (BindingsMap::iterator group = bindings.begin(); group != bindings.end(); ++group)
{
settings.setValue(group->first.toString(), group->second);
settings.endGroup();
}
settings.endGroup();
}
void LoadKeyBindings(QSettings& settings)
{
settings.beginGroup("KeyBindings");
// Make sure NOT to use a reference here because it would become invalid once we call beginGroup()
QStringList keys = settings.allKeys();
for (QList<QString>::iterator key = keys.begin(); key != keys.end(); ++key)
{
settings.beginGroup(*key);
QKeySequence keyseq = QKeySequence::fromString(settings.value("").toString());
}
settings.endGroup();
}
HID::PAD GetKeyBinding(QKeyEvent * event)
{
QKeySequence keySeq = QKeySequence(event->text());
return bindings[keySeq];
}
void RegisterKeyBinding(const QKeySequence keySeq, const HID::PAD pad)
{
bindings[keySeq] = pad;
}
void createNameMap() {
for (int i = 0; i < HID::numPadItems; i++){
nameMap[(HID::PAD)(1 << i)] = QString(HID::PAD_NAMES[i]);
}
}
GKeyBindingsDialog::GKeyBindingsDialog(QWidget* parent) : QDialog(parent)
{
ui.setupUi(this);
createNameMap();
for (BindingsMap::iterator key = bindings.begin(); key != bindings.end(); ++key)
{
QStringList columns;
columns << key->first.toString() << nameMap[key->second];
QTreeWidgetItem* item = new QTreeWidgetItem(columns);
ui.treeWidget->addTopLevelItem(item);
}
// TODO: Make context configurable as well (hiding the column for now)
ui.treeWidget->setColumnCount(2);
ui.treeWidget->resizeColumnToContents(0);
ui.treeWidget->resizeColumnToContents(1);
}

View file

@ -0,0 +1,50 @@
#include <QDialog>
#include "ui_key_bindings.h"
#include "core/hw/hid.h"
class QSettings;
/**
* Register a hotkey.
*
* @param key Keyboard button
* @param pad Name of the pad
*/
void RegisterKeyBinding(const QKeySequence keySeq, const HID::PAD pad);
/**
* Saves all key bindings to the settings file.
*
*
*/
void SaveKeyBindings(QSettings& settings);
/**
* Get PAD associated with key event
*
*
*/
HID::PAD GetKeyBinding(QKeyEvent * event);
/**
* Loads key bindings from the settings file.
*
*
*/
void LoadKeyBindings(QSettings& settings);
class GKeyBindingsDialog : public QDialog
{
Q_OBJECT
public:
GKeyBindingsDialog(QWidget* parent = NULL);
private:
Ui::key_bindings ui;
};

View file

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>key_bindings</class>
<widget class="QDialog" name="key_bindings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>363</width>
<height>388</height>
</rect>
</property>
<property name="windowTitle">
<string>Key Bindings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTreeWidget" name="treeWidget">
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectItems</enum>
</property>
<property name="headerHidden">
<bool>false</bool>
</property>
<column>
<property name="text">
<string>Action</string>
</property>
</column>
<column>
<property name="text">
<string>Key</string>
</property>
</column>
<column>
<property name="text">
<string>Pad</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>key_bindings</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>key_bindings</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -13,6 +13,7 @@
#include "bootmanager.hxx"
#include "hotkeys.hxx"
#include "key_bindings.hxx"
//debugger
#include "debugger/disassembler.hxx"
@ -80,7 +81,8 @@ GMainWindow::GMainWindow()
connect(ui.action_Pause, SIGNAL(triggered()), this, SLOT(OnPauseGame()));
connect(ui.action_Stop, SIGNAL(triggered()), this, SLOT(OnStopGame()));
connect(ui.action_Popout_Window_Mode, SIGNAL(triggered(bool)), this, SLOT(ToggleWindowMode()));
connect(ui.action_Hotkeys, SIGNAL(triggered()), this, SLOT(OnOpenHotkeysDialog()));
connect(ui.action_Hotkeys, SIGNAL(triggered()), this, SLOT(OnOpenHotkeysDialog()));\
connect(ui.action_Key_Bindings, SIGNAL(triggered()), this, SLOT(OnOpenKeyBindingsDialog()));
// BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views before the CPU continues
connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), disasmWidget, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection);
@ -95,6 +97,14 @@ GMainWindow::GMainWindow()
connect(GetHotkey("Main Window", "Load File", this), SIGNAL(activated()), this, SLOT(OnMenuLoadFile()));
connect(GetHotkey("Main Window", "Start Emulation", this), SIGNAL(activated()), this, SLOT(OnStartGame()));
// Setup key bindings
RegisterKeyBinding(QKeySequence("W"), HID::PAD::PAD_UP);
RegisterKeyBinding(QKeySequence("A"), HID::PAD::PAD_LEFT);
RegisterKeyBinding(QKeySequence("S"), HID::PAD::PAD_DOWN);
RegisterKeyBinding(QKeySequence("D"), HID::PAD::PAD_RIGHT);
LoadKeyBindings(settings);
setWindowTitle(render_window->GetWindowTitle().c_str());
show();
@ -187,6 +197,13 @@ void GMainWindow::OnOpenHotkeysDialog()
}
void GMainWindow::OnOpenKeyBindingsDialog()
{
GKeyBindingsDialog dialog(this);
dialog.exec();
}
void GMainWindow::ToggleWindowMode()
{
bool enable = ui.action_Popout_Window_Mode->isChecked();

View file

@ -39,6 +39,7 @@ private slots:
void OnMenuLoadFile();
void OnMenuLoadSymbolMap();
void OnOpenHotkeysDialog();
void OnOpenKeyBindingsDialog();
void OnConfigure();
void ToggleWindowMode();

View file

@ -53,6 +53,7 @@
<addaction name="action_Stop"/>
<addaction name="separator"/>
<addaction name="action_Configure"/>
<addaction name="action_Key_Bindings"/>
</widget>
<widget class="QMenu" name="menu_View">
<property name="title">
@ -127,6 +128,11 @@
<string>Configure &amp;Hotkeys ...</string>
</property>
</action>
<action name="action_Key_Bindings">
<property name="text">
<string>Set Key Bindings</string>
</property>
</action>
<action name="action_Configure">
<property name="text">
<string>Configure ...</string>

View file

@ -0,0 +1,77 @@
/********************************************************************************
** Form generated from reading UI file 'key_bindings.ui'
**
** Created by: Qt User Interface Compiler version 4.8.6
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_KEY_BINDINGS_H
#define UI_KEY_BINDINGS_H
#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QDialog>
#include <QtGui/QDialogButtonBox>
#include <QtGui/QHeaderView>
#include <QtGui/QTreeWidget>
#include <QtGui/QVBoxLayout>
QT_BEGIN_NAMESPACE
class Ui_key_bindings
{
public:
QVBoxLayout *verticalLayout;
QTreeWidget *treeWidget;
QDialogButtonBox *buttonBox;
void setupUi(QDialog *key_bindings)
{
if (key_bindings->objectName().isEmpty())
key_bindings->setObjectName(QString::fromUtf8("key_bindings"));
key_bindings->resize(363, 388);
verticalLayout = new QVBoxLayout(key_bindings);
verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
treeWidget = new QTreeWidget(key_bindings);
treeWidget->setObjectName(QString::fromUtf8("treeWidget"));
treeWidget->setSelectionBehavior(QAbstractItemView::SelectItems);
treeWidget->setHeaderHidden(false);
verticalLayout->addWidget(treeWidget);
buttonBox = new QDialogButtonBox(key_bindings);
buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset);
verticalLayout->addWidget(buttonBox);
retranslateUi(key_bindings);
QObject::connect(buttonBox, SIGNAL(accepted()), key_bindings, SLOT(accept()));
QObject::connect(buttonBox, SIGNAL(rejected()), key_bindings, SLOT(reject()));
QMetaObject::connectSlotsByName(key_bindings);
} // setupUi
void retranslateUi(QDialog *key_bindings)
{
key_bindings->setWindowTitle(QApplication::translate("key_bindings", "Key Bindings", 0, QApplication::UnicodeUTF8));
QTreeWidgetItem *___qtreewidgetitem = treeWidget->headerItem();
___qtreewidgetitem->setText(2, QApplication::translate("key_bindings", "Pad", 0, QApplication::UnicodeUTF8));
___qtreewidgetitem->setText(1, QApplication::translate("key_bindings", "Key", 0, QApplication::UnicodeUTF8));
___qtreewidgetitem->setText(0, QApplication::translate("key_bindings", "Action", 0, QApplication::UnicodeUTF8));
} // retranslateUi
};
namespace Ui {
class key_bindings: public Ui_key_bindings {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_KEY_BINDINGS_H

View file

@ -64,7 +64,7 @@ enum LOG_TYPE {
HW,
TIME,
NETPLAY,
USER_INPUT,
HID,
NUMBER_OF_LOGS // Must be last
};

View file

@ -73,7 +73,7 @@ LogManager::LogManager()
m_Log[LogTypes::ACTIONREPLAY] = new LogContainer("ActionReplay", "ActionReplay");
m_Log[LogTypes::MEMCARD_MANAGER] = new LogContainer("MemCard Manager", "MemCard Manager");
m_Log[LogTypes::NETPLAY] = new LogContainer("NETPLAY", "Netplay");
m_Log[LogTypes::USER_INPUT] = new LogContainer("USER_INPUT", "User Input");
m_Log[LogTypes::HID] = new LogContainer("HID", "Human Interface Devices");
m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX).c_str());
m_consoleLog = new ConsoleListener();

View file

@ -120,6 +120,7 @@
<FloatingPointModel>Fast</FloatingPointModel>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -180,7 +181,7 @@
<ClCompile Include="hw\hw.cpp" />
<ClCompile Include="hw\lcd.cpp" />
<ClCompile Include="hw\ndma.cpp" />
<ClCompile Include="hw\user_input.cpp" />
<ClCompile Include="hw\hid.cpp" />
<ClCompile Include="loader.cpp" />
<ClCompile Include="mem_map.cpp" />
<ClCompile Include="mem_map_funcs.cpp" />
@ -230,7 +231,7 @@
<ClInclude Include="hw\hw.h" />
<ClInclude Include="hw\lcd.h" />
<ClInclude Include="hw\ndma.h" />
<ClInclude Include="hw\user_input.h" />
<ClInclude Include="hw\hid.h" />
<ClInclude Include="loader.h" />
<ClInclude Include="mem_map.h" />
<ClInclude Include="system.h" />

View file

@ -165,7 +165,7 @@
<ClCompile Include="arm\interpreter\armcopro.cpp">
<Filter>arm\interpreter</Filter>
</ClCompile>
<ClCompile Include="hw\user_input.cpp">
<ClCompile Include="hw\hid.cpp">
<Filter>hw</Filter>
</ClCompile>
</ItemGroup>
@ -298,7 +298,7 @@
<ClInclude Include="hle\kernel\mutex.h">
<Filter>hle\kernel</Filter>
</ClInclude>
<ClInclude Include="hw\user_input.h">
<ClInclude Include="hw\hid.h">
<Filter>hw</Filter>
</ClInclude>
</ItemGroup>

34
src/core/hw/hid.cpp Normal file
View file

@ -0,0 +1,34 @@
#include "hid.h"
namespace HID {
template <typename T>
inline void Read(T &var, const u32 addr) {
ERROR_LOG(HID, "unknown Read%d @ 0x%08X", sizeof(var) * 8, addr);
}
template <typename T>
inline void Write(u32 addr, const T data) {
ERROR_LOG(HID, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, data, addr);
}
void setButtonReg(u32 buttonData) {
Memory::Write32(PADDR_BUTTONS, buttonData);
}
/// Update hardware
void Update() {
}
/// Initialize hardware
void Init() {
NOTICE_LOG(HID, "initialized OK");
}
/// Shutdown hardware
void Shutdown() {
NOTICE_LOG(HID, "shutdown OK");
}
}

73
src/core/hw/hid.h Normal file
View file

@ -0,0 +1,73 @@
#pragma once
#include "common/common_types.h"
#include "core\mem_map.h"
namespace HID {
struct Registers {
u32 buttons;
//u32 pad1; etc...
};
extern Registers g_regs;
enum {
PADDR_BUTTONS = 0x1000001c, //TODO: it works using the shared mem mapping with all homebrew tested, however the wiki states 0x10146000 as the paddr
};
enum {
REG_BUTTONS = 0x1EC46000 //does not work due to confusion between shared mem and hardware IO
};
const int numPadItems = 12; // figure out a better way :(
enum PAD {
PAD_A = (1 << 0),
PAD_B = (1 << 1),
PAD_SELECT = (1 << 2),
PAD_START = (1 << 3),
PAD_RIGHT = (1 << 4),
PAD_LEFT = (1 << 5),
PAD_UP = (1 << 6),
PAD_DOWN = (1 << 7),
PAD_R = (1 << 8),
PAD_L = (1 << 9),
PAD_X = (1 << 10),
PAD_Y = (1 << 11),
};
char * const PAD_NAMES[] = {
"PAD_A",
"PAD_B",
"PAD_SELECT",
"PAD_START",
"PAD_RIGHT",
"PAD_LEFT",
"PAD_UP",
"PAD_DOWN",
"PAD_R",
"PAD_L",
"PAD_X",
"PAD_Y"
};
template <typename T>
inline void Read(T &var, const u32 addr);
template <typename T>
inline void Write(u32 addr, const T data);
void setButtonReg(u32 buttonData);
/// Update hardware
void Update();
/// Initialize hardware
void Init();
/// Shutdown hardware
void Shutdown();
}

View file

@ -8,7 +8,7 @@
#include "core/hw/hw.h"
#include "core/hw/lcd.h"
#include "core/hw/ndma.h"
#include "core/hw/user_input.h"
#include "core/hw/hid.h"
namespace HW {
@ -91,14 +91,14 @@ template void Write<u8>(u32 addr, const u8 data);
void Update() {
LCD::Update();
NDMA::Update();
USER_INPUT::Update();
HID::Update();
}
/// Initialize hardware
void Init() {
LCD::Init();
NDMA::Init();
USER_INPUT::Init();
HID::Init();
NOTICE_LOG(HW, "initialized OK");
}

View file

@ -1,46 +0,0 @@
#include "user_input.h"
namespace USER_INPUT {
template <typename T>
inline void Read(T &var, const u32 addr) {
ERROR_LOG(USER_INPUT, "unknown Read%d @ 0x%08X", sizeof(var) * 8, addr);
}
template <typename T>
inline void Write(u32 addr, const T data) {
ERROR_LOG(USER_INPUT, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, data, addr);
}
// Explicitly instantiate template functions because we aren't defining this in the header:
template void Read<u64>(u64 &var, const u32 addr);
template void Read<u32>(u32 &var, const u32 addr);
template void Read<u16>(u16 &var, const u32 addr);
template void Read<u8>(u8 &var, const u32 addr);
template void Write<u64>(u32 addr, const u64 data);
template void Write<u32>(u32 addr, const u32 data);
template void Write<u16>(u32 addr, const u16 data);
template void Write<u8>(u32 addr, const u8 data);
void setButtonReg(u32 buttonData) {
Memory::Write32(PADDR_BUTTONS, buttonData);
}
/// Update hardware
void Update() {
}
/// Initialize hardware
void Init() {
NOTICE_LOG(USER_INPUT, "initialized OK");
}
/// Shutdown hardware
void Shutdown() {
NOTICE_LOG(USER_INPUT, "shutdown OK");
}
}

View file

@ -1,55 +0,0 @@
#pragma once
#include "common/common_types.h"
#include "core\mem_map.h"
namespace USER_INPUT {
struct Registers {
u32 buttons;
//u32 pad1; etc...
};
extern Registers g_regs;
enum {
PAD_A = (1 << 0),
PAD_B = (1 << 1),
PAD_SELECT = (1 << 2),
PAD_START = (1 << 3),
PAD_RIGHT = (1 << 4),
PAD_LEFT = (1 << 5),
PAD_UP = (1 << 6),
PAD_DOWN = (1 << 7),
PAD_R = (1 << 8),
PAD_L = (1 << 9),
PAD_X = (1 << 10),
PAD_Y = (1 << 11),
PADDR_BUTTONS = 0x1000001c, //TODO: it works using the shared mem mapping with all homebrew tested, however the wiki states 0x10146000 as the paddr
};
enum {
REG_BUTTONS = 0x1EC46000 //does not work due to confusion between shared mem and hardware IO
};
template <typename T>
inline void Read(T &var, const u32 addr);
template <typename T>
inline void Write(u32 addr, const T data);
void setButtonReg(u32 buttonData);
/// Update hardware
void Update();
/// Initialize hardware
void Init();
/// Shutdown hardware
void Shutdown();
}