pcsxr-1.9.92
[pcsx_rearmed.git] / gui / Cheat.c
CommitLineData
ef79bbde
P
1/* Cheat Support for PCSX-Reloaded
2 * Copyright (C) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA
17 */
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22#include <stdint.h>
23
24#include <gdk/gdkkeysyms.h>
25#include <gtk/gtk.h>
26#include <glade/glade.h>
27
28#include "Linux.h"
29
30#include "../libpcsxcore/cheat.h"
31#include "../libpcsxcore/psxmem.h"
32
33GtkWidget *CheatListDlg = NULL;
34GtkWidget *CheatSearchDlg = NULL;
35
36static void LoadCheatListItems(int index) {
37 GtkListStore *store = gtk_list_store_new(2, G_TYPE_BOOLEAN, G_TYPE_STRING);
38 GtkTreeIter iter;
39 GtkWidget *widget;
40 GladeXML *xml;
41
42 int i;
43
44 xml = glade_get_widget_tree(CheatListDlg);
45 widget = glade_xml_get_widget(xml, "GtkCList_Cheat");
46
47 for (i = 0; i < NumCheats; i++) {
48 gtk_list_store_append(store, &iter);
49 gtk_list_store_set(store, &iter, 0, Cheats[i].Enabled, 1, Cheats[i].Descr, -1);
50 }
51
52 gtk_tree_view_set_model(GTK_TREE_VIEW(widget), GTK_TREE_MODEL(store));
53 g_object_unref(G_OBJECT(store));
54 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(widget), TRUE);
55 gtk_widget_show(widget);
56
57 if (index >= NumCheats) {
58 index = NumCheats - 1;
59 }
60
61 if (index >= 0) {
62 GtkTreePath *path;
63 GtkTreeSelection *sel;
64
65 path = gtk_tree_path_new_from_indices(index, -1);
66 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
67
68 gtk_tree_selection_select_path(sel, path);
69 gtk_tree_path_free(path);
70 }
71}
72
73static void CheatList_TreeSelectionChanged(GtkTreeSelection *selection, gpointer user_data) {
74 GladeXML *xml;
75 GtkTreeIter iter;
76 GtkTreeModel *model;
77 GtkTreePath *path;
78
79 gboolean selected;
80 int i;
81
82 selected = gtk_tree_selection_get_selected(selection, &model, &iter);
83
84 if (selected) {
85 path = gtk_tree_model_get_path(model, &iter);
86 i = *gtk_tree_path_get_indices(path);
87 gtk_tree_path_free(path);
88
89 // If a row was selected, and the row is not blank, we can now enable
90 // some of the disabled widgets
91 xml = glade_get_widget_tree(CheatListDlg);
92
93 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "editbutton1")), TRUE);
94 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "delbutton1")), TRUE);
95 } else {
96 xml = glade_get_widget_tree(CheatListDlg);
97
98 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "editbutton1")), FALSE);
99 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "delbutton1")), FALSE);
100 }
101
102 gtk_widget_set_sensitive (GTK_WIDGET(glade_xml_get_widget(xml, "savebutton1")), NumCheats);
103}
104
105static void OnCheatListDlg_AddClicked(GtkWidget *widget, gpointer user_data) {
106 GtkWidget *dlg;
107 GtkWidget *box, *scroll, *label, *descr_edit, *code_edit;
108
109 dlg = gtk_dialog_new_with_buttons(_("Add New Cheat"), GTK_WINDOW(CheatListDlg),
110 GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
111 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
112
113 gtk_window_set_default_size(GTK_WINDOW(dlg), 350, 350);
114
115 box = GTK_WIDGET(GTK_DIALOG(dlg)->vbox);
116
117 label = gtk_label_new(_("Cheat Description:"));
118 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 5);
119 gtk_widget_show(label);
120
121 descr_edit = gtk_entry_new();
122 gtk_box_pack_start(GTK_BOX(box), descr_edit, FALSE, FALSE, 5);
123 gtk_widget_show(descr_edit);
124
125 label = gtk_label_new(_("Cheat Code:"));
126 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 5);
127 gtk_widget_show(label);
128
129 code_edit = gtk_text_view_new();
130 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(code_edit), GTK_WRAP_CHAR);
131
132 scroll = gtk_scrolled_window_new(NULL, NULL);
133 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
134 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
135
136 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), code_edit);
137 gtk_widget_show(code_edit);
138
139 gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 5);
140 gtk_widget_show(scroll);
141
142 gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
143
144 gtk_widget_show_all(dlg);
145
146 if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_ACCEPT) {
147 GtkTextBuffer *b = gtk_text_view_get_buffer(GTK_TEXT_VIEW(code_edit));
148 GtkTextIter s, e;
149 char *codetext;
150
151 gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(b), &s, &e);
152 codetext = strdup(gtk_text_buffer_get_text(GTK_TEXT_BUFFER(b), &s, &e, FALSE));
153
154 if (AddCheat(gtk_entry_get_text(GTK_ENTRY(descr_edit)), codetext) != 0) {
155 SysErrorMessage(_("Error"), _("Invalid cheat code!"));
156 }
157
158 LoadCheatListItems(NumCheats - 1);
159
160 free(codetext);
161 }
162
163 gtk_widget_destroy(dlg);
164}
165
166static void OnCheatListDlg_EditClicked(GtkWidget *widget, gpointer user_data) {
167 GtkWidget *dlg;
168 GtkWidget *box, *scroll, *label, *descr_edit, *code_edit;
169 GladeXML *xml;
170 GtkTreeIter iter;
171 GtkTreeModel *model;
172 GtkTreePath *path;
173
174 gboolean selected;
175 int index, i;
176 char buf[8192];
177 char *p = buf;
178
179 xml = glade_get_widget_tree(CheatListDlg);
180 widget = glade_xml_get_widget(xml, "GtkCList_Cheat");
181
182 selected = gtk_tree_selection_get_selected(
183 gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)),
184 &model, &iter);
185
186 if (!selected) {
187 return;
188 }
189
190 path = gtk_tree_model_get_path(model, &iter);
191 index = *gtk_tree_path_get_indices(path);
192 gtk_tree_path_free(path);
193
194 dlg = gtk_dialog_new_with_buttons(_("Edit Cheat"), GTK_WINDOW(CheatListDlg),
195 GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
196 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
197
198 gtk_window_set_default_size(GTK_WINDOW(dlg), 350, 350);
199
200 box = GTK_WIDGET(GTK_DIALOG(dlg)->vbox);
201
202 label = gtk_label_new(_("Cheat Description:"));
203 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 5);
204 gtk_widget_show(label);
205
206 descr_edit = gtk_entry_new();
207 gtk_entry_set_text(GTK_ENTRY(descr_edit), Cheats[index].Descr);
208 gtk_box_pack_start(GTK_BOX(box), descr_edit, FALSE, FALSE, 5);
209 gtk_widget_show(descr_edit);
210
211 label = gtk_label_new(_("Cheat Code:"));
212 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 5);
213 gtk_widget_show(label);
214
215 code_edit = gtk_text_view_new();
216
217 for (i = Cheats[index].First; i < Cheats[index].First + Cheats[index].n; i++) {
218 sprintf(p, "%.8X %.4X\n", CheatCodes[i].Addr, CheatCodes[i].Val);
219 p += 14;
220 *p = '\0';
221 }
222
223 gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(code_edit)),
224 buf, -1);
225
226 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(code_edit), GTK_WRAP_CHAR);
227
228 scroll = gtk_scrolled_window_new(NULL, NULL);
229 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
230 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
231
232 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), code_edit);
233 gtk_widget_show(code_edit);
234
235 gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 5);
236 gtk_widget_show(scroll);
237
238 gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
239
240 gtk_widget_show_all(dlg);
241
242 if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_ACCEPT) {
243 GtkTextBuffer *b = gtk_text_view_get_buffer(GTK_TEXT_VIEW(code_edit));
244 GtkTextIter s, e;
245 char *codetext;
246
247 gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(b), &s, &e);
248 codetext = strdup(gtk_text_buffer_get_text(GTK_TEXT_BUFFER(b), &s, &e, FALSE));
249
250 if (EditCheat(index, gtk_entry_get_text(GTK_ENTRY(descr_edit)), codetext) != 0) {
251 SysErrorMessage(_("Error"), _("Invalid cheat code!"));
252 }
253
254 LoadCheatListItems(index);
255
256 free(codetext);
257 }
258
259 gtk_widget_destroy(dlg);
260}
261
262static void OnCheatListDlg_DelClicked(GtkWidget *widget, gpointer user_data) {
263 GladeXML *xml;
264 GtkTreeIter iter;
265 GtkTreeModel *model;
266 GtkTreePath *path;
267
268 gboolean selected;
269 int i = -1;
270
271 xml = glade_get_widget_tree(CheatListDlg);
272 widget = glade_xml_get_widget(xml, "GtkCList_Cheat");
273
274 selected = gtk_tree_selection_get_selected(
275 gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)),
276 &model, &iter);
277
278 if (selected) {
279 path = gtk_tree_model_get_path(model, &iter);
280 i = *gtk_tree_path_get_indices(path);
281 gtk_tree_path_free(path);
282
283 RemoveCheat(i);
284 }
285
286 LoadCheatListItems(i); // FIXME: should remove it from the list directly
287 // rather than regenerating the whole list
288}
289
290static void OnCheatListDlg_EnableToggled(GtkWidget *widget, gchar *path, gpointer user_data) {
291 int i = atoi(path);
292
293 assert(i >= 0 && i < NumCheats);
294 Cheats[i].Enabled ^= 1;
295
296 LoadCheatListItems(i); // FIXME: should modify it in the list directly
297 // rather than regenerating the whole list
298}
299
300static void OnCheatListDlg_OpenClicked(GtkWidget *widget, gpointer user_data) {
301 GtkWidget *chooser;
302 gchar *filename;
303
304 GtkFileFilter *filter;
305
306 chooser = gtk_file_chooser_dialog_new (_("Open Cheat File"),
307 NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
308 GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
309
310 filename = g_build_filename(getenv("HOME"), CHEATS_DIR, NULL);
311 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser), filename);
312 g_free(filename);
313
314 filter = gtk_file_filter_new ();
315 gtk_file_filter_add_pattern (filter, "*.cht");
316 gtk_file_filter_set_name (filter, _("PCSX Cheat Code Files (*.cht)"));
317 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
318
319 filter = gtk_file_filter_new ();
320 gtk_file_filter_add_pattern (filter, "*");
321 gtk_file_filter_set_name (filter, _("All Files"));
322 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
323
324 if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_OK) {
325 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
326 gtk_widget_destroy (GTK_WIDGET (chooser));
327 while (gtk_events_pending()) gtk_main_iteration();
328 } else {
329 gtk_widget_destroy (GTK_WIDGET (chooser));
330 while (gtk_events_pending()) gtk_main_iteration();
331 return;
332 }
333
334 LoadCheats(filename);
335
336 g_free(filename);
337
338 LoadCheatListItems(-1);
339}
340
341static void OnCheatListDlg_SaveClicked(GtkWidget *widget, gpointer user_data) {
342 GtkWidget *chooser;
343 gchar *filename;
344 GtkFileFilter *filter;
345
346 chooser = gtk_file_chooser_dialog_new(_("Save Cheat File"),
347 NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
348 GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
349
350 filename = g_build_filename(getenv("HOME"), CHEATS_DIR, NULL);
351 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(chooser), filename);
352 g_free(filename);
353
354 filter = gtk_file_filter_new();
355 gtk_file_filter_add_pattern(filter, "*.cht");
356 gtk_file_filter_set_name(filter, _("PCSX Cheat Code Files (*.cht)"));
357 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(chooser), filter);
358
359 filter = gtk_file_filter_new();
360 gtk_file_filter_add_pattern(filter, "*");
361 gtk_file_filter_set_name(filter, _("All Files (*.*)"));
362 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(chooser), filter);
363
364 if (gtk_dialog_run(GTK_DIALOG(chooser)) == GTK_RESPONSE_OK) {
365 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
366 gtk_widget_destroy (GTK_WIDGET(chooser));
367 while (gtk_events_pending()) gtk_main_iteration();
368 } else {
369 gtk_widget_destroy (GTK_WIDGET(chooser));
370 while (gtk_events_pending()) gtk_main_iteration();
371 return;
372 }
373
374 SaveCheats(filename);
375
376 g_free(filename);
377}
378
379static void OnCheatListDlg_CloseClicked() {
380 gtk_widget_destroy(CheatListDlg);
381 CheatListDlg = NULL;
382}
383
384// run the cheat list dialog
385void RunCheatListDialog() {
386 GladeXML *xml;
387 GtkWidget *widget;
388 GtkTreeSelection *treesel;
389 GtkTreeViewColumn *column;
390 GtkCellRenderer *renderer;
391
392 xml = glade_xml_new(PACKAGE_DATA_DIR "pcsx.glade2", "CheatListDlg", NULL);
393 if (!xml) {
394 g_warning(_("Error: Glade interface could not be loaded!"));
395 return;
396 }
397
398 CheatListDlg = glade_xml_get_widget(xml, "CheatListDlg");
399 gtk_window_set_title(GTK_WINDOW(CheatListDlg), _("Cheat Codes"));
400
401 widget = glade_xml_get_widget(xml, "GtkCList_Cheat");
402
403 // column for enable
404 renderer = gtk_cell_renderer_toggle_new();
405 column = gtk_tree_view_column_new_with_attributes(_("Enable"),
406 renderer, "active", 0, NULL);
407 gtk_tree_view_append_column(GTK_TREE_VIEW(widget), column);
408
409 g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(OnCheatListDlg_EnableToggled), 0);
410
411 // column for description
412 renderer = gtk_cell_renderer_text_new();
413 column = gtk_tree_view_column_new_with_attributes(_("Description"),
414 renderer, "text", 1, NULL);
415 gtk_tree_view_append_column(GTK_TREE_VIEW(widget), column);
416
417 LoadCheatListItems(-1);
418
419 treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
420 gtk_tree_selection_set_mode(treesel, GTK_SELECTION_SINGLE);
421 g_signal_connect_data(G_OBJECT (treesel), "changed",
422 G_CALLBACK (CheatList_TreeSelectionChanged),
423 NULL, NULL, G_CONNECT_AFTER);
424
425 widget = glade_xml_get_widget(xml, "addbutton1");
426 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
427 GTK_SIGNAL_FUNC(OnCheatListDlg_AddClicked), xml, NULL, G_CONNECT_AFTER);
428
429 widget = glade_xml_get_widget(xml, "editbutton1");
430 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
431 GTK_SIGNAL_FUNC(OnCheatListDlg_EditClicked), xml, NULL, G_CONNECT_AFTER);
432
433 widget = glade_xml_get_widget(xml, "delbutton1");
434 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
435 GTK_SIGNAL_FUNC(OnCheatListDlg_DelClicked), xml, NULL, G_CONNECT_AFTER);
436
437 widget = glade_xml_get_widget(xml, "loadbutton1");
438 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
439 GTK_SIGNAL_FUNC(OnCheatListDlg_OpenClicked), xml, NULL, G_CONNECT_AFTER);
440
441 widget = glade_xml_get_widget(xml, "savebutton1");
442 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
443 GTK_SIGNAL_FUNC(OnCheatListDlg_SaveClicked), xml, NULL, G_CONNECT_AFTER);
444
445 // Setup a handler for when Close or Cancel is clicked
446 g_signal_connect_data(GTK_OBJECT(CheatListDlg), "response",
447 GTK_SIGNAL_FUNC(OnCheatListDlg_CloseClicked), xml, (GClosureNotify)g_object_unref, G_CONNECT_AFTER);
448
449 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "savebutton1")), NumCheats);
450 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "editbutton1")), FALSE);
451 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "delbutton1")), FALSE);
452 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "editbutton1")), FALSE);
453}
454
455///////////////////////////////////////////////////////////////////////////////
456
457#define SEARCH_EQUALVAL 0
458#define SEARCH_NOTEQUALVAL 1
459#define SEARCH_RANGE 2
460#define SEARCH_INCBY 3
461#define SEARCH_DECBY 4
462#define SEARCH_INC 5
463#define SEARCH_DEC 6
464#define SEARCH_DIFFERENT 7
465#define SEARCH_NOCHANGE 8
466
467#define SEARCHTYPE_8BIT 0
468#define SEARCHTYPE_16BIT 1
469#define SEARCHTYPE_32BIT 2
470
471#define SEARCHBASE_DEC 0
472#define SEARCHBASE_HEX 1
473
474static char current_search = SEARCH_EQUALVAL;
475static char current_searchtype = SEARCHTYPE_8BIT;
476static char current_searchbase = SEARCHBASE_DEC;
477static uint32_t current_valuefrom = 0;
478static uint32_t current_valueto = 0;
479
480// update the cheat search dialog
481static void UpdateCheatSearchDialog() {
482 GladeXML *xml;
483 char buf[256];
484 int i;
485 u32 addr;
486 GtkListStore *store = gtk_list_store_new(1, G_TYPE_STRING);
487 GtkTreeIter iter;
488 GtkWidget *widget;
489
490 xml = glade_get_widget_tree(CheatSearchDlg);
491 widget = glade_xml_get_widget(xml, "GtkCList_Result");
492
493 gtk_combo_box_set_active(GTK_COMBO_BOX(glade_xml_get_widget(xml, "combo_searchfor")), current_search);
494 gtk_combo_box_set_active(GTK_COMBO_BOX(glade_xml_get_widget(xml, "combo_datatype")), current_searchtype);
495 gtk_combo_box_set_active(GTK_COMBO_BOX(glade_xml_get_widget(xml, "combo_database")), current_searchbase);
496
497 if (current_searchbase == SEARCHBASE_DEC) {
498 sprintf(buf, "%u", current_valuefrom);
499 gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_value")), buf);
500 sprintf(buf, "%u", current_valueto);
501 gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_valueto")), buf);
502 }
503 else {
504 sprintf(buf, "%X", current_valuefrom);
505 gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_value")), buf);
506 sprintf(buf, "%X", current_valueto);
507 gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_valueto")), buf);
508 }
509
510 if (current_search == SEARCH_RANGE) {
511 gtk_widget_show(GTK_WIDGET(glade_xml_get_widget(xml, "label_valueto")));
512 gtk_widget_show(GTK_WIDGET(glade_xml_get_widget(xml, "entry_valueto")));
513 }
514 else {
515 gtk_widget_hide(GTK_WIDGET(glade_xml_get_widget(xml, "label_valueto")));
516 gtk_widget_hide(GTK_WIDGET(glade_xml_get_widget(xml, "entry_valueto")));
517 }
518
519 if (current_search >= SEARCH_INC) {
520 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "entry_value")), FALSE);
521 }
522 else {
523 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "entry_value")), TRUE);
524 }
525
526 if (current_search >= SEARCH_INCBY && prevM == NULL) {
527 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "btn_start")), FALSE);
528 }
529 else {
530 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "btn_start")), TRUE);
531 }
532
533 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "btn_freeze")), FALSE);
534 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "btn_modify")), FALSE);
535 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "btn_copy")), FALSE);
536
537 if (prevM != NULL) {
538 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "combo_datatype")), FALSE);
539
540 if (NumSearchResults > 100) {
541 // too many results to be shown
542 gtk_list_store_append(store, &iter);
543 gtk_list_store_set(store, &iter, 0, _("Too many addresses found."), -1);
544 gtk_widget_set_sensitive(widget, FALSE);
545 }
546 else {
547 for (i = 0; i < NumSearchResults; i++) {
548 addr = SearchResults[i];
549
550 switch (current_searchtype) {
551 case SEARCHTYPE_8BIT:
552 sprintf(buf, _("%.8X Current: %u (%.2X), Previous: %u (%.2X)"),
553 addr, PSXMu8(addr), PSXMu8(addr), PrevMu8(addr), PrevMu8(addr));
554 break;
555
556 case SEARCHTYPE_16BIT:
557 sprintf(buf, _("%.8X Current: %u (%.4X), Previous: %u (%.4X)"),
558 addr, PSXMu16(addr), PSXMu16(addr), PrevMu16(addr), PrevMu16(addr));
559 break;
560
561 case SEARCHTYPE_32BIT:
562 sprintf(buf, _("%.8X Current: %u (%.8X), Previous: %u (%.8X)"),
563 addr, PSXMu32(addr), PSXMu32(addr), PrevMu32(addr), PrevMu32(addr));
564 break;
565
566 default:
567 assert(FALSE); // impossible
568 break;
569 }
570
571 gtk_list_store_append(store, &iter);
572 gtk_list_store_set(store, &iter, 0, buf, -1);
573 }
574 gtk_widget_set_sensitive(widget, TRUE);
575 }
576
577 sprintf(buf, _("Founded Addresses: %d"), NumSearchResults);
578 gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(xml, "label_resultsfound")), buf);
579 }
580 else {
581 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "combo_datatype")), TRUE);
582 gtk_widget_set_sensitive(widget, FALSE);
583
584 gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(xml, "label_resultsfound")),
585 _("Enter the values and start your search."));
586 }
587
588 gtk_tree_view_set_model(GTK_TREE_VIEW(widget), GTK_TREE_MODEL(store));
589 g_object_unref(G_OBJECT(store));
590 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(widget), TRUE);
591 gtk_widget_show(widget);
592}
593
594// get the current selected result index in the list
595static int GetSelectedResultIndex() {
596 GladeXML *xml;
597 GtkTreeSelection *selection;
598 GtkTreeIter iter;
599 GtkTreeModel *model;
600 GtkTreePath *path;
601 gboolean selected;
602 int i;
603
604 xml = glade_get_widget_tree(CheatSearchDlg);
605
606 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(glade_xml_get_widget(xml, "GtkCList_Result")));
607 selected = gtk_tree_selection_get_selected(selection, &model, &iter);
608
609 if (!selected) {
610 return -1;
611 }
612
613 path = gtk_tree_model_get_path(model, &iter);
614 i = *gtk_tree_path_get_indices(path);
615 gtk_tree_path_free(path);
616
617 assert(i < NumSearchResults);
618 return i;
619}
620
621// add cheat code to freeze the value
622static void OnCheatSearchDlg_FreezeClicked(GtkWidget *widget, gpointer user_data) {
623 GtkWidget *dlg;
624 GtkWidget *box, *hbox, *label, *descr_edit, *value_edit;
625 char buf[256];
626 u32 addr, val = 0;
627
628 addr = SearchResults[GetSelectedResultIndex()];
629
630 dlg = gtk_dialog_new_with_buttons(_("Freeze value"), GTK_WINDOW(CheatListDlg),
631 GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
632 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
633
634 box = GTK_WIDGET(GTK_DIALOG(dlg)->vbox);
635
636 label = gtk_label_new(_("Description:"));
637 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 5);
638 gtk_widget_show(label);
639
640 descr_edit = gtk_entry_new();
641 gtk_box_pack_start(GTK_BOX(box), descr_edit, FALSE, FALSE, 10);
642 gtk_widget_show(descr_edit);
643
644 hbox = gtk_hbox_new(FALSE, 0);
645 gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 15);
646
647 label = gtk_label_new(_("Value:"));
648 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
649 gtk_widget_show(label);
650
651 value_edit = gtk_entry_new();
652 gtk_box_pack_start(GTK_BOX(hbox), value_edit, FALSE, FALSE, 10);
653 gtk_widget_show(value_edit);
654
655 switch (current_searchtype) {
656 case SEARCHTYPE_8BIT:
657 val = PSXMu8(addr);
658 break;
659
660 case SEARCHTYPE_16BIT:
661 val = PSXMu16(addr);
662 break;
663
664 case SEARCHTYPE_32BIT:
665 val = PSXMu32(addr);
666 break;
667
668 default:
669 assert(FALSE); // should not reach here
670 break;
671 }
672
673 sprintf(buf, "%u", val);
674 gtk_entry_set_text(GTK_ENTRY(value_edit), buf);
675
676 sprintf(buf, "%.8X", addr);
677 gtk_entry_set_text(GTK_ENTRY(descr_edit), buf);
678
679 gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
680 gtk_widget_show_all(dlg);
681
682 if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_ACCEPT) {
683 val = 0;
684 sscanf(gtk_entry_get_text(GTK_ENTRY(value_edit)), "%u", &val);
685
686 switch (current_searchtype) {
687 case SEARCHTYPE_8BIT:
688 if (val > (u32)0xFF) {
689 val = 0xFF;
690 }
691 sprintf(buf, "%.8X %.4X", (addr & 0x1FFFFF) | (CHEAT_CONST8 << 24), val);
692 break;
693
694 case SEARCHTYPE_16BIT:
695 if (val > (u32)0xFFFF) {
696 val = 0xFFFF;
697 }
698 sprintf(buf, "%.8X %.4X", (addr & 0x1FFFFF) | (CHEAT_CONST16 << 24), val);
699 break;
700
701 case SEARCHTYPE_32BIT:
702 sprintf(buf, "%.8X %.4X\n%.8X %.4X",
703 (addr & 0x1FFFFF) | (CHEAT_CONST16 << 24), val & 0xFFFF,
704 ((addr + 2) & 0x1FFFFF) | (CHEAT_CONST16 << 24), ((val & 0xFFFF0000) >> 16) & 0xFFFF);
705 break;
706
707 default:
708 assert(FALSE); // should not reach here
709 break;
710 }
711
712 if (AddCheat(gtk_entry_get_text(GTK_ENTRY(descr_edit)), buf) == 0) {
713 Cheats[NumCheats - 1].Enabled = 1;
714 }
715 }
716
717 gtk_widget_destroy(dlg);
718}
719
720// modify the value on the fly
721static void OnCheatSearchDlg_ModifyClicked(GtkWidget *widget, gpointer user_data) {
722 GtkWidget *dlg;
723 GtkWidget *box, *hbox, *label, *value_edit;
724 char buf[256];
725 u32 addr, val = 0;
726
727 addr = SearchResults[GetSelectedResultIndex()];
728
729 dlg = gtk_dialog_new_with_buttons(_("Modify value"), GTK_WINDOW(CheatListDlg),
730 GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
731 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
732
733 box = GTK_WIDGET(GTK_DIALOG(dlg)->vbox);
734 hbox = gtk_hbox_new(FALSE, 0);
735 gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 5);
736
737 label = gtk_label_new(_("New value:"));
738 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
739 gtk_widget_show(label);
740
741 value_edit = gtk_entry_new();
742 gtk_box_pack_start(GTK_BOX(hbox), value_edit, FALSE, FALSE, 10);
743 gtk_widget_show(value_edit);
744
745 switch (current_searchtype) {
746 case SEARCHTYPE_8BIT:
747 val = PSXMu8(addr);
748 break;
749
750 case SEARCHTYPE_16BIT:
751 val = PSXMu16(addr);
752 break;
753
754 case SEARCHTYPE_32BIT:
755 val = PSXMu32(addr);
756 break;
757
758 default:
759 assert(FALSE); // should not reach here
760 break;
761 }
762
763 sprintf(buf, "%u", val);
764 gtk_entry_set_text(GTK_ENTRY(value_edit), buf);
765
766 gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
767 gtk_widget_show_all(dlg);
768
769 if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_ACCEPT) {
770 val = 0;
771 sscanf(gtk_entry_get_text(GTK_ENTRY(value_edit)), "%u", &val);
772
773 switch (current_searchtype) {
774 case SEARCHTYPE_8BIT:
775 if (val > 0xFF) {
776 val = 0xFF;
777 }
778 psxMemWrite8(addr, (u8)val);
779 break;
780
781 case SEARCHTYPE_16BIT:
782 if (val > 0xFFFF) {
783 val = 0xFFFF;
784 }
785 psxMemWrite16(addr, (u16)val);
786 break;
787
788 case SEARCHTYPE_32BIT:
789 psxMemWrite32(addr, (u32)val);
790 break;
791
792 default:
793 assert(FALSE); // should not reach here
794 break;
795 }
796
797 UpdateCheatSearchDialog();
798 }
799
800 gtk_widget_destroy(dlg);
801}
802
803// copy the selected address to clipboard
804static void OnCheatSearchDlg_CopyClicked(GtkWidget *widget, gpointer user_data) {
805 int i;
806 char buf[9];
807
808 i = GetSelectedResultIndex();
809 assert(i != -1);
810
811 sprintf(buf, "%8X", SearchResults[i]);
812 buf[8] = '\0';
813
814 gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), buf, 8);
815}
816
817// preform the search
818static void OnCheatSearchDlg_SearchClicked(GtkWidget *widget, gpointer user_data) {
819 GladeXML *xml;
820
821 xml = glade_get_widget_tree(CheatSearchDlg);
822
823 current_search = gtk_combo_box_get_active(GTK_COMBO_BOX(glade_xml_get_widget(xml, "combo_searchfor")));
824 current_searchtype = gtk_combo_box_get_active(GTK_COMBO_BOX(glade_xml_get_widget(xml, "combo_datatype")));
825 current_searchbase = gtk_combo_box_get_active(GTK_COMBO_BOX(glade_xml_get_widget(xml, "combo_database")));
826 current_valuefrom = 0;
827 current_valueto = 0;
828
829 if (current_searchbase == SEARCHBASE_DEC) {
830 sscanf(gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_value"))), "%u", &current_valuefrom);
831 sscanf(gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_valueto"))), "%u", &current_valueto);
832 }
833 else {
834 sscanf(gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_value"))), "%x", &current_valuefrom);
835 sscanf(gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_valueto"))), "%x", &current_valueto);
836 }
837
838 switch (current_searchtype) {
839 case SEARCHTYPE_8BIT:
840 if (current_valuefrom > (u32)0xFF) {
841 current_valuefrom = 0xFF;
842 }
843 if (current_valueto > (u32)0xFF) {
844 current_valueto = 0xFF;
845 }
846 break;
847
848 case SEARCHTYPE_16BIT:
849 if (current_valuefrom > (u32)0xFFFF) {
850 current_valuefrom = 0xFFFF;
851 }
852 if (current_valueto > (u32)0xFFFF) {
853 current_valueto = 0xFFFF;
854 }
855 break;
856 }
857
858 if (current_search == SEARCH_RANGE && current_valuefrom > current_valueto) {
859 u32 t = current_valuefrom;
860 current_valuefrom = current_valueto;
861 current_valueto = t;
862 }
863
864 switch (current_search) {
865 case SEARCH_EQUALVAL:
866 switch (current_searchtype) {
867 case SEARCHTYPE_8BIT:
868 CheatSearchEqual8((u8)current_valuefrom);
869 break;
870
871 case SEARCHTYPE_16BIT:
872 CheatSearchEqual16((u16)current_valuefrom);
873 break;
874
875 case SEARCHTYPE_32BIT:
876 CheatSearchEqual32((u32)current_valuefrom);
877 break;
878 }
879 break;
880
881 case SEARCH_NOTEQUALVAL:
882 switch (current_searchtype) {
883 case SEARCHTYPE_8BIT:
884 CheatSearchNotEqual8((u8)current_valuefrom);
885 break;
886
887 case SEARCHTYPE_16BIT:
888 CheatSearchNotEqual16((u16)current_valuefrom);
889 break;
890
891 case SEARCHTYPE_32BIT:
892 CheatSearchNotEqual32((u32)current_valuefrom);
893 break;
894 }
895 break;
896
897 case SEARCH_RANGE:
898 switch (current_searchtype) {
899 case SEARCHTYPE_8BIT:
900 CheatSearchRange8((u8)current_valuefrom, (u8)current_valueto);
901 break;
902
903 case SEARCHTYPE_16BIT:
904 CheatSearchRange16((u16)current_valuefrom, (u16)current_valueto);
905 break;
906
907 case SEARCHTYPE_32BIT:
908 CheatSearchRange32((u32)current_valuefrom, (u32)current_valueto);
909 break;
910 }
911 break;
912
913 case SEARCH_INCBY:
914 switch (current_searchtype) {
915 case SEARCHTYPE_8BIT:
916 CheatSearchIncreasedBy8((u8)current_valuefrom);
917 break;
918
919 case SEARCHTYPE_16BIT:
920 CheatSearchIncreasedBy16((u16)current_valuefrom);
921 break;
922
923 case SEARCHTYPE_32BIT:
924 CheatSearchIncreasedBy32((u32)current_valuefrom);
925 break;
926 }
927 break;
928
929 case SEARCH_DECBY:
930 switch (current_searchtype) {
931 case SEARCHTYPE_8BIT:
932 CheatSearchDecreasedBy8((u8)current_valuefrom);
933 break;
934
935 case SEARCHTYPE_16BIT:
936 CheatSearchDecreasedBy16((u16)current_valuefrom);
937 break;
938
939 case SEARCHTYPE_32BIT:
940 CheatSearchDecreasedBy32((u32)current_valuefrom);
941 break;
942 }
943 break;
944
945 case SEARCH_INC:
946 switch (current_searchtype) {
947 case SEARCHTYPE_8BIT:
948 CheatSearchIncreased8();
949 break;
950
951 case SEARCHTYPE_16BIT:
952 CheatSearchIncreased16();
953 break;
954
955 case SEARCHTYPE_32BIT:
956 CheatSearchIncreased32();
957 break;
958 }
959 break;
960
961 case SEARCH_DEC:
962 switch (current_searchtype) {
963 case SEARCHTYPE_8BIT:
964 CheatSearchDecreased8();
965 break;
966
967 case SEARCHTYPE_16BIT:
968 CheatSearchDecreased16();
969 break;
970
971 case SEARCHTYPE_32BIT:
972 CheatSearchDecreased32();
973 break;
974 }
975 break;
976
977 case SEARCH_DIFFERENT:
978 switch (current_searchtype) {
979 case SEARCHTYPE_8BIT:
980 CheatSearchDifferent8();
981 break;
982
983 case SEARCHTYPE_16BIT:
984 CheatSearchDifferent16();
985 break;
986
987 case SEARCHTYPE_32BIT:
988 CheatSearchDifferent32();
989 break;
990 }
991 break;
992
993 case SEARCH_NOCHANGE:
994 switch (current_searchtype) {
995 case SEARCHTYPE_8BIT:
996 CheatSearchNoChange8();
997 break;
998
999 case SEARCHTYPE_16BIT:
1000 CheatSearchNoChange16();
1001 break;
1002
1003 case SEARCHTYPE_32BIT:
1004 CheatSearchNoChange32();
1005 break;
1006 }
1007 break;
1008
1009 default:
1010 assert(FALSE); // not possible
1011 break;
1012 }
1013
1014 UpdateCheatSearchDialog();
1015}
1016
1017// restart the search
1018static void OnCheatSearchDlg_RestartClicked(GtkWidget *widget, gpointer user_data) {
1019 FreeCheatSearchResults();
1020 FreeCheatSearchMem();
1021
1022 current_search = SEARCH_EQUALVAL;
1023 current_searchtype = SEARCHTYPE_8BIT;
1024 current_searchbase = SEARCHBASE_DEC;
1025 current_valuefrom = 0;
1026 current_valueto = 0;
1027
1028 UpdateCheatSearchDialog();
1029}
1030
1031// close the cheat search window
1032static void OnCheatSearchDlg_CloseClicked(GtkWidget *widget, gpointer user_data) {
1033 gtk_widget_destroy(CheatSearchDlg);
1034 CheatSearchDlg = NULL;
1035}
1036
1037static void OnCheatSearchDlg_SearchForChanged(GtkWidget *widget, gpointer user_data) {
1038 GladeXML *xml;
1039
1040 xml = glade_get_widget_tree(CheatSearchDlg);
1041
1042 if (gtk_combo_box_get_active(GTK_COMBO_BOX(widget)) == SEARCH_RANGE) {
1043 gtk_widget_show(GTK_WIDGET(glade_xml_get_widget(xml, "label_valueto")));
1044 gtk_widget_show(GTK_WIDGET(glade_xml_get_widget(xml, "entry_valueto")));
1045 }
1046 else {
1047 gtk_widget_hide(GTK_WIDGET(glade_xml_get_widget(xml, "label_valueto")));
1048 gtk_widget_hide(GTK_WIDGET(glade_xml_get_widget(xml, "entry_valueto")));
1049 }
1050
1051 if (gtk_combo_box_get_active(GTK_COMBO_BOX(widget)) >= SEARCH_INC) {
1052 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "entry_value")), FALSE);
1053 }
1054 else {
1055 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "entry_value")), TRUE);
1056 }
1057
1058 if (gtk_combo_box_get_active(GTK_COMBO_BOX(widget)) >= SEARCH_INCBY && prevM == NULL) {
1059 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "btn_start")), FALSE);
1060 }
1061 else {
1062 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "btn_start")), TRUE);
1063 }
1064}
1065
1066static void OnCheatSearchDlg_DataBaseChanged(GtkWidget *widget, gpointer user_data) {
1067 u32 val;
1068 char buf[256];
1069 GladeXML *xml;
1070
1071 xml = glade_get_widget_tree(CheatSearchDlg);
1072
1073 if (gtk_combo_box_get_active(GTK_COMBO_BOX(widget)) == SEARCHBASE_DEC) {
1074 val = 0;
1075 sscanf(gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_value"))), "%x", &val);
1076 sprintf(buf, "%u", val);
1077 gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_value")), buf);
1078
1079 val = 0;
1080 sscanf(gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_valueto"))), "%x", &val);
1081 sprintf(buf, "%u", val);
1082 gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_valueto")), buf);
1083 }
1084 else {
1085 val = 0;
1086 sscanf(gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_value"))), "%u", &val);
1087 sprintf(buf, "%X", val);
1088 gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_value")), buf);
1089
1090 val = 0;
1091 sscanf(gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_valueto"))), "%u", &val);
1092 sprintf(buf, "%X", val);
1093 gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(xml, "entry_valueto")), buf);
1094 }
1095}
1096
1097static void CheatSearch_TreeSelectionChanged(GtkTreeSelection *selection, gpointer user_data) {
1098 GladeXML *xml;
1099
1100 xml = glade_get_widget_tree(CheatSearchDlg);
1101
1102 if (GetSelectedResultIndex() != -1) {
1103 // If a row was selected, we can now enable some of the disabled widgets
1104 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "btn_freeze")), TRUE);
1105 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "btn_modify")), TRUE);
1106 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "btn_copy")), TRUE);
1107 } else {
1108 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "btn_freeze")), FALSE);
1109 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "btn_modify")), FALSE);
1110 gtk_widget_set_sensitive(GTK_WIDGET(glade_xml_get_widget(xml, "btn_copy")), FALSE);
1111 }
1112}
1113
1114// run the cheat search dialog
1115void RunCheatSearchDialog() {
1116 GladeXML *xml;
1117 GtkWidget *widget;
1118 GtkCellRenderer *renderer;
1119 GtkTreeSelection *treesel;
1120 GtkTreeViewColumn *column;
1121
1122 xml = glade_xml_new(PACKAGE_DATA_DIR "pcsx.glade2", "CheatSearchDlg", NULL);
1123 if (!xml) {
1124 g_warning(_("Error: Glade interface could not be loaded!"));
1125 return;
1126 }
1127
1128 CheatSearchDlg = glade_xml_get_widget(xml, "CheatSearchDlg");
1129 gtk_window_set_title(GTK_WINDOW(CheatSearchDlg), _("Cheat Search"));
1130
1131 widget = glade_xml_get_widget(xml, "GtkCList_Result");
1132
1133 renderer = gtk_cell_renderer_text_new ();
1134 column = gtk_tree_view_column_new_with_attributes(_("Search Results"),
1135 renderer, "text", 0, NULL);
1136 gtk_tree_view_append_column(GTK_TREE_VIEW(widget), column);
1137
1138 treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
1139 gtk_tree_selection_set_mode (treesel, GTK_SELECTION_SINGLE);
1140 g_signal_connect_data(G_OBJECT(treesel), "changed",
1141 G_CALLBACK(CheatSearch_TreeSelectionChanged),
1142 NULL, NULL, G_CONNECT_AFTER);
1143
1144 UpdateCheatSearchDialog();
1145
1146 widget = glade_xml_get_widget(xml, "btn_freeze");
1147 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
1148 GTK_SIGNAL_FUNC(OnCheatSearchDlg_FreezeClicked), xml, NULL, G_CONNECT_AFTER);
1149
1150 widget = glade_xml_get_widget(xml, "btn_modify");
1151 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
1152 GTK_SIGNAL_FUNC(OnCheatSearchDlg_ModifyClicked), xml, NULL, G_CONNECT_AFTER);
1153
1154 widget = glade_xml_get_widget(xml, "btn_copy");
1155 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
1156 GTK_SIGNAL_FUNC(OnCheatSearchDlg_CopyClicked), xml, NULL, G_CONNECT_AFTER);
1157
1158 widget = glade_xml_get_widget(xml, "btn_start");
1159 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
1160 GTK_SIGNAL_FUNC(OnCheatSearchDlg_SearchClicked), xml, NULL, G_CONNECT_AFTER);
1161
1162 widget = glade_xml_get_widget(xml, "btn_restart");
1163 g_signal_connect_data(GTK_OBJECT(widget), "clicked",
1164 GTK_SIGNAL_FUNC(OnCheatSearchDlg_RestartClicked), xml, NULL, G_CONNECT_AFTER);
1165
1166 widget = glade_xml_get_widget(xml, "combo_searchfor");
1167 g_signal_connect_data(GTK_OBJECT(widget), "changed",
1168 GTK_SIGNAL_FUNC(OnCheatSearchDlg_SearchForChanged), xml, NULL, G_CONNECT_AFTER);
1169
1170 widget = glade_xml_get_widget(xml, "combo_database");
1171 g_signal_connect_data(GTK_OBJECT(widget), "changed",
1172 GTK_SIGNAL_FUNC(OnCheatSearchDlg_DataBaseChanged), xml, NULL, G_CONNECT_AFTER);
1173
1174 g_signal_connect_data(GTK_OBJECT(CheatSearchDlg), "response",
1175 GTK_SIGNAL_FUNC(OnCheatSearchDlg_CloseClicked), xml, (GClosureNotify)g_object_unref, G_CONNECT_AFTER);
1176}