all repos — mgba @ 4cb243f15c011264e3b4e84100f6e4a050c4a623

mGBA Game Boy Advance Emulator

src/platform/qt/CheatsView.cpp (view raw)

  1/* Copyright (c) 2013-2015 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include "CheatsView.h"
  7
  8#include "GBAApp.h"
  9#include "GameController.h"
 10
 11#include <QClipboard>
 12#include <QPushButton>
 13
 14extern "C" {
 15#include "core/cheats.h"
 16#ifdef M_CORE_GBA
 17#include "gba/cheats.h"
 18#endif
 19#ifdef M_CORE_GB
 20#include "gb/cheats.h"
 21#endif
 22}
 23
 24using namespace QGBA;
 25
 26CheatsView::CheatsView(GameController* controller, QWidget* parent)
 27	: QWidget(parent)
 28	, m_controller(controller)
 29	, m_model(controller->cheatDevice())
 30{
 31	m_ui.setupUi(this);
 32
 33	m_ui.cheatList->installEventFilter(this);
 34	m_ui.cheatList->setModel(&m_model);
 35
 36	connect(m_ui.load, SIGNAL(clicked()), this, SLOT(load()));
 37	connect(m_ui.save, SIGNAL(clicked()), this, SLOT(save()));
 38	connect(m_ui.addSet, SIGNAL(clicked()), this, SLOT(addSet()));
 39	connect(m_ui.remove, SIGNAL(clicked()), this, SLOT(removeSet()));
 40	connect(controller, SIGNAL(gameStopped(mCoreThread*)), this, SLOT(close()));
 41	connect(controller, SIGNAL(stateLoaded(mCoreThread*)), &m_model, SLOT(invalidated()));
 42
 43	QPushButton* add;
 44	switch (controller->platform()) {
 45#ifdef M_CORE_GBA
 46	case PLATFORM_GBA:
 47		connect(m_ui.add, &QPushButton::clicked, [this]() {
 48			enterCheat(GBA_CHEAT_AUTODETECT);
 49		});
 50
 51		add = new QPushButton("Add GameShark");
 52		m_ui.gridLayout->addWidget(add, m_ui.gridLayout->rowCount(), 2, 1, 2);
 53		connect(add, &QPushButton::clicked, [this]() {
 54			enterCheat(GBA_CHEAT_GAMESHARK);
 55		});
 56
 57		add = new QPushButton("Add Pro Action Replay");
 58		m_ui.gridLayout->addWidget(add, m_ui.gridLayout->rowCount(), 2, 1, 2);
 59		connect(add, &QPushButton::clicked, [this]() {
 60			enterCheat(GBA_CHEAT_PRO_ACTION_REPLAY);
 61		});
 62
 63		add = new QPushButton("Add CodeBreaker");
 64		m_ui.gridLayout->addWidget(add, m_ui.gridLayout->rowCount(), 2, 1, 2);
 65		connect(add, &QPushButton::clicked, [this]() {
 66			enterCheat(GBA_CHEAT_CODEBREAKER);
 67		});
 68		break;
 69#endif
 70#ifdef M_CORE_GB
 71	case PLATFORM_GB:
 72		connect(m_ui.add, &QPushButton::clicked, [this]() {
 73			enterCheat(GB_CHEAT_AUTODETECT);
 74		});
 75
 76		add = new QPushButton("Add GameShark");
 77		m_ui.gridLayout->addWidget(add, m_ui.gridLayout->rowCount(), 2, 1, 2);
 78		connect(add, &QPushButton::clicked, [this]() {
 79			enterCheat(GB_CHEAT_GAMESHARK);
 80		});
 81
 82		add = new QPushButton("Add GameGenie");
 83		m_ui.gridLayout->addWidget(add, m_ui.gridLayout->rowCount(), 2, 1, 2);
 84		connect(add, &QPushButton::clicked, [this]() {
 85			enterCheat(GB_CHEAT_GAME_GENIE);
 86		});
 87		break;
 88#endif
 89	default:
 90		break;
 91	}
 92
 93	// Stretch the cheat list back into place
 94	int index = m_ui.gridLayout->indexOf(m_ui.cheatList);
 95	m_ui.gridLayout->takeAt(index);
 96	m_ui.gridLayout->addWidget(m_ui.cheatList, 0, 0, -1, 1);
 97}
 98
 99bool CheatsView::eventFilter(QObject* object, QEvent* event) {
100	if (object != m_ui.cheatList) {
101		return false;
102	}
103	if (event->type() != QEvent::KeyPress) {
104		return false;
105	}
106	if (static_cast<QKeyEvent*>(event) == QKeySequence::Copy) {
107		QApplication::clipboard()->setText(m_model.toString(m_ui.cheatList->selectionModel()->selectedIndexes()));
108		return true;
109	}
110	return false;
111}
112
113void CheatsView::load() {
114	QString filename = GBAApp::app()->getOpenFileName(this, tr("Select cheats file"));
115	if (!filename.isEmpty()) {
116		m_model.loadFile(filename);
117	}
118}
119
120void CheatsView::save() {
121	QString filename = GBAApp::app()->getSaveFileName(this, tr("Select cheats file"));
122	if (!filename.isEmpty()) {
123		m_model.saveFile(filename);
124	}
125}
126
127void CheatsView::addSet() {
128	m_controller->threadInterrupt();
129	mCheatSet* set = m_controller->cheatDevice()->createSet(m_controller->cheatDevice(), nullptr);
130	m_model.addSet(set);
131	m_controller->threadContinue();
132}
133
134void CheatsView::removeSet() {
135	GBACheatSet* set;
136	QModelIndexList selection = m_ui.cheatList->selectionModel()->selectedIndexes();
137	if (selection.count() < 1) {
138		return;
139	}
140	m_controller->threadInterrupt();
141	for (const QModelIndex& index : selection) {
142		m_model.removeAt(selection[0]);
143	}
144	m_controller->threadContinue();
145}
146
147void CheatsView::enterCheat(int codeType) {
148	mCheatSet* set = nullptr;
149	QModelIndexList selection = m_ui.cheatList->selectionModel()->selectedIndexes();
150	QModelIndex index;
151	if (selection.count() == 0) {
152		set = m_controller->cheatDevice()->createSet(m_controller->cheatDevice(), nullptr);
153	} else if (selection.count() == 1) {
154		index = selection[0];
155		set = m_model.itemAt(index);
156	}
157
158	if (!set) {
159		return;
160	}
161	m_controller->threadInterrupt();
162	if (selection.count() == 0) {
163		m_model.addSet(set);
164		index = m_model.index(m_model.rowCount() - 1, 0, QModelIndex());
165		m_ui.cheatList->selectionModel()->select(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
166	}
167	QStringList cheats = m_ui.codeEntry->toPlainText().split('\n', QString::SkipEmptyParts);
168	for (const QString& string : cheats) {
169		m_model.beginAppendRow(index);
170		mCheatAddLine(set, string.toUtf8().constData(), codeType);
171		m_model.endAppendRow();
172	}
173	set->refresh(set, m_controller->cheatDevice());
174	m_controller->threadContinue();
175	m_ui.codeEntry->clear();
176}