got rid of 'src' folders in each sub-project
This commit is contained in:
parent
03c245345e
commit
63e46abdb8
148 changed files with 0 additions and 0 deletions
71
src/citra/citra.cpp
Normal file
71
src/citra/citra.cpp
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* Copyright (C) 2013 citra Emulator
|
||||
*
|
||||
* @file citra.cpp
|
||||
* @author ShizZy <shizzy247@gmail.com>
|
||||
* @date 2013-09-04
|
||||
* @brief Main entry point
|
||||
*
|
||||
* @section LICENSE
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details at
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* Official project repository can be found at:
|
||||
* http://code.google.com/p/gekko-gc-emu/
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "log_manager.h"
|
||||
#include "file_util.h"
|
||||
|
||||
#include "system.h"
|
||||
#include "core.h"
|
||||
#include "loader.h"
|
||||
|
||||
#include "emu_window/emu_window_glfw.h"
|
||||
|
||||
#include "citra.h"
|
||||
|
||||
#define E_ERR -1
|
||||
|
||||
//#define PLAY_FIFO_RECORDING
|
||||
|
||||
/// Application entry point
|
||||
int __cdecl main(int argc, char **argv) {
|
||||
//u32 tight_loop;
|
||||
|
||||
printf("citra starting...\n");
|
||||
|
||||
std::string program_dir = File::GetCurrentDir();
|
||||
|
||||
LogManager::Init();
|
||||
|
||||
EmuWindow_GLFW* emu_window = new EmuWindow_GLFW;
|
||||
|
||||
System::Init(emu_window);
|
||||
|
||||
std::string boot_filename = "homebrew.elf";
|
||||
std::string error_str;
|
||||
|
||||
bool res = Loader::LoadFile(boot_filename, &error_str);
|
||||
|
||||
if (!res) {
|
||||
ERROR_LOG(BOOT, "Failed to load ROM: %s", error_str.c_str());
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
Core::SingleStep();
|
||||
}
|
||||
|
||||
delete emu_window;
|
||||
|
||||
return 0;
|
||||
}
|
||||
35
src/citra/citra.h
Normal file
35
src/citra/citra.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* Copyright (C) 2013 Citra Emulator
|
||||
*
|
||||
* @file citra.h
|
||||
* @author ShizZy <shizzy247@gmail.com>
|
||||
* @date 2013-09-04
|
||||
* @brief Main entry point
|
||||
*
|
||||
* @section LICENSE
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details at
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* Official project repository can be found at:
|
||||
* http://code.google.com/p/gekko-gc-emu/
|
||||
*/
|
||||
|
||||
#ifndef CITRA_CITRA_H
|
||||
#define CITRA_CITRA_H
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#define APP_NAME "citra"
|
||||
#define APP_VERSION "0.01-" VERSION
|
||||
#define APP_TITLE APP_NAME " " APP_VERSION
|
||||
#define COPYRIGHT "Copyright (C) 2013 Citra Emulator"
|
||||
|
||||
#endif // CITRA_CITRA_H
|
||||
98
src/citra/emu_window/emu_window_glfw.cpp
Normal file
98
src/citra/emu_window/emu_window_glfw.cpp
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/**
|
||||
* Copyright (C) 2013 Citra Emulator
|
||||
*
|
||||
* @file emu_window_glfw.cpp
|
||||
* @author ShizZy <shizzy@6bit.net>
|
||||
* @date 2013-09-04
|
||||
* @brief Implementation implementation of EmuWindow class for GLFW
|
||||
*
|
||||
* @section LICENSE
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details at
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* Official project repository can be found at:
|
||||
* http://code.google.com/p/gekko-gc-emu/
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "video_core.h"
|
||||
#include "emu_window_glfw.h"
|
||||
|
||||
static void OnKeyEvent(GLFWwindow* win, int key, int action) {
|
||||
// EmuWindow_GLFW* emuwin = (EmuWindow_GLFW*)glfwGetWindowUserPointer(win);
|
||||
//input_common::GCController::GCButtonState state;
|
||||
|
||||
//if (action == GLFW_PRESS) {
|
||||
// state = input_common::GCController::PRESSED;
|
||||
//} else {
|
||||
// state = input_common::GCController::RELEASED;
|
||||
//}
|
||||
// for (int channel = 0; channel < 4 && emuwin->controller_interface(); ++channel) {
|
||||
// emuwin->controller_interface()->SetControllerStatus(channel, key, state);
|
||||
// }
|
||||
}
|
||||
|
||||
static void OnWindowSizeEvent(GLFWwindow* win, int width, int height) {
|
||||
EmuWindow_GLFW* emuwin = (EmuWindow_GLFW*)glfwGetWindowUserPointer(win);
|
||||
emuwin->set_client_area_width(width);
|
||||
emuwin->set_client_area_height(height);
|
||||
}
|
||||
|
||||
/// EmuWindow_GLFW constructor
|
||||
EmuWindow_GLFW::EmuWindow_GLFW() {
|
||||
// Initialize the window
|
||||
if(glfwInit() != GL_TRUE) {
|
||||
printf("Failed to initialize GLFW! Exiting...");
|
||||
exit(1);
|
||||
}
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
||||
render_window_ = glfwCreateWindow(VideoCore::kScreenTopWidth,
|
||||
(VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight), "citra", NULL, NULL);
|
||||
|
||||
// Setup callbacks
|
||||
glfwSetWindowUserPointer(render_window_, this);
|
||||
//glfwSetKeyCallback(render_window_, OnKeyEvent);
|
||||
//glfwSetWindowSizeCallback(render_window_, OnWindowSizeEvent);
|
||||
|
||||
DoneCurrent();
|
||||
}
|
||||
|
||||
/// EmuWindow_GLFW destructor
|
||||
EmuWindow_GLFW::~EmuWindow_GLFW() {
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
/// Swap buffers to display the next frame
|
||||
void EmuWindow_GLFW::SwapBuffers() {
|
||||
glfwSwapBuffers(render_window_);
|
||||
}
|
||||
|
||||
/// Polls window events
|
||||
void EmuWindow_GLFW::PollEvents() {
|
||||
// TODO(ShizZy): Does this belong here? This is a reasonable place to update the window title
|
||||
// from the main thread, but this should probably be in an event handler...
|
||||
static char title[128];
|
||||
sprintf(title, "%s (FPS: %02.02f)", window_title_.c_str(), 0.0f);
|
||||
glfwSetWindowTitle(render_window_, title);
|
||||
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
/// Makes the GLFW OpenGL context current for the caller thread
|
||||
void EmuWindow_GLFW::MakeCurrent() {
|
||||
glfwMakeContextCurrent(render_window_);
|
||||
}
|
||||
|
||||
/// Releases (dunno if this is the "right" word) the GLFW context from the caller thread
|
||||
void EmuWindow_GLFW::DoneCurrent() {
|
||||
glfwMakeContextCurrent(NULL);
|
||||
}
|
||||
53
src/citra/emu_window/emu_window_glfw.h
Normal file
53
src/citra/emu_window/emu_window_glfw.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* Copyright (C) 2013 Citra Emulator
|
||||
*
|
||||
* @file emu_window_glfw.h
|
||||
* @author ShizZy <shizzy@6bit.net>
|
||||
* @date 2013-09-04
|
||||
* @brief Implementation implementation of EmuWindow class for GLFW
|
||||
*
|
||||
* @section LICENSE
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details at
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* Official project repository can be found at:
|
||||
* http://code.google.com/p/gekko-gc-emu/
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "emu_window.h"
|
||||
|
||||
class EmuWindow_GLFW : public EmuWindow {
|
||||
public:
|
||||
EmuWindow_GLFW();
|
||||
~EmuWindow_GLFW();
|
||||
|
||||
/// Swap buffers to display the next frame
|
||||
void SwapBuffers();
|
||||
|
||||
/// Polls window events
|
||||
void PollEvents();
|
||||
|
||||
/// Makes the graphics context current for the caller thread
|
||||
void MakeCurrent();
|
||||
|
||||
/// Releases (dunno if this is the "right" word) the GLFW context from the caller thread
|
||||
void DoneCurrent();
|
||||
|
||||
GLFWwindow* render_window_; ///< Internal GLFW render window
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
6
src/citra/version.h
Normal file
6
src/citra/version.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// GENERATED - Do not edit!
|
||||
#ifndef VERSION_H_
|
||||
#define VERSION_H_
|
||||
#define __BUILD__ "122"
|
||||
#define VERSION __BUILD__
|
||||
#endif // VERSION_H_
|
||||
206
src/citra_qt/bootmanager.cpp
Normal file
206
src/citra_qt/bootmanager.cpp
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
#include <QHBoxLayout>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include "common.h"
|
||||
#include "bootmanager.hxx"
|
||||
|
||||
#include "core.h"
|
||||
#include "loader.h"
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#define APP_NAME "citra"
|
||||
#define APP_VERSION "0.1-" VERSION
|
||||
#define APP_TITLE APP_NAME " " APP_VERSION
|
||||
#define COPYRIGHT "Copyright (C) 2013-2014 Citra Team"
|
||||
|
||||
EmuThread::EmuThread(GRenderWindow* render_window) : exec_cpu_step(false), cpu_running(false), render_window(render_window)
|
||||
{
|
||||
}
|
||||
|
||||
void EmuThread::SetFilename(const char* filename)
|
||||
{
|
||||
strcpy(this->filename, filename);
|
||||
}
|
||||
|
||||
void EmuThread::run()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
for (int tight_loop = 0; tight_loop < 10000; ++tight_loop)
|
||||
{
|
||||
if (cpu_running || exec_cpu_step)
|
||||
{
|
||||
if (exec_cpu_step)
|
||||
exec_cpu_step = false;
|
||||
|
||||
Core::SingleStep();
|
||||
emit CPUStepped();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Core::Stop();
|
||||
}
|
||||
|
||||
void EmuThread::Stop()
|
||||
{
|
||||
if (!isRunning())
|
||||
{
|
||||
INFO_LOG(MASTER_LOG, "EmuThread::Stop called while emu thread wasn't running, returning...");
|
||||
return;
|
||||
}
|
||||
|
||||
//core::g_state = core::SYS_DIE;
|
||||
|
||||
wait(1000);
|
||||
if (isRunning())
|
||||
{
|
||||
WARN_LOG(MASTER_LOG, "EmuThread still running, terminating...");
|
||||
terminate();
|
||||
wait(1000);
|
||||
if (isRunning())
|
||||
WARN_LOG(MASTER_LOG, "EmuThread STILL running, something is wrong here...");
|
||||
}
|
||||
INFO_LOG(MASTER_LOG, "EmuThread stopped");
|
||||
}
|
||||
|
||||
|
||||
// This class overrides paintEvent and resizeEvent to prevent the GUI thread from stealing GL context.
|
||||
// The corresponding functionality is handled in EmuThread instead
|
||||
class GGLWidgetInternal : public QGLWidget
|
||||
{
|
||||
public:
|
||||
GGLWidgetInternal(GRenderWindow* parent) : QGLWidget(parent)
|
||||
{
|
||||
setAutoBufferSwap(false);
|
||||
doneCurrent();
|
||||
parent_ = parent;
|
||||
}
|
||||
|
||||
void paintEvent(QPaintEvent* ev)
|
||||
{
|
||||
// Apparently, Windows doesn't display anything if we don't call this here.
|
||||
// TODO: Breaks linux though because we aren't calling doneCurrent() ... -.-
|
||||
// makeCurrent();
|
||||
}
|
||||
void resizeEvent(QResizeEvent* ev) {
|
||||
parent_->set_client_area_width(size().width());
|
||||
parent_->set_client_area_height(size().height());
|
||||
}
|
||||
private:
|
||||
GRenderWindow* parent_;
|
||||
};
|
||||
|
||||
|
||||
EmuThread& GRenderWindow::GetEmuThread()
|
||||
{
|
||||
return emu_thread;
|
||||
}
|
||||
|
||||
GRenderWindow::GRenderWindow(QWidget* parent) : QWidget(parent), emu_thread(this)
|
||||
{
|
||||
// TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground, WA_DontShowOnScreen, WA_DeleteOnClose
|
||||
|
||||
child = new GGLWidgetInternal(this);
|
||||
|
||||
QBoxLayout* layout = new QHBoxLayout(this);
|
||||
resize(640, 480); // TODO: Load size from config instead
|
||||
layout->addWidget(child);
|
||||
layout->setMargin(0);
|
||||
setLayout(layout);
|
||||
|
||||
BackupGeometry();
|
||||
}
|
||||
|
||||
GRenderWindow::~GRenderWindow()
|
||||
{
|
||||
emu_thread.Stop();
|
||||
}
|
||||
|
||||
void GRenderWindow::SwapBuffers()
|
||||
{
|
||||
child->makeCurrent(); // TODO: Not necessary?
|
||||
child->swapBuffers();
|
||||
}
|
||||
|
||||
void GRenderWindow::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
emu_thread.Stop();
|
||||
QWidget::closeEvent(event);
|
||||
}
|
||||
|
||||
void GRenderWindow::MakeCurrent()
|
||||
{
|
||||
child->makeCurrent();
|
||||
}
|
||||
|
||||
void GRenderWindow::DoneCurrent()
|
||||
{
|
||||
child->doneCurrent();
|
||||
}
|
||||
|
||||
void GRenderWindow::PollEvents() {
|
||||
// TODO(ShizZy): Does this belong here? This is a reasonable place to update the window title
|
||||
// from the main thread, but this should probably be in an event handler...
|
||||
/*
|
||||
static char title[128];
|
||||
sprintf(title, "%s (FPS: %02.02f)", window_title_.c_str(),
|
||||
video_core::g_renderer->current_fps());
|
||||
setWindowTitle(title);
|
||||
*/
|
||||
}
|
||||
|
||||
void GRenderWindow::BackupGeometry()
|
||||
{
|
||||
geometry = ((QGLWidget*)this)->saveGeometry();
|
||||
}
|
||||
|
||||
void GRenderWindow::RestoreGeometry()
|
||||
{
|
||||
// We don't want to back up the geometry here (obviously)
|
||||
QWidget::restoreGeometry(geometry);
|
||||
}
|
||||
|
||||
void GRenderWindow::restoreGeometry(const QByteArray& geometry)
|
||||
{
|
||||
// Make sure users of this class don't need to deal with backing up the geometry themselves
|
||||
QWidget::restoreGeometry(geometry);
|
||||
BackupGeometry();
|
||||
}
|
||||
|
||||
QByteArray GRenderWindow::saveGeometry()
|
||||
{
|
||||
// If we are a top-level widget, store the current geometry
|
||||
// otherwise, store the last backup
|
||||
if (parent() == NULL)
|
||||
return ((QGLWidget*)this)->saveGeometry();
|
||||
else
|
||||
return geometry;
|
||||
}
|
||||
|
||||
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 (!key_processed)
|
||||
QWidget::keyPressEvent(event);
|
||||
*/
|
||||
}
|
||||
|
||||
void GRenderWindow::keyReleaseEvent(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::RELEASED))
|
||||
key_processed = true;
|
||||
|
||||
if (!key_processed)
|
||||
QWidget::keyPressEvent(event);
|
||||
*/
|
||||
}
|
||||
112
src/citra_qt/bootmanager.hxx
Normal file
112
src/citra_qt/bootmanager.hxx
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
#include <QThread>
|
||||
#include <QGLWidget>
|
||||
#include "common.h"
|
||||
#include "emu_window.h"
|
||||
|
||||
class GRenderWindow;
|
||||
class QKeyEvent;
|
||||
|
||||
class EmuThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* Set image filename
|
||||
*
|
||||
* @param filename
|
||||
* @warning Only call when not running!
|
||||
*/
|
||||
void SetFilename(const char* filename);
|
||||
|
||||
/**
|
||||
* Start emulation (on new thread)
|
||||
*
|
||||
* @warning Only call when not running!
|
||||
*/
|
||||
void run();
|
||||
|
||||
/**
|
||||
* Allow the CPU to process a single instruction (if cpu is not running)
|
||||
*
|
||||
* @note This function is thread-safe
|
||||
*/
|
||||
void ExecStep() { exec_cpu_step = true; }
|
||||
|
||||
/**
|
||||
* Allow the CPU to continue processing instructions without interruption
|
||||
*
|
||||
* @note This function is thread-safe
|
||||
*/
|
||||
void SetCpuRunning(bool running) { cpu_running = running; }
|
||||
|
||||
/**
|
||||
* Allow the CPU to continue processing instructions without interruption
|
||||
*
|
||||
* @note This function is thread-safe
|
||||
*/
|
||||
bool IsCpuRunning() { return cpu_running; }
|
||||
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* Stop emulation and wait for the thread to finish.
|
||||
*
|
||||
* @details: This function will wait a second for the thread to finish; if it hasn't finished until then, we'll terminate() it and wait another second, hoping that it will be terminated by then.
|
||||
* @note: This function is thread-safe.
|
||||
*/
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
friend class GRenderWindow;
|
||||
|
||||
EmuThread(GRenderWindow* render_window);
|
||||
|
||||
char filename[MAX_PATH];
|
||||
|
||||
bool exec_cpu_step;
|
||||
bool cpu_running;
|
||||
|
||||
GRenderWindow* render_window;
|
||||
|
||||
signals:
|
||||
/**
|
||||
* Emitted when CPU when we've finished processing a single Gekko instruction
|
||||
*
|
||||
* @warning This will only be emitted when the CPU is not running (SetCpuRunning(false))
|
||||
* @warning When connecting to this signal from other threads, make sure to specify either Qt::QueuedConnection (invoke slot within the destination object's message thread) or even Qt::BlockingQueuedConnection (additionally block source thread until slot returns)
|
||||
*/
|
||||
void CPUStepped();
|
||||
};
|
||||
|
||||
class GRenderWindow : public QWidget, public EmuWindow
|
||||
{
|
||||
public:
|
||||
GRenderWindow(QWidget* parent = NULL);
|
||||
~GRenderWindow();
|
||||
|
||||
void closeEvent(QCloseEvent*);
|
||||
|
||||
// EmuWindow implementation
|
||||
void SwapBuffers();
|
||||
void MakeCurrent();
|
||||
void DoneCurrent();
|
||||
void PollEvents();
|
||||
|
||||
void BackupGeometry();
|
||||
void RestoreGeometry();
|
||||
void restoreGeometry(const QByteArray& geometry); // overridden
|
||||
QByteArray saveGeometry(); // overridden
|
||||
|
||||
EmuThread& GetEmuThread();
|
||||
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void keyReleaseEvent(QKeyEvent* event);
|
||||
|
||||
private:
|
||||
QGLWidget* child;
|
||||
|
||||
EmuThread emu_thread;
|
||||
|
||||
QByteArray geometry;
|
||||
};
|
||||
36
src/citra_qt/callstack.cpp
Normal file
36
src/citra_qt/callstack.cpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#include <QStandardItemModel>
|
||||
#include "callstack.hxx"
|
||||
|
||||
//#include "debugger/debugger.h"
|
||||
|
||||
GCallstackView::GCallstackView(QWidget* parent): QDockWidget(parent)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
|
||||
callstack_model = new QStandardItemModel(this);
|
||||
callstack_model->setColumnCount(3);
|
||||
callstack_model->setHeaderData(0, Qt::Horizontal, "Depth");
|
||||
callstack_model->setHeaderData(1, Qt::Horizontal, "Address");
|
||||
callstack_model->setHeaderData(2, Qt::Horizontal, "Function Name");
|
||||
ui.treeView->setModel(callstack_model);
|
||||
|
||||
// TODO: Make single clicking a callstack entry jump to the corresponding disassembly position
|
||||
}
|
||||
|
||||
void GCallstackView::OnCPUStepped()
|
||||
{
|
||||
/*
|
||||
Debugger::Callstack callstack;
|
||||
Debugger::GetCallstack(callstack);
|
||||
callstack_model->setRowCount(callstack.size());
|
||||
|
||||
for (int i = 0; i < callstack.size(); ++i)
|
||||
for (Debugger::CallstackIterator it = callstack.begin(); it != callstack.end(); ++it)
|
||||
{
|
||||
Debugger::CallstackEntry entry = callstack[i];
|
||||
callstack_model->setItem(i, 0, new QStandardItem(QString("%1").arg(i+1)));
|
||||
callstack_model->setItem(i, 1, new QStandardItem(QString("0x%1").arg(entry.addr, 8, 16, QLatin1Char('0'))));
|
||||
callstack_model->setItem(i, 2, new QStandardItem(QString::fromStdString(entry.name)));
|
||||
}
|
||||
*/
|
||||
}
|
||||
20
src/citra_qt/callstack.hxx
Normal file
20
src/citra_qt/callstack.hxx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#include <QDockWidget>
|
||||
#include "ui_callstack.h"
|
||||
#include "platform.h"
|
||||
|
||||
class QStandardItemModel;
|
||||
|
||||
class GCallstackView : public QDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GCallstackView(QWidget* parent = 0);
|
||||
|
||||
public slots:
|
||||
void OnCPUStepped();
|
||||
|
||||
private:
|
||||
Ui::CallStack ui;
|
||||
QStandardItemModel* callstack_model;
|
||||
};
|
||||
36
src/citra_qt/callstack.ui
Normal file
36
src/citra_qt/callstack.ui
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CallStack</class>
|
||||
<widget class="QDockWidget" name="CallStack">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Call stack</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTreeView" name="treeView">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="itemsExpandable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
91
src/citra_qt/config/controller_config.cpp
Normal file
91
src/citra_qt/config/controller_config.cpp
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
#include <QDialogButtonBox>
|
||||
|
||||
#include "controller_config.hxx"
|
||||
#include "controller_config_util.hxx"
|
||||
|
||||
/* TODO(bunnei): ImplementMe
|
||||
|
||||
using common::Config;
|
||||
|
||||
GControllerConfig::GControllerConfig(common::Config::ControllerPort* initial_config, QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
((QGridLayout*)ui.mainStickTab->layout())->addWidget(new GStickConfig(Config::ANALOG_LEFT, Config::ANALOG_RIGHT, Config::ANALOG_UP, Config::ANALOG_DOWN, this, this), 1, 1);
|
||||
((QGridLayout*)ui.cStickTab->layout())->addWidget(new GStickConfig(Config::C_LEFT, Config::C_RIGHT, Config::C_UP, Config::C_DOWN, this, this), 1, 1);
|
||||
((QGridLayout*)ui.dPadTab->layout())->addWidget(new GStickConfig(Config::DPAD_LEFT, Config::DPAD_RIGHT, Config::DPAD_UP, Config::DPAD_DOWN, this, this), 1, 1);
|
||||
|
||||
// TODO: Arrange these more compactly?
|
||||
QVBoxLayout* layout = (QVBoxLayout*)ui.buttonsTab->layout();
|
||||
layout->addWidget(new GButtonConfigGroup("A Button", Config::BUTTON_A, this, ui.buttonsTab));
|
||||
layout->addWidget(new GButtonConfigGroup("B Button", Config::BUTTON_B, this, ui.buttonsTab));
|
||||
layout->addWidget(new GButtonConfigGroup("X Button", Config::BUTTON_X, this, ui.buttonsTab));
|
||||
layout->addWidget(new GButtonConfigGroup("Y Button", Config::BUTTON_Y, this, ui.buttonsTab));
|
||||
layout->addWidget(new GButtonConfigGroup("Z Button", Config::BUTTON_Z, this, ui.buttonsTab));
|
||||
layout->addWidget(new GButtonConfigGroup("L Trigger", Config::TRIGGER_L, this, ui.buttonsTab));
|
||||
layout->addWidget(new GButtonConfigGroup("R Trigger", Config::TRIGGER_R, this, ui.buttonsTab));
|
||||
layout->addWidget(new GButtonConfigGroup("Start Button", Config::BUTTON_START, this, ui.buttonsTab));
|
||||
|
||||
memcpy(config, initial_config, sizeof(config));
|
||||
|
||||
emit ActivePortChanged(config[0]);
|
||||
}
|
||||
|
||||
void GControllerConfig::OnKeyConfigChanged(common::Config::Control id, int key, const QString& name)
|
||||
{
|
||||
if (InputSourceJoypad())
|
||||
{
|
||||
config[GetActiveController()].pads.key_code[id] = key;
|
||||
}
|
||||
else
|
||||
{
|
||||
config[GetActiveController()].keys.key_code[id] = key;
|
||||
}
|
||||
emit ActivePortChanged(config[GetActiveController()]);
|
||||
}
|
||||
|
||||
int GControllerConfig::GetActiveController()
|
||||
{
|
||||
return ui.activeControllerCB->currentIndex();
|
||||
}
|
||||
|
||||
bool GControllerConfig::InputSourceJoypad()
|
||||
{
|
||||
return ui.inputSourceCB->currentIndex() == 1;
|
||||
}
|
||||
|
||||
GControllerConfigDialog::GControllerConfigDialog(common::Config::ControllerPort* controller_ports, QWidget* parent) : QDialog(parent), config_ptr(controller_ports)
|
||||
{
|
||||
setWindowTitle(tr("Input configuration"));
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
config_widget = new GControllerConfig(controller_ports, this);
|
||||
layout->addWidget(config_widget);
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
layout->addWidget(buttons);
|
||||
|
||||
connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
|
||||
connect(this, SIGNAL(accepted()), this, SLOT(EnableChanges()));
|
||||
|
||||
layout->setSizeConstraint(QLayout::SetFixedSize);
|
||||
setLayout(layout);
|
||||
setModal(true);
|
||||
show();
|
||||
}
|
||||
|
||||
void GControllerConfigDialog::EnableChanges()
|
||||
{
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
{
|
||||
memcpy(&config_ptr[i], &config_widget->GetControllerConfig(i), sizeof(common::Config::ControllerPort));
|
||||
|
||||
if (common::g_config) {
|
||||
// Apply changes if running a game
|
||||
memcpy(&common::g_config->controller_ports(i), &config_widget->GetControllerConfig(i), sizeof(common::Config::ControllerPort));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
52
src/citra_qt/config/controller_config.hxx
Normal file
52
src/citra_qt/config/controller_config.hxx
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#ifndef _CONTROLLER_CONFIG_HXX_
|
||||
#define _CONTROLLER_CONFIG_HXX_
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include "ui_controller_config.h"
|
||||
|
||||
/* TODO(bunnei): ImplementMe
|
||||
|
||||
#include "config.h"
|
||||
|
||||
class GControllerConfig : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GControllerConfig(common::Config::ControllerPort* initial_config, QWidget* parent = NULL);
|
||||
|
||||
const common::Config::ControllerPort& GetControllerConfig(int index) const { return config[index]; }
|
||||
|
||||
signals:
|
||||
void ActivePortChanged(const common::Config::ControllerPort&);
|
||||
|
||||
public slots:
|
||||
void OnKeyConfigChanged(common::Config::Control id, int key, const QString& name);
|
||||
|
||||
private:
|
||||
int GetActiveController();
|
||||
bool InputSourceJoypad();
|
||||
|
||||
Ui::ControllerConfig ui;
|
||||
common::Config::ControllerPort config[4];
|
||||
};
|
||||
|
||||
class GControllerConfigDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GControllerConfigDialog(common::Config::ControllerPort* controller_ports, QWidget* parent = NULL);
|
||||
|
||||
public slots:
|
||||
void EnableChanges();
|
||||
|
||||
private:
|
||||
GControllerConfig* config_widget;
|
||||
common::Config::ControllerPort* config_ptr;
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
#endif // _CONTROLLER_CONFIG_HXX_
|
||||
308
src/citra_qt/config/controller_config.ui
Normal file
308
src/citra_qt/config/controller_config.ui
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ControllerConfig</class>
|
||||
<widget class="QWidget" name="ControllerConfig">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>503</width>
|
||||
<height>293</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Controller Configuration</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetFixedSize</enum>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="activeControllerCB">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Controller 1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Controller 2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Controller 3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Controller 4</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QCheckBox" name="checkBox">
|
||||
<property name="text">
|
||||
<string>Enabled</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="inputSourceCB">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Keyboard</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Joypad</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Active Controller:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Input Source:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="mainStickTab">
|
||||
<attribute name="title">
|
||||
<string>Main Stick</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="2" column="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="cStickTab">
|
||||
<attribute name="title">
|
||||
<string>C-Stick</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="1" column="0">
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<spacer name="verticalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="dPadTab">
|
||||
<attribute name="title">
|
||||
<string>D-Pad</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<spacer name="verticalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<spacer name="verticalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="buttonsTab">
|
||||
<attribute name="title">
|
||||
<string>Buttons</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2"/>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<slots>
|
||||
<signal>ControlsChanged()</signal>
|
||||
<signal>MainStickCleared()</signal>
|
||||
<signal>CStickCleared()</signal>
|
||||
<signal>DPadCleared()</signal>
|
||||
<signal>ButtonsCleared()</signal>
|
||||
<slot>OnControlsChanged()</slot>
|
||||
<slot>OnMainStickCleared()</slot>
|
||||
<slot>OnCStickCleared()</slot>
|
||||
<slot>OnDPadCleared()</slot>
|
||||
<slot>OnButtonsCleared()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
121
src/citra_qt/config/controller_config_util.cpp
Normal file
121
src/citra_qt/config/controller_config_util.cpp
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
#include <QPushButton>
|
||||
#include <QStyle>
|
||||
#include <QGridLayout>
|
||||
#include <QKeyEvent>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
|
||||
#include "controller_config_util.hxx"
|
||||
|
||||
/* TODO(bunnei): ImplementMe
|
||||
GStickConfig::GStickConfig(common::Config::Control leftid, common::Config::Control rightid, common::Config::Control upid, common::Config::Control downid, QObject* change_receiver, QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
left = new GKeyConfigButton(leftid, style()->standardIcon(QStyle::SP_ArrowLeft), QString(), change_receiver, this);
|
||||
right = new GKeyConfigButton(rightid, style()->standardIcon(QStyle::SP_ArrowRight), QString(), change_receiver, this);
|
||||
up = new GKeyConfigButton(upid, style()->standardIcon(QStyle::SP_ArrowUp), QString(), change_receiver, this);
|
||||
down = new GKeyConfigButton(downid, style()->standardIcon(QStyle::SP_ArrowDown), QString(), change_receiver, this);
|
||||
clear = new QPushButton(tr("Clear"), this);
|
||||
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
layout->addWidget(left, 1, 0);
|
||||
layout->addWidget(right, 1, 2);
|
||||
layout->addWidget(up, 0, 1);
|
||||
layout->addWidget(down, 2, 1);
|
||||
layout->addWidget(clear, 1, 1);
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
GKeyConfigButton::GKeyConfigButton(common::Config::Control id, const QIcon& icon, const QString& text, QObject* change_receiver, QWidget* parent) : QPushButton(icon, text, parent), id(id), inputGrabbed(false)
|
||||
{
|
||||
connect(this, SIGNAL(clicked()), this, SLOT(OnClicked()));
|
||||
connect(this, SIGNAL(KeyAssigned(common::Config::Control, int, const QString&)), change_receiver, SLOT(OnKeyConfigChanged(common::Config::Control, int, const QString&)));
|
||||
connect(change_receiver, SIGNAL(ActivePortChanged(const common::Config::ControllerPort&)), this, SLOT(OnActivePortChanged(const common::Config::ControllerPort&)));
|
||||
}
|
||||
|
||||
GKeyConfigButton::GKeyConfigButton(common::Config::Control id, const QString& text, QObject* change_receiver, QWidget* parent) : QPushButton(text, parent), id(id), inputGrabbed(false)
|
||||
{
|
||||
connect(this, SIGNAL(clicked()), this, SLOT(OnClicked()));
|
||||
connect(this, SIGNAL(KeyAssigned(common::Config::Control, int, const QString&)), change_receiver, SLOT(OnKeyConfigChanged(common::Config::Control, int, const QString&)));
|
||||
connect(change_receiver, SIGNAL(ActivePortChanged(const common::Config::ControllerPort&)), this, SLOT(OnActivePortChanged(const common::Config::ControllerPort&)));
|
||||
}
|
||||
|
||||
void GKeyConfigButton::OnActivePortChanged(const common::Config::ControllerPort& config)
|
||||
{
|
||||
// TODO: Doesn't use joypad struct if that's the input source...
|
||||
QString text = QKeySequence(config.keys.key_code[id]).toString(); // has a nicer format
|
||||
if (config.keys.key_code[id] == Qt::Key_Shift) text = tr("Shift");
|
||||
else if (config.keys.key_code[id] == Qt::Key_Control) text = tr("Control");
|
||||
else if (config.keys.key_code[id] == Qt::Key_Alt) text = tr("Alt");
|
||||
else if (config.keys.key_code[id] == Qt::Key_Meta) text = tr("Meta");
|
||||
setText(text);
|
||||
}
|
||||
|
||||
void GKeyConfigButton::OnClicked()
|
||||
{
|
||||
grabKeyboard();
|
||||
grabMouse();
|
||||
inputGrabbed = true;
|
||||
|
||||
old_text = text();
|
||||
setText(tr("Input..."));
|
||||
}
|
||||
|
||||
void GKeyConfigButton::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
if (inputGrabbed)
|
||||
{
|
||||
releaseKeyboard();
|
||||
releaseMouse();
|
||||
setText(QString());
|
||||
|
||||
// TODO: Doesn't capture "return" key
|
||||
// TODO: This doesn't quite work well, yet... find a better way
|
||||
QString text = QKeySequence(event->key()).toString(); // has a nicer format than event->text()
|
||||
int key = event->key();
|
||||
if (event->modifiers() == Qt::ShiftModifier) { text = tr("Shift"); key = Qt::Key_Shift; }
|
||||
else if (event->modifiers() == Qt::ControlModifier) { text = tr("Ctrl"); key = Qt::Key_Control; }
|
||||
else if (event->modifiers() == Qt::AltModifier) { text = tr("Alt"); key = Qt::Key_Alt; }
|
||||
else if (event->modifiers() == Qt::MetaModifier) { text = tr("Meta"); key = Qt::Key_Meta; }
|
||||
|
||||
setText(old_text);
|
||||
emit KeyAssigned(id, key, text);
|
||||
|
||||
inputGrabbed = false;
|
||||
|
||||
// TODO: Keys like "return" cause another keyPressEvent to be generated after this one...
|
||||
}
|
||||
|
||||
QPushButton::keyPressEvent(event); // TODO: Necessary?
|
||||
}
|
||||
|
||||
void GKeyConfigButton::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
// Abort key assignment
|
||||
if (inputGrabbed)
|
||||
{
|
||||
releaseKeyboard();
|
||||
releaseMouse();
|
||||
setText(old_text);
|
||||
inputGrabbed = false;
|
||||
}
|
||||
|
||||
QAbstractButton::mousePressEvent(event);
|
||||
}
|
||||
|
||||
GButtonConfigGroup::GButtonConfigGroup(const QString& name, common::Config::Control id, QObject* change_receiver, QWidget* parent) : QWidget(parent), id(id)
|
||||
{
|
||||
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||
|
||||
QPushButton* clear_button = new QPushButton(tr("Clear"));
|
||||
|
||||
layout->addWidget(new QLabel(name, this));
|
||||
layout->addWidget(config_button = new GKeyConfigButton(id, QString(), change_receiver, this));
|
||||
layout->addWidget(clear_button);
|
||||
|
||||
// TODO: connect config_button, clear_button
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
*/
|
||||
78
src/citra_qt/config/controller_config_util.hxx
Normal file
78
src/citra_qt/config/controller_config_util.hxx
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#ifndef _CONTROLLER_CONFIG_UTIL_HXX_
|
||||
#define _CONTROLLER_CONFIG_UTIL_HXX_
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPushButton>
|
||||
|
||||
/* TODO(bunnei): ImplementMe
|
||||
|
||||
#include "config.h"
|
||||
|
||||
class GStickConfig : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// change_receiver needs to have a OnKeyConfigChanged(common::Config::Control, int, const QString&) slot!
|
||||
GStickConfig(common::Config::Control leftid, common::Config::Control rightid, common::Config::Control upid, common::Config::Control downid, QObject* change_receiver, QWidget* parent = NULL);
|
||||
|
||||
signals:
|
||||
void LeftChanged();
|
||||
void RightChanged();
|
||||
void UpChanged();
|
||||
void DownChanged();
|
||||
|
||||
private:
|
||||
QPushButton* left;
|
||||
QPushButton* right;
|
||||
QPushButton* up;
|
||||
QPushButton* down;
|
||||
|
||||
QPushButton* clear;
|
||||
};
|
||||
|
||||
class GKeyConfigButton : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// TODO: change_receiver also needs to have an ActivePortChanged(const common::Config::ControllerPort&) signal
|
||||
// change_receiver needs to have a OnKeyConfigChanged(common::Config::Control, int, const QString&) slot!
|
||||
GKeyConfigButton(common::Config::Control id, const QIcon& icon, const QString& text, QObject* change_receiver, QWidget* parent);
|
||||
GKeyConfigButton(common::Config::Control id, const QString& text, QObject* change_receiver, QWidget* parent);
|
||||
|
||||
signals:
|
||||
void KeyAssigned(common::Config::Control id, int key, const QString& text);
|
||||
|
||||
private slots:
|
||||
void OnActivePortChanged(const common::Config::ControllerPort& config);
|
||||
|
||||
void OnClicked();
|
||||
|
||||
void keyPressEvent(QKeyEvent* event); // TODO: bGrabbed?
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
|
||||
private:
|
||||
common::Config::Control id;
|
||||
bool inputGrabbed;
|
||||
|
||||
QString old_text;
|
||||
};
|
||||
|
||||
class GButtonConfigGroup : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// change_receiver needs to have a OnKeyConfigChanged(common::Config::Control, int, const QString&) slot!
|
||||
GButtonConfigGroup(const QString& name, common::Config::Control id, QObject* change_receiver, QWidget* parent = NULL);
|
||||
|
||||
private:
|
||||
GKeyConfigButton* config_button;
|
||||
|
||||
common::Config::Control id;
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
#endif // _CONTROLLER_CONFIG_HXX_
|
||||
222
src/citra_qt/config/ui_controller_config.h
Normal file
222
src/citra_qt/config/ui_controller_config.h
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
/********************************************************************************
|
||||
** Form generated from reading UI file 'controller_config.ui'
|
||||
**
|
||||
** Created by: Qt User Interface Compiler version 4.8.5
|
||||
**
|
||||
** WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef UI_CONTROLLER_CONFIG_H
|
||||
#define UI_CONTROLLER_CONFIG_H
|
||||
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QButtonGroup>
|
||||
#include <QtGui/QCheckBox>
|
||||
#include <QtGui/QComboBox>
|
||||
#include <QtGui/QGridLayout>
|
||||
#include <QtGui/QHeaderView>
|
||||
#include <QtGui/QLabel>
|
||||
#include <QtGui/QSpacerItem>
|
||||
#include <QtGui/QTabWidget>
|
||||
#include <QtGui/QVBoxLayout>
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Ui_ControllerConfig
|
||||
{
|
||||
public:
|
||||
QVBoxLayout *verticalLayout;
|
||||
QGridLayout *gridLayout;
|
||||
QComboBox *activeControllerCB;
|
||||
QSpacerItem *horizontalSpacer;
|
||||
QCheckBox *checkBox;
|
||||
QComboBox *inputSourceCB;
|
||||
QLabel *label_2;
|
||||
QLabel *label;
|
||||
QTabWidget *tabWidget;
|
||||
QWidget *mainStickTab;
|
||||
QGridLayout *gridLayout_3;
|
||||
QSpacerItem *verticalSpacer_2;
|
||||
QSpacerItem *verticalSpacer_3;
|
||||
QSpacerItem *horizontalSpacer_4;
|
||||
QSpacerItem *horizontalSpacer_3;
|
||||
QWidget *cStickTab;
|
||||
QGridLayout *gridLayout_4;
|
||||
QSpacerItem *horizontalSpacer_6;
|
||||
QSpacerItem *verticalSpacer_5;
|
||||
QSpacerItem *verticalSpacer_4;
|
||||
QSpacerItem *horizontalSpacer_5;
|
||||
QWidget *dPadTab;
|
||||
QGridLayout *gridLayout_5;
|
||||
QSpacerItem *horizontalSpacer_7;
|
||||
QSpacerItem *verticalSpacer_7;
|
||||
QSpacerItem *verticalSpacer_6;
|
||||
QSpacerItem *horizontalSpacer_8;
|
||||
QWidget *buttonsTab;
|
||||
QVBoxLayout *verticalLayout_2;
|
||||
|
||||
void setupUi(QWidget *ControllerConfig)
|
||||
{
|
||||
if (ControllerConfig->objectName().isEmpty())
|
||||
ControllerConfig->setObjectName(QString::fromUtf8("ControllerConfig"));
|
||||
ControllerConfig->resize(503, 293);
|
||||
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
sizePolicy.setHorizontalStretch(0);
|
||||
sizePolicy.setVerticalStretch(0);
|
||||
sizePolicy.setHeightForWidth(ControllerConfig->sizePolicy().hasHeightForWidth());
|
||||
ControllerConfig->setSizePolicy(sizePolicy);
|
||||
verticalLayout = new QVBoxLayout(ControllerConfig);
|
||||
verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
|
||||
verticalLayout->setSizeConstraint(QLayout::SetFixedSize);
|
||||
gridLayout = new QGridLayout();
|
||||
gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
|
||||
activeControllerCB = new QComboBox(ControllerConfig);
|
||||
activeControllerCB->setObjectName(QString::fromUtf8("activeControllerCB"));
|
||||
|
||||
gridLayout->addWidget(activeControllerCB, 1, 1, 1, 1);
|
||||
|
||||
horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
|
||||
gridLayout->addItem(horizontalSpacer, 0, 2, 1, 1);
|
||||
|
||||
checkBox = new QCheckBox(ControllerConfig);
|
||||
checkBox->setObjectName(QString::fromUtf8("checkBox"));
|
||||
|
||||
gridLayout->addWidget(checkBox, 1, 2, 1, 1);
|
||||
|
||||
inputSourceCB = new QComboBox(ControllerConfig);
|
||||
inputSourceCB->setObjectName(QString::fromUtf8("inputSourceCB"));
|
||||
|
||||
gridLayout->addWidget(inputSourceCB, 0, 1, 1, 1);
|
||||
|
||||
label_2 = new QLabel(ControllerConfig);
|
||||
label_2->setObjectName(QString::fromUtf8("label_2"));
|
||||
|
||||
gridLayout->addWidget(label_2, 1, 0, 1, 1);
|
||||
|
||||
label = new QLabel(ControllerConfig);
|
||||
label->setObjectName(QString::fromUtf8("label"));
|
||||
|
||||
gridLayout->addWidget(label, 0, 0, 1, 1);
|
||||
|
||||
|
||||
verticalLayout->addLayout(gridLayout);
|
||||
|
||||
tabWidget = new QTabWidget(ControllerConfig);
|
||||
tabWidget->setObjectName(QString::fromUtf8("tabWidget"));
|
||||
mainStickTab = new QWidget();
|
||||
mainStickTab->setObjectName(QString::fromUtf8("mainStickTab"));
|
||||
gridLayout_3 = new QGridLayout(mainStickTab);
|
||||
gridLayout_3->setObjectName(QString::fromUtf8("gridLayout_3"));
|
||||
verticalSpacer_2 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
|
||||
gridLayout_3->addItem(verticalSpacer_2, 2, 2, 1, 1);
|
||||
|
||||
verticalSpacer_3 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
|
||||
gridLayout_3->addItem(verticalSpacer_3, 0, 2, 1, 1);
|
||||
|
||||
horizontalSpacer_4 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
|
||||
gridLayout_3->addItem(horizontalSpacer_4, 1, 0, 1, 1);
|
||||
|
||||
horizontalSpacer_3 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
|
||||
gridLayout_3->addItem(horizontalSpacer_3, 1, 4, 1, 1);
|
||||
|
||||
tabWidget->addTab(mainStickTab, QString());
|
||||
cStickTab = new QWidget();
|
||||
cStickTab->setObjectName(QString::fromUtf8("cStickTab"));
|
||||
gridLayout_4 = new QGridLayout(cStickTab);
|
||||
gridLayout_4->setObjectName(QString::fromUtf8("gridLayout_4"));
|
||||
horizontalSpacer_6 = new QSpacerItem(40, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
|
||||
gridLayout_4->addItem(horizontalSpacer_6, 1, 0, 1, 1);
|
||||
|
||||
verticalSpacer_5 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
|
||||
gridLayout_4->addItem(verticalSpacer_5, 0, 1, 1, 1);
|
||||
|
||||
verticalSpacer_4 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
|
||||
gridLayout_4->addItem(verticalSpacer_4, 2, 1, 1, 1);
|
||||
|
||||
horizontalSpacer_5 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
|
||||
gridLayout_4->addItem(horizontalSpacer_5, 1, 2, 1, 1);
|
||||
|
||||
tabWidget->addTab(cStickTab, QString());
|
||||
dPadTab = new QWidget();
|
||||
dPadTab->setObjectName(QString::fromUtf8("dPadTab"));
|
||||
gridLayout_5 = new QGridLayout(dPadTab);
|
||||
gridLayout_5->setObjectName(QString::fromUtf8("gridLayout_5"));
|
||||
horizontalSpacer_7 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
|
||||
gridLayout_5->addItem(horizontalSpacer_7, 1, 2, 1, 1);
|
||||
|
||||
verticalSpacer_7 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
|
||||
gridLayout_5->addItem(verticalSpacer_7, 0, 1, 1, 1);
|
||||
|
||||
verticalSpacer_6 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
|
||||
gridLayout_5->addItem(verticalSpacer_6, 2, 1, 1, 1);
|
||||
|
||||
horizontalSpacer_8 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
|
||||
gridLayout_5->addItem(horizontalSpacer_8, 1, 0, 1, 1);
|
||||
|
||||
tabWidget->addTab(dPadTab, QString());
|
||||
buttonsTab = new QWidget();
|
||||
buttonsTab->setObjectName(QString::fromUtf8("buttonsTab"));
|
||||
verticalLayout_2 = new QVBoxLayout(buttonsTab);
|
||||
verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2"));
|
||||
tabWidget->addTab(buttonsTab, QString());
|
||||
|
||||
verticalLayout->addWidget(tabWidget);
|
||||
|
||||
|
||||
retranslateUi(ControllerConfig);
|
||||
|
||||
tabWidget->setCurrentIndex(0);
|
||||
|
||||
|
||||
QMetaObject::connectSlotsByName(ControllerConfig);
|
||||
} // setupUi
|
||||
|
||||
void retranslateUi(QWidget *ControllerConfig)
|
||||
{
|
||||
ControllerConfig->setWindowTitle(QApplication::translate("ControllerConfig", "Controller Configuration", 0, QApplication::UnicodeUTF8));
|
||||
activeControllerCB->clear();
|
||||
activeControllerCB->insertItems(0, QStringList()
|
||||
<< QApplication::translate("ControllerConfig", "Controller 1", 0, QApplication::UnicodeUTF8)
|
||||
<< QApplication::translate("ControllerConfig", "Controller 2", 0, QApplication::UnicodeUTF8)
|
||||
<< QApplication::translate("ControllerConfig", "Controller 3", 0, QApplication::UnicodeUTF8)
|
||||
<< QApplication::translate("ControllerConfig", "Controller 4", 0, QApplication::UnicodeUTF8)
|
||||
);
|
||||
checkBox->setText(QApplication::translate("ControllerConfig", "Enabled", 0, QApplication::UnicodeUTF8));
|
||||
inputSourceCB->clear();
|
||||
inputSourceCB->insertItems(0, QStringList()
|
||||
<< QApplication::translate("ControllerConfig", "Keyboard", 0, QApplication::UnicodeUTF8)
|
||||
<< QApplication::translate("ControllerConfig", "Joypad", 0, QApplication::UnicodeUTF8)
|
||||
);
|
||||
label_2->setText(QApplication::translate("ControllerConfig", "Active Controller:", 0, QApplication::UnicodeUTF8));
|
||||
label->setText(QApplication::translate("ControllerConfig", "Input Source:", 0, QApplication::UnicodeUTF8));
|
||||
tabWidget->setTabText(tabWidget->indexOf(mainStickTab), QApplication::translate("ControllerConfig", "Main Stick", 0, QApplication::UnicodeUTF8));
|
||||
tabWidget->setTabText(tabWidget->indexOf(cStickTab), QApplication::translate("ControllerConfig", "C-Stick", 0, QApplication::UnicodeUTF8));
|
||||
tabWidget->setTabText(tabWidget->indexOf(dPadTab), QApplication::translate("ControllerConfig", "D-Pad", 0, QApplication::UnicodeUTF8));
|
||||
tabWidget->setTabText(tabWidget->indexOf(buttonsTab), QApplication::translate("ControllerConfig", "Buttons", 0, QApplication::UnicodeUTF8));
|
||||
} // retranslateUi
|
||||
|
||||
};
|
||||
|
||||
namespace Ui {
|
||||
class ControllerConfig: public Ui_ControllerConfig {};
|
||||
} // namespace Ui
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // UI_CONTROLLER_CONFIG_H
|
||||
63
src/citra_qt/cpu_regs.cpp
Normal file
63
src/citra_qt/cpu_regs.cpp
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#include "cpu_regs.hxx"
|
||||
|
||||
#include "core.h"
|
||||
#include "arm/interpreter/armdefs.h"
|
||||
|
||||
GARM11RegsView::GARM11RegsView(QWidget* parent) : QDockWidget(parent)
|
||||
{
|
||||
cpu_regs_ui.setupUi(this);
|
||||
|
||||
tree = cpu_regs_ui.treeWidget;
|
||||
tree->addTopLevelItem(registers = new QTreeWidgetItem(QStringList("Registers")));
|
||||
tree->addTopLevelItem(CSPR = new QTreeWidgetItem(QStringList("CSPR")));
|
||||
|
||||
registers->setExpanded(true);
|
||||
CSPR->setExpanded(true);
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
QTreeWidgetItem* child = new QTreeWidgetItem(QStringList(QString("R[%1]").arg(i, 2, 10, QLatin1Char('0'))));
|
||||
registers->addChild(child);
|
||||
}
|
||||
|
||||
CSPR->addChild(new QTreeWidgetItem(QStringList("M")));
|
||||
CSPR->addChild(new QTreeWidgetItem(QStringList("T")));
|
||||
CSPR->addChild(new QTreeWidgetItem(QStringList("F")));
|
||||
CSPR->addChild(new QTreeWidgetItem(QStringList("I")));
|
||||
CSPR->addChild(new QTreeWidgetItem(QStringList("A")));
|
||||
CSPR->addChild(new QTreeWidgetItem(QStringList("E")));
|
||||
CSPR->addChild(new QTreeWidgetItem(QStringList("IT")));
|
||||
CSPR->addChild(new QTreeWidgetItem(QStringList("GE")));
|
||||
CSPR->addChild(new QTreeWidgetItem(QStringList("DNM")));
|
||||
CSPR->addChild(new QTreeWidgetItem(QStringList("J")));
|
||||
CSPR->addChild(new QTreeWidgetItem(QStringList("Q")));
|
||||
CSPR->addChild(new QTreeWidgetItem(QStringList("V")));
|
||||
CSPR->addChild(new QTreeWidgetItem(QStringList("C")));
|
||||
CSPR->addChild(new QTreeWidgetItem(QStringList("Z")));
|
||||
CSPR->addChild(new QTreeWidgetItem(QStringList("N")));
|
||||
}
|
||||
|
||||
void GARM11RegsView::OnCPUStepped()
|
||||
{
|
||||
ARM_Interface* app_core = Core::g_app_core;
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
registers->child(i)->setText(1, QString("0x%1").arg(app_core->Reg(i), 8, 16, QLatin1Char('0')));
|
||||
|
||||
CSPR->setText(1, QString("0x%1").arg(app_core->CPSR(), 8, 16, QLatin1Char('0')));
|
||||
CSPR->child(0)->setText(1, QString("b%1").arg(app_core->CPSR() & 0x1F, 5, 2, QLatin1Char('0'))); // M - Mode
|
||||
CSPR->child(1)->setText(1, QString("%1").arg((app_core->CPSR() >> 5) & 0x1)); // T - State
|
||||
CSPR->child(2)->setText(1, QString("%1").arg((app_core->CPSR() >> 6) & 0x1)); // F - FIQ disable
|
||||
CSPR->child(3)->setText(1, QString("%1").arg((app_core->CPSR() >> 7) & 0x1)); // I - IRQ disable
|
||||
CSPR->child(4)->setText(1, QString("%1").arg((app_core->CPSR() >> 8) & 0x1)); // A - Imprecise abort
|
||||
CSPR->child(5)->setText(1, QString("%1").arg((app_core->CPSR() >> 9) & 0x1)); // E - Data endianess
|
||||
CSPR->child(6)->setText(1, QString("%1").arg((app_core->CPSR() >> 10) & 0x3F)); // IT - If-Then state (DNM)
|
||||
CSPR->child(7)->setText(1, QString("%1").arg((app_core->CPSR() >> 16) & 0xF)); // GE - Greater-than-or-Equal
|
||||
CSPR->child(8)->setText(1, QString("%1").arg((app_core->CPSR() >> 20) & 0xF)); // DNM - Do not modify
|
||||
CSPR->child(9)->setText(1, QString("%1").arg((app_core->CPSR() >> 24) & 0x1)); // J - Java state
|
||||
CSPR->child(10)->setText(1, QString("%1").arg((app_core->CPSR() >> 27) & 0x1)); // Q - Sticky overflow
|
||||
CSPR->child(11)->setText(1, QString("%1").arg((app_core->CPSR() >> 28) & 0x1)); // V - Overflow
|
||||
CSPR->child(12)->setText(1, QString("%1").arg((app_core->CPSR() >> 29) & 0x1)); // C - Carry/Borrow/Extend
|
||||
CSPR->child(13)->setText(1, QString("%1").arg((app_core->CPSR() >> 30) & 0x1)); // Z - Zero
|
||||
CSPR->child(14)->setText(1, QString("%1").arg((app_core->CPSR() >> 31) & 0x1)); // N - Negative/Less than
|
||||
}
|
||||
27
src/citra_qt/cpu_regs.hxx
Normal file
27
src/citra_qt/cpu_regs.hxx
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#include "ui_cpu_regs.h"
|
||||
|
||||
#include <QDockWidget>
|
||||
#include <QTreeWidgetItem>
|
||||
|
||||
//#include "ui_gekko_regs.h"
|
||||
|
||||
class QTreeWidget;
|
||||
|
||||
class GARM11RegsView : public QDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GARM11RegsView(QWidget* parent = NULL);
|
||||
|
||||
public slots:
|
||||
void OnCPUStepped();
|
||||
|
||||
private:
|
||||
Ui::ARMRegisters cpu_regs_ui;
|
||||
|
||||
QTreeWidget* tree;
|
||||
|
||||
QTreeWidgetItem* registers;
|
||||
QTreeWidgetItem* CSPR;
|
||||
};
|
||||
40
src/citra_qt/cpu_regs.ui
Normal file
40
src/citra_qt/cpu_regs.ui
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ARMRegisters</class>
|
||||
<widget class="QDockWidget" name="ARMRegisters">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>ARM registers</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="treeWidget">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Register</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Value</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
135
src/citra_qt/disasm.cpp
Normal file
135
src/citra_qt/disasm.cpp
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
#include <QtGui>
|
||||
#include "ui_disasm.h"
|
||||
#include "disasm.hxx"
|
||||
|
||||
#include "bootmanager.hxx"
|
||||
#include "hotkeys.hxx"
|
||||
|
||||
#include "common.h"
|
||||
#include "mem_map.h"
|
||||
|
||||
#include "core.h"
|
||||
#include "break_points.h"
|
||||
#include "arm/interpreter/armdefs.h"
|
||||
#include "arm/disassembler/arm_disasm.h"
|
||||
|
||||
GDisAsmView::GDisAsmView(QWidget* parent, EmuThread& emu_thread) : QDockWidget(parent), base_addr(0), emu_thread(emu_thread)
|
||||
{
|
||||
disasm_ui.setupUi(this);
|
||||
|
||||
breakpoints = new BreakPoints();
|
||||
|
||||
model = new QStandardItemModel(this);
|
||||
model->setColumnCount(2);
|
||||
disasm_ui.treeView->setModel(model);
|
||||
|
||||
RegisterHotkey("Disassembler", "Start/Stop", QKeySequence(Qt::Key_F5), Qt::ApplicationShortcut);
|
||||
RegisterHotkey("Disassembler", "Step", QKeySequence(Qt::Key_F10), Qt::ApplicationShortcut);
|
||||
RegisterHotkey("Disassembler", "Step into", QKeySequence(Qt::Key_F11), Qt::ApplicationShortcut);
|
||||
RegisterHotkey("Disassembler", "Set Breakpoint", QKeySequence(Qt::Key_F9), Qt::ApplicationShortcut);
|
||||
|
||||
connect(disasm_ui.button_breakpoint, SIGNAL(clicked()), this, SLOT(OnSetBreakpoint()));
|
||||
connect(disasm_ui.button_step, SIGNAL(clicked()), this, SLOT(OnStep()));
|
||||
connect(disasm_ui.button_pause, SIGNAL(clicked()), this, SLOT(OnPause()));
|
||||
connect(disasm_ui.button_continue, SIGNAL(clicked()), this, SLOT(OnContinue()));
|
||||
|
||||
connect(GetHotkey("Disassembler", "Start/Stop", this), SIGNAL(activated()), this, SLOT(OnToggleStartStop()));
|
||||
connect(GetHotkey("Disassembler", "Step", this), SIGNAL(activated()), this, SLOT(OnStep()));
|
||||
connect(GetHotkey("Disassembler", "Step into", this), SIGNAL(activated()), this, SLOT(OnStepInto()));
|
||||
connect(GetHotkey("Disassembler", "Set Breakpoint", this), SIGNAL(activated()), this, SLOT(OnSetBreakpoint()));
|
||||
}
|
||||
|
||||
void GDisAsmView::Init()
|
||||
{
|
||||
ARM_Disasm* disasm = new ARM_Disasm();
|
||||
|
||||
base_addr = Core::g_app_core->PC();
|
||||
unsigned int curInstAddr = base_addr;
|
||||
char result[255];
|
||||
|
||||
for (int i = 0; i < 10000; i++) // fixed for now
|
||||
{
|
||||
disasm->disasm(curInstAddr, Memory::Read32(curInstAddr), result);
|
||||
model->setItem(i, 0, new QStandardItem(QString("0x%1").arg((uint)(curInstAddr), 8, 16, QLatin1Char('0'))));
|
||||
model->setItem(i, 1, new QStandardItem(QString(result)));
|
||||
curInstAddr += 4;
|
||||
}
|
||||
disasm_ui.treeView->resizeColumnToContents(0);
|
||||
disasm_ui.treeView->resizeColumnToContents(1);
|
||||
|
||||
QModelIndex model_index = model->index(0, 0);
|
||||
disasm_ui.treeView->scrollTo(model_index);
|
||||
disasm_ui.treeView->selectionModel()->setCurrentIndex(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
|
||||
}
|
||||
|
||||
void GDisAsmView::OnSetBreakpoint()
|
||||
{
|
||||
int selected_row = SelectedRow();
|
||||
|
||||
if (selected_row == -1)
|
||||
return;
|
||||
|
||||
u32 address = base_addr + (selected_row * 4);
|
||||
if (breakpoints->IsAddressBreakPoint(address))
|
||||
{
|
||||
breakpoints->Remove(address);
|
||||
model->item(selected_row, 0)->setBackground(QBrush());
|
||||
model->item(selected_row, 1)->setBackground(QBrush());
|
||||
}
|
||||
else
|
||||
{
|
||||
breakpoints->Add(address);
|
||||
model->item(selected_row, 0)->setBackground(QBrush(QColor(0xFF, 0x99, 0x99)));
|
||||
model->item(selected_row, 1)->setBackground(QBrush(QColor(0xFF, 0x99, 0x99)));
|
||||
}
|
||||
}
|
||||
|
||||
void GDisAsmView::OnContinue()
|
||||
{
|
||||
emu_thread.SetCpuRunning(true);
|
||||
}
|
||||
|
||||
void GDisAsmView::OnStep()
|
||||
{
|
||||
OnStepInto(); // change later
|
||||
}
|
||||
|
||||
void GDisAsmView::OnStepInto()
|
||||
{
|
||||
emu_thread.SetCpuRunning(false);
|
||||
emu_thread.ExecStep();
|
||||
}
|
||||
|
||||
void GDisAsmView::OnPause()
|
||||
{
|
||||
emu_thread.SetCpuRunning(false);
|
||||
}
|
||||
|
||||
void GDisAsmView::OnToggleStartStop()
|
||||
{
|
||||
emu_thread.SetCpuRunning(!emu_thread.IsCpuRunning());
|
||||
}
|
||||
|
||||
void GDisAsmView::OnCPUStepped()
|
||||
{
|
||||
ARMword next_instr = Core::g_app_core->PC();
|
||||
|
||||
if (breakpoints->IsAddressBreakPoint(next_instr))
|
||||
{
|
||||
emu_thread.SetCpuRunning(false);
|
||||
}
|
||||
|
||||
unsigned int index = (next_instr - base_addr) / 4;
|
||||
QModelIndex model_index = model->index(index, 0);
|
||||
disasm_ui.treeView->scrollTo(model_index);
|
||||
disasm_ui.treeView->selectionModel()->setCurrentIndex(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
|
||||
}
|
||||
|
||||
int GDisAsmView::SelectedRow()
|
||||
{
|
||||
QModelIndex index = disasm_ui.treeView->selectionModel()->currentIndex();
|
||||
if (!index.isValid())
|
||||
return -1;
|
||||
|
||||
return model->itemFromIndex(disasm_ui.treeView->selectionModel()->currentIndex())->row();
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue