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