GTK: Added GBA cheats support. Thanks to unmacaque for the patch.

This commit is contained in:
bgk 2011-02-20 14:53:04 +00:00
parent 4b9103e16c
commit 8c0ea991c8
13 changed files with 1060 additions and 0 deletions

View File

@ -250,6 +250,8 @@ SET(SRC_GTK
src/gtk/filters.cpp
src/gtk/gameboyconfig.cpp
src/gtk/gameboyadvanceconfig.cpp
src/gtk/cheatlist.cpp
src/gtk/cheatedit.cpp
src/gtk/joypadconfig.cpp
src/gtk/directoriesconfig.cpp
src/gtk/displayconfig.cpp
@ -257,6 +259,7 @@ SET(SRC_GTK
src/gtk/screenarea.cpp
src/gtk/screenarea-cairo.cpp
src/gtk/screenarea-opengl.cpp
src/gtk/stringtokenizer.cpp
src/gtk/tools.cpp
src/gtk/window.cpp
src/sdl/inputSDL.cpp

116
src/gtk/cheatedit.cpp Normal file
View File

@ -0,0 +1,116 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 2008 VBA-M development team
// 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, 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.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "cheatedit.h"
#include "intl.h"
namespace VBA
{
class CheatCodeColumns : public Gtk::TreeModel::ColumnRecord
{
public:
CheatCodeColumns()
{
add(uText);
add(iType);
}
~CheatCodeColumns() {}
Gtk::TreeModelColumn<Glib::ustring> uText;
Gtk::TreeModelColumn<ECheatType> iType;
};
CheatCodeColumns cTypeModel;
/**
* GameBoyAdvanceCheatEditDialog
*
* A unified cheat editing dialog for multiple code types.
*/
CheatEditDialog::CheatEditDialog(GtkDialog* _pstDialog, const Glib::RefPtr<Gtk::Builder>& refBuilder) :
Gtk::Dialog(_pstDialog)
{
refBuilder->get_widget("CheatDescEntry", m_poCheatDescEntry);
refBuilder->get_widget("CheatTypeComboBox", m_poCheatTypeComboBox);
refBuilder->get_widget("CheatInputTextView", m_poCheatInputTextView);
refBuilder->get_widget("CheatApplyButton", m_poCheatApplyButton);
refBuilder->get_widget("CheatCancelButton", m_poCheatCancelButton);
// Tree View model
m_poCheatTypeStore = Gtk::ListStore::create(cTypeModel);
m_poCheatTypeComboBox->set_model(m_poCheatTypeStore);
Gtk::TreeModel::Row row = *(m_poCheatTypeStore->append());
row[cTypeModel.iType] = CheatGeneric;
row[cTypeModel.uText] = "Generic Code";
row = *(m_poCheatTypeStore->append());
row[cTypeModel.iType] = CheatGSA;
row[cTypeModel.uText] = "Gameshark Advance";
row = *(m_poCheatTypeStore->append());
row[cTypeModel.iType] = CheatCBA;
row[cTypeModel.uText] = "CodeBreaker Advance";
m_poCheatTypeComboBox->set_active(CheatGeneric);
m_poCheatApplyButton->signal_clicked().connect(sigc::mem_fun(*this, &CheatEditDialog::vOnApply));
m_poCheatCancelButton->signal_clicked().connect(sigc::mem_fun(*this, &CheatEditDialog::vOnCancel));
}
Glib::RefPtr<Gtk::TextBuffer> CheatEditDialog::vGetCode()
{
return m_poCheatInputTextView->get_buffer();
}
Glib::ustring CheatEditDialog::vGetDesc()
{
return m_poCheatDescEntry->get_text();
}
ECheatType CheatEditDialog::vGetType()
{
Gtk::TreeModel::iterator iter = m_poCheatTypeComboBox->get_active();
if (iter)
{
Gtk::TreeModel::Row row = *iter;
return row[cTypeModel.iType];
}
return CheatGeneric;
}
void CheatEditDialog::vOnApply()
{
response(Gtk::RESPONSE_APPLY);
}
void CheatEditDialog::vOnCancel() {
response(Gtk::RESPONSE_CANCEL);
}
} // namespace VBA

62
src/gtk/cheatedit.h Normal file
View File

@ -0,0 +1,62 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 2008 VBA-M development team
// 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, 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.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef __VBA_CHEATEDIT_H__
#define __VBA_CHEATEDIT_H__
#include <gtkmm.h>
#include "window.h"
namespace VBA
{
enum ECheatType
{
CheatGeneric,
CheatGSA,
CheatCBA
};
class CheatEditDialog : public Gtk::Dialog
{
public:
CheatEditDialog(GtkDialog* _pstDialog, const Glib::RefPtr<Gtk::Builder>& refBuilder);
Glib::RefPtr<Gtk::TextBuffer> vGetCode();
Glib::ustring vGetDesc();
ECheatType vGetType();
private:
void vOnApply();
void vOnCancel();
VBA::Window * m_poWindow;
Gtk::Entry * m_poCheatDescEntry;
Gtk::ComboBox * m_poCheatTypeComboBox;
Gtk::TextView * m_poCheatInputTextView;
Gtk::Button * m_poCheatApplyButton;
Gtk::Button * m_poCheatCancelButton;
Glib::RefPtr<Gtk::TextBuffer> m_poCheatInputBuffer;
Glib::RefPtr<Gtk::ListStore> m_poCheatTypeStore;
};
} // namespace VBA
#endif

293
src/gtk/cheatlist.cpp Normal file
View File

@ -0,0 +1,293 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 2008 VBA-M development team
// 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, 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.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "cheatlist.h"
#include "intl.h"
#include "stringtokenizer.h"
#include <vector>
namespace VBA
{
class CheatCodeColumns : public Gtk::TreeModel::ColumnRecord
{
public:
CheatCodeColumns()
{
add(iIndex);
add(bEnabled);
add(uDesc);
}
~CheatCodeColumns() {}
Gtk::TreeModelColumn<int> iIndex;
Gtk::TreeModelColumn<bool> bEnabled;
Gtk::TreeModelColumn<Glib::ustring> uDesc;
};
CheatCodeColumns cRecordModel;
CheatListDialog::CheatListDialog(GtkDialog* _pstDialog, const Glib::RefPtr<Gtk::Builder>& refBuilder) :
Gtk::Dialog(_pstDialog)
{
refBuilder->get_widget("CheatOpenButton", m_poCheatOpenButton);
refBuilder->get_widget("CheatSaveButton", m_poCheatSaveButton);
refBuilder->get_widget("CheatAddButton", m_poCheatAddButton);
refBuilder->get_widget("CheatRemoveButton", m_poCheatRemoveButton);
refBuilder->get_widget("CheatRemoveAllButton", m_poCheatRemoveAllButton);
refBuilder->get_widget("CheatMarkAllButton", m_poCheatMarkAllButton);
refBuilder->get_widget("CheatTreeView", m_poCheatTreeView);
// Tree View model
m_poCheatListStore = Gtk::ListStore::create(cRecordModel);
m_poCheatTreeView->set_model(m_poCheatListStore);
Gtk::CellRendererToggle* pRenderer = Gtk::manage(new Gtk::CellRendererToggle());
int cols_count = m_poCheatTreeView->append_column("", *pRenderer);
pRenderer->signal_toggled().connect(sigc::mem_fun(*this, &CheatListDialog::vOnCheatToggled));
Gtk::TreeViewColumn* pColumn = m_poCheatTreeView->get_column(cols_count - 1);
if (pColumn)
pColumn->add_attribute(pRenderer->property_active(), cRecordModel.bEnabled);
m_poCheatTreeView->append_column("Description", cRecordModel.uDesc);
m_poCheatOpenButton->signal_clicked().connect(sigc::mem_fun(*this, &CheatListDialog::vOnCheatOpen));
m_poCheatSaveButton->signal_clicked().connect(sigc::mem_fun(*this, &CheatListDialog::vOnCheatSave));
m_poCheatAddButton->signal_clicked().connect(sigc::mem_fun(*this, &CheatListDialog::vOnCheatAdd));
m_poCheatRemoveButton->signal_clicked().connect(sigc::mem_fun(*this, &CheatListDialog::vOnCheatRemove));
m_poCheatRemoveAllButton->signal_clicked().connect(sigc::mem_fun(*this, &CheatListDialog::vOnCheatRemoveAll));
m_poCheatMarkAllButton->signal_clicked().connect(sigc::mem_fun(*this, &CheatListDialog::vOnCheatMarkAll));
bMark = false;
vUpdateList();
}
void CheatListDialog::vOnCheatOpen()
{
Gtk::FileChooserDialog oDialog(*this, _("Open cheat list"));
oDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
oDialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
oDialog.set_current_folder(Glib::get_home_dir()); // TODO: remember dir?
while (oDialog.run() == Gtk::RESPONSE_OK)
{
// delete existing cheats before loading the list
cheatsDeleteAll(false);
m_poCheatListStore->clear();
if (cheatsLoadCheatList(oDialog.get_filename().c_str()))
{
vUpdateList();
break;
}
}
}
void CheatListDialog::vOnCheatSave()
{
Gtk::FileChooserDialog sDialog(*this, _("Save cheat list"));
sDialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
sDialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
sDialog.set_current_folder(Glib::get_home_dir());
if (sDialog.run() == Gtk::RESPONSE_OK)
cheatsSaveCheatList(sDialog.get_filename().c_str());
}
void CheatListDialog::vOnCheatAdd()
{
std::string sUiFile = VBA::Window::sGetUiFilePath("cheatedit.ui");
Glib::RefPtr<Gtk::Builder> poBuilder = Gtk::Builder::create_from_file(sUiFile);
CheatEditDialog * poDialog = 0;
poBuilder->get_widget_derived("CheatEditDialog", poDialog);
poDialog->set_transient_for(*this);
int response = poDialog->run();
poDialog->hide();
if (response == Gtk::RESPONSE_APPLY)
{
Glib::ustring sDesc = poDialog->vGetDesc();
int previous = cheatsNumber;
switch (poDialog->vGetType())
{
// Generic Code
case CheatGeneric:
{
std::vector<Glib::ustring> tokens;
Glib::RefPtr<Gtk::TextBuffer> code_buffer = poDialog->vGetCode();
StringTokenizer::tokenize(code_buffer->get_text(), tokens);
for (std::vector<Glib::ustring>::iterator it = tokens.begin();
it != tokens.end();
it++)
{
Glib::ustring sToken = it->uppercase();
cheatsAddCheatCode(sToken.c_str(), sDesc.c_str());
}
break;
}
// Gameshark Advance & CodeBreaker Advance
case CheatGSA:
case CheatCBA:
{
std::vector<Glib::ustring> tokens;
Glib::RefPtr<Gtk::TextBuffer> code_buffer = poDialog->vGetCode();
Glib::ustring sToken;
Glib::ustring sCode;
Glib::ustring sPart = "";
StringTokenizer::tokenize(code_buffer->get_text(), tokens);
for (std::vector<Glib::ustring>::iterator it = tokens.begin();
it != tokens.end();
it++)
{
sToken = it->uppercase();
const char *cToken = sToken.c_str();
if (sToken.size() == 16)
{
cheatsAddGSACode(cToken, sDesc.c_str(), false);
}
else if (sToken.size() == 12)
{
sCode = sToken.substr(0,8);
sCode += " ";
sCode += sToken.substr(9,4); // TODO: is this safe?
cheatsAddCBACode(sCode.c_str(), sDesc.c_str());
}
else
if (sPart.empty())
{
sPart = sToken;
}
else
{
if (sToken.size() == 4)
{
sCode = sPart;
sCode += " ";
sCode += cToken;
cheatsAddCBACode(sCode.c_str(), sDesc.c_str());
}
else
{
sCode = sPart + sToken;
cheatsAddGSACode(sCode.c_str(), sDesc.c_str(), true);
}
sPart = "";
}
} // end of loop
} // end of case
} // end of switch
vUpdateList(previous);
} // end of condition
}
void CheatListDialog::vOnCheatRemove()
{
Gtk::TreeModel::iterator iter = m_poCheatTreeView->get_selection()->get_selected();
if (iter)
{
Gtk::TreeModel::Row row = *iter;
cheatsDelete(row[cRecordModel.iIndex], false);
m_poCheatListStore->erase(iter);
}
}
void CheatListDialog::vOnCheatRemoveAll()
{
cheatsDeleteAll(false);
m_poCheatListStore->clear();
}
void CheatListDialog::vOnCheatMarkAll()
{
Gtk::TreeModel::Children cListEntries = m_poCheatListStore->children();
for (Gtk::TreeModel::iterator iter = cListEntries.begin(); iter; iter++)
{
Gtk::TreeModel::Row row = *iter;
row[cRecordModel.bEnabled] = bMark;
vToggleCheat(row[cRecordModel.iIndex], row[cRecordModel.bEnabled]);
}
bMark = !bMark;
}
void CheatListDialog::vOnCheatToggled(Glib::ustring const& string_path)
{
Gtk::TreeIter iter = m_poCheatListStore->get_iter(string_path);
Gtk::TreeModel::Row row = *iter;
row[cRecordModel.bEnabled] = !row[cRecordModel.bEnabled];
vToggleCheat(row[cRecordModel.iIndex], row[cRecordModel.bEnabled]);
}
void CheatListDialog::vToggleCheat(int index, bool enable) {
if (enable)
cheatsEnable(index);
else
cheatsDisable(index);
}
void CheatListDialog::vUpdateList(int previous)
{
for (int i = previous; i < cheatsNumber; i++)
{
// Add row for each newly added cheat
Gtk::TreeModel::Row row = *(m_poCheatListStore->append());
row[cRecordModel.iIndex] = i;
row[cRecordModel.bEnabled] = cheatsList[i].enabled;
row[cRecordModel.uDesc] = cheatsList[i].desc;
}
}
} // namespace VBA

69
src/gtk/cheatlist.h Normal file
View File

@ -0,0 +1,69 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 2008 VBA-M development team
// 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, 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.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef __VBA_CHEATLIST_H__
#define __VBA_CHEATLIST_H__
#include <gtkmm.h>
#include "../System.h"
#include "../gba/Cheats.h"
#include "../gba/GBA.h"
#include "../gba/Globals.h"
#include "cheatedit.h"
#include "window.h"
namespace VBA
{
class CheatListDialog : public Gtk::Dialog
{
public:
CheatListDialog(GtkDialog* _pstDialog, const Glib::RefPtr<Gtk::Builder>& refBuilder);
private:
void vAddCheat(int index, Glib::ustring desc, bool enabled = true);
void vOnCheatOpen();
void vOnCheatSave();
void vOnCheatAdd();
void vOnCheatRemove();
void vOnCheatRemoveAll();
void vOnCheatMarkAll();
void vOnCheatToggled(Glib::ustring const& string_path);
void vToggleCheat(int index, bool enable);
void vUpdateList(int previous = 0);
VBA::Window * m_poWindow;
Gtk::ToolButton * m_poCheatOpenButton;
Gtk::ToolButton * m_poCheatSaveButton;
Gtk::ToolButton * m_poCheatAddButton;
Gtk::ToolButton * m_poCheatRemoveButton;
Gtk::ToolButton * m_poCheatRemoveAllButton;
Gtk::ToolButton * m_poCheatMarkAllButton;
Gtk::TreeView * m_poCheatTreeView;
Glib::RefPtr<Gtk::ListStore> m_poCheatListStore;
bool bMark;
};
} // namespace VBA
#endif

View File

@ -0,0 +1,42 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team
// 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, 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.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "stringtokenizer.h"
namespace VBA
{
void StringTokenizer::tokenize(Glib::ustring source, std::vector<Glib::ustring>& tokens)
{
// Skip delimiters at beginning.
Glib::ustring::size_type lastPos = source.find_first_not_of(delimiters, 0);
// Find first "non-delimiter".
Glib::ustring::size_type pos = source.find_first_of(delimiters, lastPos);
while (Glib::ustring::npos != pos || std:: string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(source.substr(lastPos, pos - lastPos));
// Skip delimiters. Note the "not_of"
lastPos = source.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
pos = source.find_first_of(delimiters, lastPos);
}
}
} // VBA namespace

40
src/gtk/stringtokenizer.h Normal file
View File

@ -0,0 +1,40 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team
// 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, 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.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef __VBA_STRINGTOKENIZER_H__
#define __VBA_STRINGTOKENIZER_H__
#include <gtkmm.h>
#include <string>
#include <vector>
namespace VBA
{
class StringTokenizer
{
public:
static void tokenize(Glib::ustring source, std::vector<Glib::ustring>& tokens);
};
static const Glib::ustring delimiters = " \t\n\r";
} // VBA namespace
#endif

179
src/gtk/ui/cheatedit.ui Normal file
View File

@ -0,0 +1,179 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkListStore" id="model1">
<columns>
<!-- column-name gchararray -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkDialog" id="CheatEditDialog">
<property name="border_width">5</property>
<property name="title" translatable="yes">Edit cheat</property>
<property name="window_position">center-on-parent</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<child>
<object class="GtkFrame" id="frame1">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<object class="GtkEntry" id="CheatDescEntry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="max_length">31</property>
<property name="invisible_char">●</property>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Description&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame2">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment3">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<object class="GtkComboBox" id="CheatTypeComboBox">
<property name="visible">True</property>
<property name="model">model1</property>
<child>
<object class="GtkCellRendererText" id="renderer1"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Type&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame3">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
<property name="vscrollbar_policy">automatic</property>
<child>
<object class="GtkTextView" id="CheatInputTextView">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Codes&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="CheatApplyButton">
<property name="label">gtk-apply</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="CheatCancelButton">
<property name="label">gtk-close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">CheatApplyButton</action-widget>
<action-widget response="0">CheatCancelButton</action-widget>
</action-widgets>
</object>
</interface>

180
src/gtk/ui/cheatlist.ui Normal file
View File

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkDialog" id="CheatListDialog">
<property name="width_request">320</property>
<property name="height_request">260</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Cheat list</property>
<property name="window_position">center-on-parent</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<child>
<object class="GtkToolbar" id="toolbar1">
<property name="visible">True</property>
<child>
<object class="GtkToolButton" id="CheatOpenButton">
<property name="visible">True</property>
<property name="tooltip_text" translatable="yes">Open cheat list</property>
<property name="label" translatable="yes">gtk-open</property>
<property name="use_underline">True</property>
<property name="icon_name">document-open</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="CheatSaveButton">
<property name="visible">True</property>
<property name="tooltip_text" translatable="yes">Save cheat list</property>
<property name="label" translatable="yes">gtk-save</property>
<property name="use_underline">True</property>
<property name="icon_name">document-save</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkSeparatorToolItem" id="separator2">
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="CheatAddButton">
<property name="visible">True</property>
<property name="tooltip_text" translatable="yes">Add new cheat</property>
<property name="label" translatable="yes">gtk-add</property>
<property name="use_underline">True</property>
<property name="icon_name">list-add</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="CheatRemoveButton">
<property name="visible">True</property>
<property name="tooltip_text" translatable="yes">Delete selected cheat</property>
<property name="label" translatable="yes">gtk-delete</property>
<property name="use_underline">True</property>
<property name="icon_name">list-remove</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="CheatRemoveAllButton">
<property name="visible">True</property>
<property name="tooltip_text" translatable="yes">Delete all cheats</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-clear</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkSeparatorToolItem" id="separator1">
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="CheatMarkAllButton">
<property name="visible">True</property>
<property name="tooltip_text" translatable="yes">Toggle all Cheats</property>
<property name="label" translatable="yes">gtk-markall</property>
<property name="use_underline">True</property>
<property name="icon_name">edit-select-all</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
<property name="vscrollbar_policy">automatic</property>
<child>
<object class="GtkTreeView" id="CheatTreeView">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">end</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkButton" id="button1">
<property name="label">gtk-close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">button1</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -435,6 +435,31 @@
</child>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="separator34">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="CheatList">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_action_appearance">False</property>
<property name="label" translatable="yes">_List cheats ...</property>
<property name="use_underline">True</property>
<accelerator key="C" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
</child>
<child>
<object class="GtkCheckMenuItem" id="CheatDisable">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_action_appearance">False</property>
<property name="label" translatable="yes">_Disable cheats</property>
<property name="use_underline">True</property>
</object>
</child>
</object>
</child>
</object>

View File

@ -31,6 +31,7 @@
#include "../gba/Sound.h"
#include "../gb/gb.h"
#include "../gb/gbGlobals.h"
#include "../gb/gbCheats.h"
#include "../gb/gbSound.h"
#include "../gb/gbPrinter.h"
#include "../Util.h"
@ -342,6 +343,19 @@ Window::Window(GtkWindow * _pstWindow, const Glib::RefPtr<Gtk::Builder> & _poXml
_poXml->get_widget("GameBoyAdvanceConfigure", poMI);
poMI->signal_activate().connect(sigc::mem_fun(*this, &Window::vOnGameBoyAdvanceConfigure));
// Cheat list menu
_poXml->get_widget("CheatList", poMI);
poMI->signal_activate().connect(sigc::mem_fun(*this, &Window::vOnCheatList));
m_listSensitiveWhenPlaying.push_back(poMI);
// Cheat disable item
_poXml->get_widget("CheatDisable", poCMI);
poCMI->set_active(!cheatsEnabled);
poCMI->signal_toggled().connect(sigc::bind(
sigc::mem_fun(*this, &Window::vOnCheatDisableToggled),
poCMI));
m_listSensitiveWhenPlaying.push_back(poCMI);
// Display menu
_poXml->get_widget("DisplayConfigure", poMI);
poMI->signal_activate().connect(sigc::mem_fun(*this, &Window::vOnDisplayConfigure));
@ -993,6 +1007,10 @@ bool Window::bLoadROM(const std::string & _rsFile)
{
vOnFileClose();
// clear cheat list
cheatsDeleteAll(false);
gbCheatRemoveAll();
m_sRomFile = _rsFile;
const char * csFile = _rsFile.c_str();

View File

@ -161,6 +161,8 @@ protected:
virtual void vOnSoundConfigure();
virtual void vOnGameBoyConfigure();
virtual void vOnGameBoyAdvanceConfigure();
virtual void vOnCheatList();
virtual void vOnCheatDisableToggled(Gtk::CheckMenuItem * _poCMI);
virtual void vOnHelpAbout();
virtual bool bOnEmuIdle();

View File

@ -40,6 +40,7 @@
#include "soundconfig.h"
#include "gameboyconfig.h"
#include "gameboyadvanceconfig.h"
#include "cheatlist.h"
namespace VBA
{
@ -471,6 +472,36 @@ void Window::vOnGameBoyAdvanceConfigure()
poDialog->hide();
}
void Window::vOnCheatList()
{
if (m_eCartridge == CartridgeGBA)
{
std::string sUiFile = sGetUiFilePath("cheatlist.ui");
Glib::RefPtr<Gtk::Builder> poBuilder = Gtk::Builder::create_from_file(sUiFile);
CheatListDialog * poDialog = 0;
poBuilder->get_widget_derived("CheatListDialog", poDialog);
poDialog->set_transient_for(*this);
poDialog->run();
poDialog->hide();
}
else
{
vPopupError(_("Only Gameboy Advance cheats are supported"));
}
}
void Window::vOnCheatDisableToggled(Gtk::CheckMenuItem * _poCMI)
{
if (m_eCartridge == CartridgeGB) {
// TODO: implement
}
else if (m_eCartridge == CartridgeGBA) {
cheatsEnabled = !cheatsEnabled;
}
_poCMI->set_active(!cheatsEnabled);
}
void Window::vOnHelpAbout()
{