mirror of
https://github.com/libretro/snes9x.git
synced 2024-11-23 16:29:41 +00:00
More cheats stuff.
This commit is contained in:
parent
5b2a754fb4
commit
4edaba97ca
2
cheats.h
2
cheats.h
@ -269,7 +269,7 @@ void S9xDeleteCheatGroup (uint32 index);
|
||||
bool8 S9xLoadCheatFile (const char *filename);
|
||||
bool8 S9xSaveCheatFile (const char *filename);
|
||||
void S9xUpdateCheatsInMemory (void);
|
||||
bool8 S9xImportCheatsFromDatabase (const char *filename);
|
||||
int S9xImportCheatsFromDatabase(const char *filename);
|
||||
void S9xCheatsDisable (void);
|
||||
void S9xCheatsEnable (void);
|
||||
char *S9xCheatValidate (char *cheat);
|
||||
|
36
cheats2.cpp
36
cheats2.cpp
@ -701,6 +701,32 @@ void S9xUpdateCheatsInMemory (void)
|
||||
}
|
||||
}
|
||||
|
||||
static int S9xCheatIsDuplicate (char *name, char *code)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < Cheat.g.size(); i++)
|
||||
{
|
||||
if (!strcmp (name, Cheat.g[i].name))
|
||||
{
|
||||
char *code_string = S9xCheatGroupToText (i);
|
||||
char *validated = S9xCheatValidate (code);
|
||||
|
||||
if (validated && !strcmp (code_string, validated))
|
||||
{
|
||||
free (code_string);
|
||||
free (validated);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
free (code_string);
|
||||
free (validated);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void S9xLoadCheatsFromBMLNode (bml_node *n)
|
||||
{
|
||||
unsigned int i;
|
||||
@ -725,7 +751,7 @@ static void S9xLoadCheatsFromBMLNode (bml_node *n)
|
||||
if (bml_find_sub(c, "enabled"))
|
||||
enabled = true;
|
||||
|
||||
if (desc && code)
|
||||
if (desc && code && !S9xCheatIsDuplicate (desc, code))
|
||||
{
|
||||
int index = S9xAddCheatGroup (desc, code);
|
||||
|
||||
@ -878,7 +904,7 @@ void S9xCheatsEnable (void)
|
||||
}
|
||||
}
|
||||
|
||||
bool8 S9xImportCheatsFromDatabase (const char *filename)
|
||||
int S9xImportCheatsFromDatabase (const char *filename)
|
||||
{
|
||||
bml_node *bml;
|
||||
char sha256_txt[65];
|
||||
@ -888,7 +914,7 @@ bool8 S9xImportCheatsFromDatabase (const char *filename)
|
||||
bml = bml_parse_file (filename);
|
||||
|
||||
if (!bml)
|
||||
return FALSE;
|
||||
return -1; /* No file */
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
@ -909,7 +935,7 @@ bool8 S9xImportCheatsFromDatabase (const char *filename)
|
||||
{
|
||||
S9xLoadCheatsFromBMLNode (bml->child[i]);
|
||||
bml_free_node (bml);
|
||||
return TRUE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -917,5 +943,5 @@ bool8 S9xImportCheatsFromDatabase (const char *filename)
|
||||
|
||||
bml_free_node (bml);
|
||||
|
||||
return FALSE;
|
||||
return -2; /* No codes */
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ snes9x_gtk_CXXFLAGS = -fno-exceptions -fno-rtti
|
||||
endif
|
||||
noinst_LIBRARIES =
|
||||
|
||||
AM_CPPFLAGS = -I../apu/bapu -I$(top_srcdir) -I.. -DSNES9XLOCALEDIR=\""$(snes9xlocaledir)"\"
|
||||
AM_CPPFLAGS = -I../apu/bapu -I$(top_srcdir) -I.. -DDATADIR=\""$(snes9xdatadir)"\" -DSNES9XLOCALEDIR=\""$(snes9xlocaledir)"\"
|
||||
|
||||
CLEANFILES = \
|
||||
src/gtk_snes9x_ui.cpp \
|
||||
|
@ -34,7 +34,10 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE")
|
||||
AM_GLIB_GNU_GETTEXT
|
||||
|
||||
snes9xlocaledir='${prefix}/${DATADIRNAME}/locale'
|
||||
snes9xdatadir='${prefix}/${DATADIRNAME}/snes9x'
|
||||
|
||||
AC_SUBST(snes9xlocaledir)
|
||||
AC_SUBST(snes9xdatadir)
|
||||
|
||||
AC_ARG_WITH(debug,
|
||||
[AS_HELP_STRING([--with(out)-debug],
|
||||
@ -152,9 +155,9 @@ AC_ARG_WITH(screenshot,
|
||||
|
||||
AC_ARG_WITH(gtk3,
|
||||
[AS_HELP_STRING([--with(out)-gtk3],
|
||||
[Build with GTK+ 3 if available (default: without)])],
|
||||
[Build with GTK+ 3 if available (default: with)])],
|
||||
[],
|
||||
[with_gtk3=no])
|
||||
[with_gtk3=yes])
|
||||
|
||||
if test yes = "$with_debug" ; then
|
||||
CFLAGS="$CFLAGS -g"
|
||||
@ -499,7 +502,7 @@ echo "Snes9x will build with support for the following:"
|
||||
echo ""
|
||||
|
||||
if test yes = "$GTK3_WARNING" ; then
|
||||
echo " GTK+ 3.0 (experimental)"
|
||||
echo " GTK+ 3.0"
|
||||
else
|
||||
echo " GTK+ 2.0"
|
||||
fi
|
||||
|
@ -13,6 +13,9 @@ icon32x32_DATA = snes9x_32x32.png
|
||||
iconscalabledir = $(datadir)/icons/hicolor/scalable/apps
|
||||
iconscalable_DATA = snes9x.svg
|
||||
|
||||
cheatsdir = $(datadir)/snes9x
|
||||
cheats_DATA = ../../data/cheats.bml
|
||||
|
||||
install-data-hook:
|
||||
mv -f $(DESTDIR)$(datadir)/icons/hicolor/16x16/apps/snes9x_16x16.png \
|
||||
$(DESTDIR)$(datadir)/icons/hicolor/16x16/apps/snes9x.png
|
||||
|
@ -41,12 +41,37 @@ event_remove_code (GtkButton *button, gpointer data)
|
||||
((Snes9xCheats *) data)->remove_code ();
|
||||
}
|
||||
|
||||
static void
|
||||
event_search_database (GtkButton *button, gpointer data)
|
||||
{
|
||||
((Snes9xCheats *) data)->search_database ();
|
||||
}
|
||||
|
||||
static void
|
||||
event_delete_all_cheats (GtkButton *button, gpointer data)
|
||||
{
|
||||
((Snes9xCheats *) data)->delete_all_cheats ();
|
||||
}
|
||||
|
||||
static void
|
||||
event_code_toggled (GtkCellRendererToggle *cell_renderer,
|
||||
gchar *path,
|
||||
gpointer data)
|
||||
{
|
||||
((Snes9xCheats *) data)->toggle_code (path);
|
||||
int enabled = !gtk_cell_renderer_toggle_get_active (cell_renderer);
|
||||
|
||||
((Snes9xCheats *) data)->toggle_code (path, enabled);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
event_row_activated (GtkTreeView *tree_view,
|
||||
GtkTreePath *path,
|
||||
GtkTreeViewColumn *column,
|
||||
gpointer data)
|
||||
{
|
||||
((Snes9xCheats *) data)->row_activated (path);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -60,13 +85,17 @@ Snes9xCheats::Snes9xCheats (void)
|
||||
{
|
||||
{ "add_code", G_CALLBACK (event_add_code) },
|
||||
{ "remove_code", G_CALLBACK (event_remove_code) },
|
||||
{ "search_database", G_CALLBACK (event_search_database) },
|
||||
{ "delete_all_cheats", G_CALLBACK (event_delete_all_cheats) },
|
||||
{ NULL, NULL}
|
||||
};
|
||||
|
||||
view = GTK_TREE_VIEW (get_widget ("cheat_treeview"));
|
||||
|
||||
g_signal_connect (view, "row-activated", G_CALLBACK (event_row_activated), (gpointer) this);
|
||||
|
||||
renderer = gtk_cell_renderer_toggle_new ();
|
||||
gtk_cell_renderer_toggle_set_activatable (GTK_CELL_RENDERER_TOGGLE (renderer), TRUE);
|
||||
gtk_tree_view_insert_column_with_attributes (view,
|
||||
-1,
|
||||
"",
|
||||
@ -86,6 +115,8 @@ Snes9xCheats::Snes9xCheats (void)
|
||||
renderer,
|
||||
"text", COLUMN_DESCRIPTION,
|
||||
NULL);
|
||||
GtkTreeViewColumn *column = gtk_tree_view_get_column (view, 1);
|
||||
gtk_tree_view_column_set_resizable (column, TRUE);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
gtk_tree_view_insert_column_with_attributes (view,
|
||||
@ -94,6 +125,9 @@ Snes9xCheats::Snes9xCheats (void)
|
||||
renderer,
|
||||
"text", COLUMN_CHEAT,
|
||||
NULL);
|
||||
column = gtk_tree_view_get_column (view, 2);
|
||||
gtk_tree_view_column_set_resizable (column, TRUE);
|
||||
|
||||
|
||||
store = gtk_list_store_new (NUM_COLS,
|
||||
G_TYPE_BOOLEAN,
|
||||
@ -182,14 +216,25 @@ void
|
||||
Snes9xCheats::refresh_tree_view (void)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
unsigned int list_size;
|
||||
|
||||
gtk_list_store_clear (store);
|
||||
list_size = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL);
|
||||
|
||||
if (Cheat.g.size () == 0)
|
||||
return;
|
||||
|
||||
for (unsigned int i = 0; i < Cheat.g.size() - list_size; i++)
|
||||
gtk_list_store_append (store, &iter);
|
||||
|
||||
gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
|
||||
|
||||
for (unsigned int i = 0; i < Cheat.g.size (); i++)
|
||||
{
|
||||
char *str = S9xCheatGroupToText (i);
|
||||
|
||||
gtk_list_store_append (store, &iter);
|
||||
if (i > 0)
|
||||
gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
|
||||
|
||||
gtk_list_store_set (store, &iter,
|
||||
COLUMN_DESCRIPTION,
|
||||
!strcmp (Cheat.g [i].name, "") ? _("No description")
|
||||
@ -200,7 +245,6 @@ Snes9xCheats::refresh_tree_view (void)
|
||||
delete[] str;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -228,31 +272,127 @@ void
|
||||
Snes9xCheats::remove_code (void)
|
||||
{
|
||||
int index = get_selected_index ();
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
S9xDeleteCheatGroup (index);
|
||||
gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, NULL, index);
|
||||
gtk_list_store_remove (store, &iter);
|
||||
|
||||
refresh_tree_view ();
|
||||
S9xDeleteCheatGroup (index);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
Snes9xCheats::toggle_code (const gchar *path)
|
||||
Snes9xCheats::delete_all_cheats (void)
|
||||
{
|
||||
int index = get_index_from_path (path);
|
||||
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
if (Cheat.g[index].enabled)
|
||||
S9xDisableCheatGroup (index);
|
||||
else
|
||||
S9xEnableCheatGroup (index);
|
||||
|
||||
refresh_tree_view ();
|
||||
S9xDeleteCheats ();
|
||||
gtk_list_store_clear (store);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
Snes9xCheats::search_database (void)
|
||||
{
|
||||
std::string filename;
|
||||
int result;
|
||||
int reason = 0;
|
||||
|
||||
filename = S9xGetFilename ("cheats.bml", CHEAT_DIR);
|
||||
if (!(result = S9xImportCheatsFromDatabase (filename.c_str ())))
|
||||
{
|
||||
refresh_tree_view ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (result < reason)
|
||||
reason = result;
|
||||
|
||||
char *config_dir = get_config_dir ();
|
||||
filename = std::string (config_dir) + "/cheats.bml";
|
||||
free (config_dir);
|
||||
if (!(result = S9xImportCheatsFromDatabase (filename.c_str ())))
|
||||
{
|
||||
refresh_tree_view ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (result < reason)
|
||||
reason = result;
|
||||
|
||||
|
||||
filename = std::string (DATADIR) + "/cheats.bml";
|
||||
if (!(result = S9xImportCheatsFromDatabase (filename.c_str ())))
|
||||
{
|
||||
refresh_tree_view ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (result < reason)
|
||||
reason = result;
|
||||
|
||||
filename = S9xGetFilename ("cheats.bml", ROM_DIR);
|
||||
if (!(result = S9xImportCheatsFromDatabase (filename.c_str ())))
|
||||
{
|
||||
refresh_tree_view ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (result < reason)
|
||||
reason = result;
|
||||
|
||||
GtkMessageDialog *dialog;
|
||||
GtkDialogFlags flags = GTK_DIALOG_DESTROY_WITH_PARENT;
|
||||
dialog = GTK_MESSAGE_DIALOG (gtk_message_dialog_new (get_window (),
|
||||
flags,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
reason == -1 ? _("Couldn't Find Cheats Database") :
|
||||
_("No Matching Game Found")));
|
||||
gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG (dialog),
|
||||
reason == -1 ?
|
||||
_("The database file <b>cheats.bml</b> was not found. It is normally installed with "
|
||||
"Snes9x, but you may also place a custom copy in your configuration or cheats directory.") :
|
||||
_("No matching game was found in the databases. If you are using a non-official "
|
||||
"translation or modified copy, you may be able to find and manually enter the codes."));
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy (GTK_WIDGET (dialog));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
Snes9xCheats::row_activated (GtkTreePath *path)
|
||||
{
|
||||
gint *indices = gtk_tree_path_get_indices (path);
|
||||
char *cheat_text;
|
||||
|
||||
cheat_text = S9xCheatGroupToText (indices[0]);
|
||||
set_entry_text ("code_entry", cheat_text);
|
||||
delete[] cheat_text;
|
||||
set_entry_text ("description_entry", Cheat.g[indices[0]].name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
Snes9xCheats::toggle_code (const gchar *path, int enabled)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
int index = get_index_from_path (path);
|
||||
|
||||
GtkTreePath *treepath = gtk_tree_path_new_from_string (path);
|
||||
gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, treepath);
|
||||
gtk_list_store_set (store, &iter, COLUMN_ENABLED, enabled, -1);
|
||||
|
||||
if (enabled)
|
||||
S9xEnableCheatGroup (index);
|
||||
else
|
||||
S9xDisableCheatGroup (index);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -15,7 +15,10 @@ class Snes9xCheats : public GtkBuilderWindow
|
||||
void show (void);
|
||||
void add_code (void);
|
||||
void remove_code (void);
|
||||
void toggle_code (const gchar *path);
|
||||
void search_database (void);
|
||||
void delete_all_cheats (void);
|
||||
void toggle_code (const gchar *path, int enabled);
|
||||
void row_activated (GtkTreePath *path);
|
||||
|
||||
private:
|
||||
void refresh_tree_view (void);
|
||||
|
@ -256,8 +256,8 @@
|
||||
<property name="page_increment">0.10000000000000001</property>
|
||||
</object>
|
||||
<object class="GtkDialog" id="cheat_window">
|
||||
<property name="width_request">512</property>
|
||||
<property name="height_request">350</property>
|
||||
<property name="width_request">720</property>
|
||||
<property name="height_request">480</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="border_width">5</property>
|
||||
@ -438,6 +438,36 @@
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="delete_all_cheats_button">
|
||||
<property name="label" translatable="yes">Delete All Cheats</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal name="clicked" handler="delete_all_cheats" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="cheat_search_button">
|
||||
<property name="label" translatable="yes">Search Cheat Database</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal name="clicked" handler="search_database" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">7</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
Loading…
Reference in New Issue
Block a user