diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 8c5451c08..ba8a71bbf 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -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" @@ -121,7 +123,7 @@ GRenderWindow::GRenderWindow(QWidget* parent) : QWidget(parent), emu_thread(this BackupGeometry(); - buttonReg = 0x0; + buttonReg = 0x0; } GRenderWindow::~GRenderWindow() @@ -195,31 +197,17 @@ void GRenderWindow::keyPressEvent(QKeyEvent* event) /* bool key_processed = false; for (unsigned int channel = 0; channel < 4 && controller_interface(); ++channel) - if (controller_interface()->SetControllerStatus(channel, event->key(), input_common::GCController::PRESSED)) - key_processed = true; + if (controller_interface()->SetControllerStatus(channel, event->key(), input_common::GCController::PRESSED)) + key_processed = true; if (!key_processed) - QWidget::keyPressEvent(event); + QWidget::keyPressEvent(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); } \ No newline at end of file diff --git a/src/citra_qt/bootmanager.hxx b/src/citra_qt/bootmanager.hxx index efbed6b7c..84216cf2a 100644 --- a/src/citra_qt/bootmanager.hxx +++ b/src/citra_qt/bootmanager.hxx @@ -1,5 +1,6 @@ #include #include +#include #include "common/common.h" #include "common/emu_window.h" @@ -110,5 +111,5 @@ private: QByteArray geometry; - u32 buttonReg; + u32 buttonReg; }; diff --git a/src/citra_qt/citra_qt.vcxproj b/src/citra_qt/citra_qt.vcxproj index 3f24bbfbf..c841bab3e 100644 --- a/src/citra_qt/citra_qt.vcxproj +++ b/src/citra_qt/citra_qt.vcxproj @@ -135,6 +135,7 @@ + @@ -148,6 +149,7 @@ + @@ -173,6 +175,7 @@ + diff --git a/src/citra_qt/citra_qt.vcxproj.filters b/src/citra_qt/citra_qt.vcxproj.filters index 2b3838e29..7d4e365a4 100644 --- a/src/citra_qt/citra_qt.vcxproj.filters +++ b/src/citra_qt/citra_qt.vcxproj.filters @@ -45,6 +45,7 @@ debugger + @@ -74,6 +75,7 @@ debugger + @@ -102,6 +104,7 @@ debugger + diff --git a/src/citra_qt/key_bindings.cpp b/src/citra_qt/key_bindings.cpp new file mode 100644 index 000000000..6cd0db86d --- /dev/null +++ b/src/citra_qt/key_bindings.cpp @@ -0,0 +1,78 @@ +#include +#include +#include +#include "key_bindings.hxx" +#include +#include "core/hw/hid.h" + +typedef std::map BindingsMap; + +BindingsMap bindings; + +std::map 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::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); +} diff --git a/src/citra_qt/key_bindings.hxx b/src/citra_qt/key_bindings.hxx new file mode 100644 index 000000000..166bca245 --- /dev/null +++ b/src/citra_qt/key_bindings.hxx @@ -0,0 +1,50 @@ +#include +#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; +}; diff --git a/src/citra_qt/key_bindings.ui b/src/citra_qt/key_bindings.ui new file mode 100644 index 000000000..0b97ec7d7 --- /dev/null +++ b/src/citra_qt/key_bindings.ui @@ -0,0 +1,89 @@ + + + key_bindings + + + + 0 + 0 + 363 + 388 + + + + Key Bindings + + + + + + QAbstractItemView::SelectItems + + + false + + + + Action + + + + + Key + + + + + Pad + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset + + + + + + + + + buttonBox + accepted() + key_bindings + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + key_bindings + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 9be982909..556e9015a 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -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(); diff --git a/src/citra_qt/main.hxx b/src/citra_qt/main.hxx index fa122f76e..f6a5043c5 100644 --- a/src/citra_qt/main.hxx +++ b/src/citra_qt/main.hxx @@ -39,6 +39,7 @@ private slots: void OnMenuLoadFile(); void OnMenuLoadSymbolMap(); void OnOpenHotkeysDialog(); + void OnOpenKeyBindingsDialog(); void OnConfigure(); void ToggleWindowMode(); diff --git a/src/citra_qt/main.ui b/src/citra_qt/main.ui index f3596716f..52372ed8f 100644 --- a/src/citra_qt/main.ui +++ b/src/citra_qt/main.ui @@ -53,6 +53,7 @@ + @@ -127,6 +128,11 @@ Configure &Hotkeys ... + + + Set Key Bindings + + Configure ... diff --git a/src/citra_qt/ui_key_bindings.h b/src/citra_qt/ui_key_bindings.h new file mode 100644 index 000000000..7e1a88946 --- /dev/null +++ b/src/citra_qt/ui_key_bindings.h @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include + +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 diff --git a/src/common/log.h b/src/common/log.h index 4d35e2c8f..691a4fba3 100644 --- a/src/common/log.h +++ b/src/common/log.h @@ -64,7 +64,7 @@ enum LOG_TYPE { HW, TIME, NETPLAY, - USER_INPUT, + HID, NUMBER_OF_LOGS // Must be last }; diff --git a/src/common/log_manager.cpp b/src/common/log_manager.cpp index 17ca9b08b..5b2ef874f 100644 --- a/src/common/log_manager.cpp +++ b/src/common/log_manager.cpp @@ -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(); diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj index 2f964bc9e..ef621b1e8 100644 --- a/src/core/core.vcxproj +++ b/src/core/core.vcxproj @@ -120,6 +120,7 @@ Fast false StreamingSIMDExtensions2 + $(IntDir)%(RelativeDir) @@ -180,7 +181,7 @@ - + @@ -230,7 +231,7 @@ - + diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters index f56264b50..3cf702d44 100644 --- a/src/core/core.vcxproj.filters +++ b/src/core/core.vcxproj.filters @@ -165,7 +165,7 @@ arm\interpreter - + hw @@ -298,7 +298,7 @@ hle\kernel - + hw diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h index fa690ef92..87d397448 100644 --- a/src/core/hle/function_wrappers.h +++ b/src/core/hle/function_wrappers.h @@ -748,5 +748,5 @@ template void WrapI_VVUUS64() { //64 bit wrappers template void WrapU64_V() { - RETURN(func()); + RETURN(func()); } \ No newline at end of file diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 094e003c4..870e87e17 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -227,7 +227,7 @@ Result CreateEvent(void* _event, u32 reset_type) { } u64 GetSystemTick(void) { - return Core::g_sys_core->GetTicks(); + return Core::g_sys_core->GetTicks(); } const HLE::FunctionDef SVC_Table[] = { @@ -271,7 +271,7 @@ const HLE::FunctionDef SVC_Table[] = { {0x25, WrapI_VVUUS64, "WaitSynchronizationN"}, {0x26, NULL, "SignalAndWait"}, {0x27, NULL, "DuplicateHandle"}, - { 0x28, WrapU64_V, "GetSystemTick" }, + { 0x28, WrapU64_V, "GetSystemTick" }, {0x29, NULL, "GetHandleInfo"}, {0x2A, NULL, "GetSystemInfo"}, {0x2B, NULL, "GetProcessInfo"}, diff --git a/src/core/hw/hid.cpp b/src/core/hw/hid.cpp new file mode 100644 index 000000000..9f4867e31 --- /dev/null +++ b/src/core/hw/hid.cpp @@ -0,0 +1,34 @@ +#include "hid.h" + + +namespace HID { + + template + inline void Read(T &var, const u32 addr) { + ERROR_LOG(HID, "unknown Read%d @ 0x%08X", sizeof(var) * 8, addr); + } + + template + 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"); + } + +} \ No newline at end of file diff --git a/src/core/hw/hid.h b/src/core/hw/hid.h new file mode 100644 index 000000000..524b48cca --- /dev/null +++ b/src/core/hw/hid.h @@ -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 + inline void Read(T &var, const u32 addr); + + template + inline void Write(u32 addr, const T data); + + void setButtonReg(u32 buttonData); + + /// Update hardware + void Update(); + + /// Initialize hardware + void Init(); + + /// Shutdown hardware + void Shutdown(); +} + diff --git a/src/core/hw/hw.cpp b/src/core/hw/hw.cpp index 9b4fcf0cb..6c809f755 100644 --- a/src/core/hw/hw.cpp +++ b/src/core/hw/hw.cpp @@ -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(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"); } diff --git a/src/core/hw/user_input.cpp b/src/core/hw/user_input.cpp deleted file mode 100644 index 5cc5c4479..000000000 --- a/src/core/hw/user_input.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "user_input.h" - - -namespace USER_INPUT { - - template - inline void Read(T &var, const u32 addr) { - ERROR_LOG(USER_INPUT, "unknown Read%d @ 0x%08X", sizeof(var) * 8, addr); - } - - template - 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 &var, const u32 addr); - template void Read(u32 &var, const u32 addr); - template void Read(u16 &var, const u32 addr); - template void Read(u8 &var, const u32 addr); - - template void Write(u32 addr, const u64 data); - template void Write(u32 addr, const u32 data); - template void Write(u32 addr, const u16 data); - template void Write(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"); - } - -} \ No newline at end of file diff --git a/src/core/hw/user_input.h b/src/core/hw/user_input.h deleted file mode 100644 index b21da5815..000000000 --- a/src/core/hw/user_input.h +++ /dev/null @@ -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 - inline void Read(T &var, const u32 addr); - - template - inline void Write(u32 addr, const T data); - - void setButtonReg(u32 buttonData); - - /// Update hardware - void Update(); - - /// Initialize hardware - void Init(); - - /// Shutdown hardware - void Shutdown(); -} -