1 /* Pcsx - Pc Psx Emulator
2 * Copyright (C) 1999-2002 Pcsx Team
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 <unistd.h>
22 #include <string.h>
23 #include <dirent.h>
24 #include <dlfcn.h>
25 #include <sys/stat.h>
26 #include <gdk/gdkkeysyms.h>
27 #include <gtk/gtk.h>
28 #include <signal.h>
29 #include <sys/time.h>
30 #include <regex.h>
31 #include <libintl.h>
32
33 #include "Linux.h"
34
35 #include "../libpcsxcore/plugins.h"
36 #include "../libpcsxcore/cheat.h"
37 #include "../libpcsxcore/cdrom.h"
38
39 #include "MemcardDlg.h"
40 #include "ConfDlg.h"
41 #include "DebugMemory.h"
42 #include "AboutDlg.h"
43
44 // Functions Callbacks
45 void OnFile_RunCd();
46 void OnFile_RunBios();
47 void OnFile_RunExe();
48 void OnFile_RunImage();
49 void OnEmu_Run();
50 void OnEmu_Reset();
51 void OnEmu_Shutdown();
52 void OnEmu_SwitchImage();
53 void OnHelp_Help();
54 void OnHelp_About();
55 void OnDestroy();
56 void OnFile_Exit();
57
58 // EXE name is stored here
59 gchar* reset_load_info = NULL;
60
61 void on_states_load(GtkWidget *widget, gpointer user_data);
62 void on_states_load_other();
63 void on_states_save(GtkWidget *widget, gpointer user_data);
64 void on_states_save_other();
65 void on_states_load_recent();
66
67 static GtkBuilder *builder;
68 GtkWidget *Window = NULL;
69
70 int destroy = 0;
71
72 extern void LidInterrupt();
73
74 #define MAX_SLOTS 9
75
76 /* TODO - If MAX_SLOTS changes, need to find a way to automatically set all positions */
77 int Slots[MAX_SLOTS] = { -1, -1, -1, -1, -1, -1, -1, -1, -1 };
78 int recent_load_slot = -1;
79
ResetMenuSlots()80 void ResetMenuSlots() {
81 GtkWidget *widget;
82 gchar *str;
83 int i;
84
85 if (CdromId[0] == '\0') {
86 // disable state saving/loading if no CD is loaded
87 for (i = 0; i < MAX_SLOTS; i++) {
88 // Save slots
89 str = g_strdup_printf("GtkMenuItem_SaveSlot%d", i+1);
90 widget = GTK_WIDGET(gtk_builder_get_object(builder, str));
91 g_free(str);
92
93 gtk_widget_set_sensitive(widget, FALSE);
94
95 // Load slots
96 str = g_strdup_printf("GtkMenuItem_LoadSlot%d", i+1);
97 widget = GTK_WIDGET(gtk_builder_get_object(builder, str));
98 g_free(str);
99
100 gtk_widget_set_sensitive(widget, FALSE);
101 }
102 // Recent
103 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_LoadSlotRecent"));
104 gtk_widget_set_sensitive(widget, FALSE);
105 // Other save/load
106 widget = GTK_WIDGET(gtk_builder_get_object(builder, "other1"));
107 gtk_widget_set_sensitive(widget, FALSE);
108 widget = GTK_WIDGET(gtk_builder_get_object(builder, "other2"));
109 gtk_widget_set_sensitive(widget, FALSE);
110
111 // also disable certain menu/toolbar items
112 widget = GTK_WIDGET(gtk_builder_get_object(builder, "run1"));
113 gtk_widget_set_sensitive(widget, FALSE);
114 widget = GTK_WIDGET(gtk_builder_get_object(builder, "reset1"));
115 gtk_widget_set_sensitive(widget, FALSE);
116 widget = GTK_WIDGET(gtk_builder_get_object(builder, "shutdown1"));
117 gtk_widget_set_sensitive(widget, FALSE);
118 widget = GTK_WIDGET(gtk_builder_get_object(builder, "search1"));
119 gtk_widget_set_sensitive(widget, FALSE);
120 widget = GTK_WIDGET(gtk_builder_get_object(builder, "SwitchImage"));
121 gtk_widget_set_sensitive(widget, FALSE);
122 widget = GTK_WIDGET(gtk_builder_get_object(builder, "memorydump1"));
123 gtk_widget_set_sensitive(widget, FALSE);
124 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_run"));
125 gtk_widget_set_sensitive(widget, FALSE);
126 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_switchimage"));
127 gtk_widget_set_sensitive(widget, FALSE);
128 widget = GTK_WIDGET(gtk_builder_get_object(builder, "plugins_bios"));
129 gtk_widget_set_sensitive(widget, TRUE);
130 widget = GTK_WIDGET(gtk_builder_get_object(builder, "graphics1"));
131 gtk_widget_set_sensitive(widget, TRUE);
132 widget = GTK_WIDGET(gtk_builder_get_object(builder, "sound1"));
133 gtk_widget_set_sensitive(widget, TRUE);
134 widget = GTK_WIDGET(gtk_builder_get_object(builder, "cdrom1"));
135 gtk_widget_set_sensitive(widget, TRUE);
136 #ifdef ENABLE_SIO1API
137 widget = GTK_WIDGET(gtk_builder_get_object(builder, "sio1"));
138 gtk_widget_set_sensitive(widget, TRUE);
139 #else
140 widget = GTK_WIDGET(gtk_builder_get_object(builder, "sio1"));
141 gtk_widget_set_sensitive(widget, FALSE);
142 #endif
143 widget = GTK_WIDGET(gtk_builder_get_object(builder, "net1"));
144 gtk_widget_set_sensitive(widget, TRUE);
145
146 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_switchimage"));
147 gtk_widget_set_sensitive(widget, UsingIso());
148 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_graphics"));
149 gtk_widget_set_sensitive(widget, TRUE);
150 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_sound"));
151 gtk_widget_set_sensitive(widget, TRUE);
152 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_cdrom"));
153 gtk_widget_set_sensitive(widget, TRUE);
154
155 widget = GTK_WIDGET(gtk_builder_get_object(builder, "statusbar"));
156 gtk_statusbar_pop(GTK_STATUSBAR(widget), 1);
157 gtk_statusbar_push(GTK_STATUSBAR(widget), 1, _("Ready"));
158 }
159 else {
160 for (i = 0; i < MAX_SLOTS; i++) {
161 str = g_strdup_printf("GtkMenuItem_LoadSlot%d", i+1);
162 widget = GTK_WIDGET(gtk_builder_get_object (builder, str));
163 g_free (str);
164
165 if (Slots[i] == -1)
166 gtk_widget_set_sensitive(widget, FALSE);
167 else
168 gtk_widget_set_sensitive(widget, TRUE);
169 }
170 // Recent
171 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_LoadSlotRecent"));
172 gtk_widget_set_sensitive(widget, recent_load_slot>-1);
173
174 widget = GTK_WIDGET(gtk_builder_get_object(builder, "plugins_bios"));
175 gtk_widget_set_sensitive(widget, FALSE);
176 widget = GTK_WIDGET(gtk_builder_get_object(builder, "graphics1"));
177 gtk_widget_set_sensitive(widget, FALSE);
178 widget = GTK_WIDGET(gtk_builder_get_object(builder, "sound1"));
179 gtk_widget_set_sensitive(widget, FALSE);
180 widget = GTK_WIDGET(gtk_builder_get_object(builder, "cdrom1"));
181 gtk_widget_set_sensitive(widget, FALSE);
182 #ifdef ENABLE_SIO1API
183 widget = GTK_WIDGET(gtk_builder_get_object(builder, "sio1"));
184 gtk_widget_set_sensitive(widget, FALSE);
185 #endif
186 widget = GTK_WIDGET(gtk_builder_get_object(builder, "net1"));
187 gtk_widget_set_sensitive(widget, FALSE);
188 widget = GTK_WIDGET(gtk_builder_get_object(builder, "SwitchImage"));
189 gtk_widget_set_sensitive(widget, UsingIso());
190 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_switchimage"));
191 gtk_widget_set_sensitive(widget, UsingIso());
192 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_graphics"));
193 gtk_widget_set_sensitive(widget, FALSE);
194 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_sound"));
195 gtk_widget_set_sensitive(widget, FALSE);
196 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_cdrom"));
197 gtk_widget_set_sensitive(widget, FALSE);
198
199 widget = GTK_WIDGET(gtk_builder_get_object(builder, "statusbar"));
200 gtk_statusbar_pop(GTK_STATUSBAR(widget), 1);
201 gtk_statusbar_push(GTK_STATUSBAR(widget), 1, _("Emulation Paused."));
202 }
203 }
204
clear_change_image()205 static void clear_change_image() {
206 g_free(reset_load_info);
207 reset_load_info = NULL;
208 autoloadCheats();
209 g_free(cheat_last_filename);
210 cheat_last_filename = NULL;
211 }
212
match(const char * string,char * pattern)213 int match(const char *string, char *pattern) {
214 int status;
215 regex_t re;
216
217 if (regcomp(&re, pattern, REG_EXTENDED | REG_NOSUB) != 0) {
218 return 0;
219 }
220 status = regexec(&re, string, (size_t) 0, NULL, 0);
221 regfree(&re);
222 if (status != 0) {
223 return 0;
224 }
225
226 return 1;
227 }
228
get_state_filename(int i)229 gchar* get_state_filename(int i) {
230 gchar *state_filename, *trimlabel;
231 char SStateFile[64];
232 int j;
233
234 trimlabel = get_cdrom_label_trim();
235
236 if (i >= OLD_SLOT && i <= LAST_OLD_SLOT) {
237 sprintf(SStateFile, "%.32s-%.9s.old_%d", trimlabel, CdromId, i - OLD_SLOT);
238 } else {
239 sprintf(SStateFile, "%.32s-%.9s.%3.3d", trimlabel, CdromId, i);
240 }
241 state_filename = g_build_filename (getenv("HOME"), STATES_DIR, SStateFile, NULL);
242
243 g_free(trimlabel);
244
245 return state_filename;
246 }
247
get_cdrom_label_trim()248 gchar* get_cdrom_label_trim() {
249 char trimlabel[33];
250 int j;
251
252 strncpy(trimlabel, CdromLabel, 32);
253 trimlabel[32] = 0;
254 for (j = 31; j >= 0; j--) {
255 if (trimlabel[j] == ' ')
256 trimlabel[j] = 0;
257 else
258 continue;
259 }
260
261 return g_strdup(trimlabel);
262 }
263
get_cdrom_label_id(const gchar * suffix)264 gchar* get_cdrom_label_id(const gchar* suffix) {
265 const u8 lblmax = sizeof(CdromId) + sizeof(CdromLabel) + 20u;
266 //printf("MAx %u\n", lblmax);
267 char buf[lblmax];
268 gchar *trimlabel = get_cdrom_label_trim();
269
270 snprintf(buf, lblmax, "%.32s-%.9s%s", trimlabel, CdromId, suffix);
271
272 g_free(trimlabel);
273
274 if (strlen(buf) <= (2+strlen(dot_extension_cht)))
275 return g_strconcat("psx-default", dot_extension_cht, NULL);
276 else
277 return g_strdup(buf);
278 }
279
get_state_time(const char * fn)280 static time_t get_state_time(const char* fn) {
281 struct stat st;
282 int ierr = stat (fn, &st);
283 if (!ierr)
284 return st.st_ctime;
285 else
286 return -1;
287 }
288
UpdateMenuSlots()289 int UpdateMenuSlots() {
290 gchar *str;
291 int i, imax=-1;
292 time_t tsmax = -1;
293
294 for (i = 0; i < MAX_SLOTS; i++) {
295 str = get_state_filename (i);
296 if ((Slots[i] = CheckState(str)) >= 0) {
297 time_t ts = get_state_time(str);
298 if (ts > tsmax) {
299 tsmax=ts;
300 imax=i;
301 }
302 //printf("File %s time %i\n", str, ts);
303 }
304 g_free (str);
305 }
306 return (recent_load_slot=imax);
307 }
308
autoloadCheats()309 void autoloadCheats() {
310 ClearAllCheats();
311 gchar *chtfile = get_cdrom_label_id(dot_extension_cht);
312 gchar *defaultChtFilePath = g_build_filename (getenv("HOME"), CHEATS_DIR, chtfile, NULL);
313 LoadCheats(defaultChtFilePath); // file existence/access check in LoadCheats()
314 g_free(defaultChtFilePath);
315 g_free(chtfile);
316 }
317
StartGui()318 void StartGui() {
319 GtkWidget *widget;
320
321 /* If a plugin fails, the Window is not NULL, but is not initialised,
322 so the following causes a segfault
323 if (Window != NULL) {
324 gtk_window_present (GTK_WINDOW (Window));
325 return;
326 }*/
327 GtkIconTheme *itheme = gtk_icon_theme_get_default();
328 gtk_icon_theme_add_resource_path(itheme,"/org/pcsxr/gui");
329 gtk_icon_theme_add_resource_path(itheme,"/org/pcsxr/gui/pixmaps/");
330
331 builder = gtk_builder_new();
332
333 if (!gtk_builder_add_from_resource(builder, "/org/pcsxr/gui/pcsxr.ui", NULL)) {
334 g_warning("Error: interface could not be loaded!");
335 return;
336 }
337
338 Window = GTK_WIDGET(gtk_builder_get_object(builder, "MainWindow"));
339 gtk_widget_show(GTK_WIDGET(Window));
340
341 gtk_window_set_title(GTK_WINDOW(Window), "PCSXR");
342 gtk_window_set_icon(GTK_WINDOW(Window), gdk_pixbuf_new_from_resource("/org/pcsxr/gui/pixmaps/pcsxr-icon.png", NULL));
343 gtk_window_set_default_icon(gdk_pixbuf_new_from_resource("/org/pcsxr/gui/pixmaps/pcsxr-icon.png", NULL));
344 ResetMenuSlots();
345
346 // Set up callbacks
347 g_signal_connect_data(G_OBJECT(Window), "delete-event",
348 G_CALLBACK(OnDestroy), builder, (GClosureNotify)g_object_unref, G_CONNECT_AFTER);
349
350 // File menu
351 widget = GTK_WIDGET(gtk_builder_get_object(builder, "RunCd"));
352 g_signal_connect_data(G_OBJECT(widget), "activate",
353 G_CALLBACK(OnFile_RunCd), NULL, NULL, G_CONNECT_AFTER);
354
355 widget = GTK_WIDGET(gtk_builder_get_object(builder, "RunBios"));
356 g_signal_connect_data(G_OBJECT(widget), "activate",
357 G_CALLBACK(OnFile_RunBios), NULL, NULL, G_CONNECT_AFTER);
358
359 widget = GTK_WIDGET(gtk_builder_get_object(builder, "RunExe"));
360 g_signal_connect_data(G_OBJECT(widget), "activate",
361 G_CALLBACK(OnFile_RunExe), NULL, NULL, G_CONNECT_AFTER);
362
363 widget = GTK_WIDGET(gtk_builder_get_object(builder, "RunImage"));
364 g_signal_connect_data(G_OBJECT(widget), "activate",
365 G_CALLBACK(OnFile_RunImage), NULL, NULL, G_CONNECT_AFTER);
366
367 widget = GTK_WIDGET(gtk_builder_get_object(builder, "exit2"));
368 g_signal_connect_data(G_OBJECT(widget), "activate",
369 G_CALLBACK(OnFile_Exit), NULL, NULL, G_CONNECT_AFTER);
370
371 // States
372 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_LoadSlot1"));
373 g_signal_connect_data(G_OBJECT(widget), "activate",
374 G_CALLBACK(on_states_load), GINT_TO_POINTER(0), NULL, G_CONNECT_AFTER);
375 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_LoadSlot2"));
376 g_signal_connect_data(G_OBJECT(widget), "activate",
377 G_CALLBACK(on_states_load), GINT_TO_POINTER(1), NULL, G_CONNECT_AFTER);
378 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_LoadSlot3"));
379 g_signal_connect_data(G_OBJECT(widget), "activate",
380 G_CALLBACK(on_states_load), GINT_TO_POINTER(2), NULL, G_CONNECT_AFTER);
381 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_LoadSlot4"));
382 g_signal_connect_data(G_OBJECT(widget), "activate",
383 G_CALLBACK(on_states_load), GINT_TO_POINTER(3), NULL, G_CONNECT_AFTER);
384 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_LoadSlot5"));
385 g_signal_connect_data(G_OBJECT(widget), "activate",
386 G_CALLBACK(on_states_load), GINT_TO_POINTER(4), NULL, G_CONNECT_AFTER);
387 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_LoadSlot6"));
388 g_signal_connect_data(G_OBJECT(widget), "activate",
389 G_CALLBACK(on_states_load), GINT_TO_POINTER(5), NULL, G_CONNECT_AFTER);
390 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_LoadSlot7"));
391 g_signal_connect_data(G_OBJECT(widget), "activate",
392 G_CALLBACK(on_states_load), GINT_TO_POINTER(6), NULL, G_CONNECT_AFTER);
393 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_LoadSlot8"));
394 g_signal_connect_data(G_OBJECT(widget), "activate",
395 G_CALLBACK(on_states_load), GINT_TO_POINTER(7), NULL, G_CONNECT_AFTER);
396 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_LoadSlot9"));
397 g_signal_connect_data(G_OBJECT(widget), "activate",
398 G_CALLBACK(on_states_load), GINT_TO_POINTER(8), NULL, G_CONNECT_AFTER);
399 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_LoadSlotRecent"));
400 g_signal_connect_data(G_OBJECT(widget), "activate",
401 G_CALLBACK(on_states_load_recent), NULL, NULL, G_CONNECT_AFTER);
402 widget = GTK_WIDGET(gtk_builder_get_object(builder, "other1"));
403 g_signal_connect_data(G_OBJECT(widget), "activate",
404 G_CALLBACK(on_states_load_other), NULL, NULL, G_CONNECT_AFTER);
405
406 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_SaveSlot1"));
407 g_signal_connect_data(G_OBJECT(widget), "activate",
408 G_CALLBACK(on_states_save), GINT_TO_POINTER(0), NULL, G_CONNECT_AFTER);
409 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_SaveSlot2"));
410 g_signal_connect_data(G_OBJECT(widget), "activate",
411 G_CALLBACK(on_states_save), GINT_TO_POINTER(1), NULL, G_CONNECT_AFTER);
412 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_SaveSlot3"));
413 g_signal_connect_data(G_OBJECT(widget), "activate",
414 G_CALLBACK(on_states_save), GINT_TO_POINTER(2), NULL, G_CONNECT_AFTER);
415 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_SaveSlot4"));
416 g_signal_connect_data(G_OBJECT(widget), "activate",
417 G_CALLBACK(on_states_save), GINT_TO_POINTER(3), NULL, G_CONNECT_AFTER);
418 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_SaveSlot5"));
419 g_signal_connect_data(G_OBJECT(widget), "activate",
420 G_CALLBACK(on_states_save), GINT_TO_POINTER(4), NULL, G_CONNECT_AFTER);
421 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_SaveSlot6"));
422 g_signal_connect_data(G_OBJECT(widget), "activate",
423 G_CALLBACK(on_states_save), GINT_TO_POINTER(5), NULL, G_CONNECT_AFTER);
424 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_SaveSlot7"));
425 g_signal_connect_data(G_OBJECT(widget), "activate",
426 G_CALLBACK(on_states_save), GINT_TO_POINTER(6), NULL, G_CONNECT_AFTER);
427 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_SaveSlot8"));
428 g_signal_connect_data(G_OBJECT(widget), "activate",
429 G_CALLBACK(on_states_save), GINT_TO_POINTER(7), NULL, G_CONNECT_AFTER);
430 widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkMenuItem_SaveSlot9"));
431 g_signal_connect_data(G_OBJECT(widget), "activate",
432 G_CALLBACK(on_states_save), GINT_TO_POINTER(8), NULL, G_CONNECT_AFTER);
433 widget = GTK_WIDGET(gtk_builder_get_object(builder, "other2"));
434 g_signal_connect_data(G_OBJECT(widget), "activate",
435 G_CALLBACK(on_states_save_other), NULL, NULL, G_CONNECT_AFTER);
436
437 // Emulation menu
438 widget = GTK_WIDGET(gtk_builder_get_object(builder, "run1"));
439 g_signal_connect_data(G_OBJECT(widget), "activate",
440 G_CALLBACK(OnEmu_Run), NULL, NULL, G_CONNECT_AFTER);
441 widget = GTK_WIDGET(gtk_builder_get_object(builder, "reset1"));
442 g_signal_connect_data(G_OBJECT(widget), "activate",
443 G_CALLBACK(OnEmu_Reset), NULL, NULL, G_CONNECT_AFTER);
444 widget = GTK_WIDGET(gtk_builder_get_object(builder, "shutdown1"));
445 g_signal_connect_data(G_OBJECT(widget), "activate",
446 G_CALLBACK(OnEmu_Shutdown), NULL, NULL, G_CONNECT_AFTER);
447 widget = GTK_WIDGET(gtk_builder_get_object(builder, "SwitchImage"));
448 g_signal_connect_data(G_OBJECT(widget), "activate",
449 G_CALLBACK(OnEmu_SwitchImage), NULL, NULL, G_CONNECT_AFTER);
450
451 // Configuration menu
452 widget = GTK_WIDGET(gtk_builder_get_object(builder, "plugins_bios"));
453 g_signal_connect_data(G_OBJECT(widget), "activate",
454 G_CALLBACK(ConfigurePlugins), NULL, NULL, G_CONNECT_AFTER);
455 widget = GTK_WIDGET(gtk_builder_get_object(builder, "graphics1"));
456 g_signal_connect_data(G_OBJECT(widget), "activate",
457 G_CALLBACK(OnConf_Graphics), NULL, NULL, G_CONNECT_AFTER);
458 widget = GTK_WIDGET(gtk_builder_get_object(builder, "sound1"));
459 g_signal_connect_data(G_OBJECT(widget), "activate",
460 G_CALLBACK(OnConf_Sound), NULL, NULL, G_CONNECT_AFTER);
461 widget = GTK_WIDGET(gtk_builder_get_object(builder, "cdrom1"));
462 g_signal_connect_data(G_OBJECT(widget), "activate",
463 G_CALLBACK(OnConf_CdRom), NULL, NULL, G_CONNECT_AFTER);
464 widget = GTK_WIDGET(gtk_builder_get_object(builder, "pad1"));
465 g_signal_connect_data(G_OBJECT(widget), "activate",
466 G_CALLBACK(OnConf_Pad), NULL, NULL, G_CONNECT_AFTER);
467 #ifdef ENABLE_SIO1API
468 widget = GTK_WIDGET(gtk_builder_get_object(builder, "sio1"));
469 g_signal_connect_data(G_OBJECT(widget), "activate",
470 G_CALLBACK(OnConf_Sio1), NULL, NULL, G_CONNECT_AFTER);
471 #endif
472 widget = GTK_WIDGET(gtk_builder_get_object(builder, "cpu1"));
473 g_signal_connect_data(G_OBJECT(widget), "activate",
474 G_CALLBACK(OnConf_Cpu), NULL, NULL, G_CONNECT_AFTER);
475 widget = GTK_WIDGET(gtk_builder_get_object(builder, "memory_cards1"));
476 g_signal_connect_data(G_OBJECT(widget), "activate",
477 G_CALLBACK(OnConf_Mcds), NULL, NULL, G_CONNECT_AFTER);
478 widget = GTK_WIDGET(gtk_builder_get_object(builder, "net1"));
479 g_signal_connect_data(G_OBJECT(widget), "activate",
480 G_CALLBACK(OnConf_Net), NULL, NULL, G_CONNECT_AFTER);
481 widget = GTK_WIDGET(gtk_builder_get_object(builder, "memorydump1"));
482 g_signal_connect_data(G_OBJECT(widget), "activate",
483 G_CALLBACK(RunDebugMemoryDialog), NULL, NULL, G_CONNECT_AFTER);
484
485 // Cheat menu
486 widget = GTK_WIDGET(gtk_builder_get_object(builder, "browse1"));
487 g_signal_connect_data(G_OBJECT(widget), "activate",
488 G_CALLBACK(RunCheatListDialog), NULL, NULL, G_CONNECT_AFTER);
489 widget = GTK_WIDGET(gtk_builder_get_object(builder, "search1"));
490 g_signal_connect_data(G_OBJECT(widget), "activate",
491 G_CALLBACK(RunCheatSearchDialog), NULL, NULL, G_CONNECT_AFTER);
492
493 // Help menu
494 widget = GTK_WIDGET(gtk_builder_get_object(builder, "about_pcsxr1"));
495 g_signal_connect_data(G_OBJECT(widget), "activate",
496 G_CALLBACK(OnHelp_About), NULL, NULL, G_CONNECT_AFTER);
497
498 // Toolbar
499 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_runcd"));
500 g_signal_connect_data(G_OBJECT(widget), "clicked",
501 G_CALLBACK(OnFile_RunCd), NULL, NULL, G_CONNECT_AFTER);
502
503 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_runimage"));
504 g_signal_connect_data(G_OBJECT(widget), "clicked",
505 G_CALLBACK(OnFile_RunImage), NULL, NULL, G_CONNECT_AFTER);
506
507 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_run"));
508 g_signal_connect_data(G_OBJECT(widget), "clicked",
509 G_CALLBACK(OnEmu_Run), NULL, NULL, G_CONNECT_AFTER);
510
511 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_switchimage"));
512 g_signal_connect_data(G_OBJECT(widget), "clicked",
513 G_CALLBACK(OnEmu_SwitchImage), NULL, NULL, G_CONNECT_AFTER);
514
515 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_memcards"));
516 g_signal_connect_data(G_OBJECT(widget), "clicked",
517 G_CALLBACK(OnConf_Mcds), NULL, NULL, G_CONNECT_AFTER);
518
519 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_graphics"));
520 g_signal_connect_data(G_OBJECT(widget), "clicked",
521 G_CALLBACK(OnConf_Graphics), NULL, NULL, G_CONNECT_AFTER);
522
523 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_sound"));
524 g_signal_connect_data(G_OBJECT(widget), "clicked",
525 G_CALLBACK(OnConf_Sound), NULL, NULL, G_CONNECT_AFTER);
526
527 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_cdrom"));
528 g_signal_connect_data(G_OBJECT(widget), "clicked",
529 G_CALLBACK(OnConf_CdRom), NULL, NULL, G_CONNECT_AFTER);
530
531 widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbutton_controllers"));
532 g_signal_connect_data(G_OBJECT(widget), "clicked",
533 G_CALLBACK(OnConf_Pad), NULL, NULL, G_CONNECT_AFTER);
534
535 gtk_main();
536 }
537
OnDestroy()538 void OnDestroy() {
539 if (!destroy) OnFile_Exit();
540 }
541
destroy_main_window()542 void destroy_main_window () {
543 #ifdef DISABLE_GNOME_SCREENSAVER
544 // Disable GNOME screensaver
545 int response_token = 0;
546 GError *error;
547 GDBusProxy *proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
548 G_DBUS_PROXY_FLAGS_NONE, NULL,
549 "org.gnome.ScreenSaver",
550 "org/gnome/ScreenSaver",
551 "org.gnome.ScreenSaver",
552 NULL, &error);
553
554 GVariant *retval = g_dbus_proxy_call_sync (proxy,
555 "Inhibit",
556 g_variant_new ("(ssu)", "PCSXR",
557 "Emulating",
558 response_token),
559 G_DBUS_CALL_FLAGS_NONE,
560 2, /* timeout */
561 NULL, /* cancellable */
562 &error);
563 printf("Response %i\n", response_token);
564 #endif
565
566 destroy = 1;
567 gtk_widget_destroy(Window);
568 Window = NULL;
569 destroy = 0;
570 gtk_main_quit();
571 while (gtk_events_pending()) gtk_main_iteration();
572 }
573
OnFile_RunExe()574 void OnFile_RunExe() {
575 GtkWidget *file_chooser;
576
577 if (plugins_configured() == FALSE) {
578 ConfigurePlugins();
579 } else {
580 file_chooser = gtk_file_chooser_dialog_new(_("Select PSX EXE File"),
581 NULL, GTK_FILE_CHOOSER_ACTION_OPEN,
582 "_Cancel", GTK_RESPONSE_CANCEL,
583 "_Open", GTK_RESPONSE_ACCEPT, NULL);
584
585 // Add file filters
586 GtkFileFilter *exefilter = gtk_file_filter_new ();
587 gtk_file_filter_add_pattern (exefilter, "*.exe");
588 gtk_file_filter_add_pattern (exefilter, "*.psx");
589 gtk_file_filter_add_pattern (exefilter, "*.cpe");
590 gtk_file_filter_add_pattern (exefilter, "*.EXE");
591 gtk_file_filter_add_pattern (exefilter, "*.PSX");
592 gtk_file_filter_add_pattern (exefilter, "*.CPE");
593 gtk_file_filter_set_name (exefilter, _("PlayStation Executable Files"));
594 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_chooser), exefilter);
595 GtkFileFilter *allfilter = gtk_file_filter_new ();
596 gtk_file_filter_add_pattern (allfilter, "*");
597 gtk_file_filter_set_name (allfilter, _("All Files"));
598 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_chooser), allfilter);
599
600 // Set this to the config object and retain it - maybe LastUsedDir
601 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_chooser), getenv("HOME"));
602
603 if (gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT) {
604 gchar *file;
605
606 /* TODO Need to validate the file */
607
608 file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_chooser));
609
610 gtk_widget_destroy (file_chooser);
611 destroy_main_window();
612
613 SetIsoFile(NULL);
614 LoadPlugins();
615 NetOpened = FALSE;
616
617 if (OpenPlugins() == -1) {
618 g_free(file);
619 SysRunGui();
620 } else {
621 // Auto-detect: get region first, then rcnt-bios reset
622 SysReset();
623
624 if (Load(file) == 0) {
625 g_free(reset_load_info);
626 reset_load_info = g_strdup(file);
627 g_free(file);
628 psxCpu->Execute();
629 } else {
630 g_free(file);
631 ClosePlugins();
632 SysErrorMessage(_("Not a valid PSX file"), _("The file does not appear to be a valid Playstation executable"));
633 SysRunGui();
634 }
635 }
636 } else
637 gtk_widget_destroy(file_chooser);
638 }
639 }
640
OnFile_RunCd()641 void OnFile_RunCd() {
642 if (plugins_configured() == FALSE) {
643 ConfigurePlugins();
644 return;
645 }
646
647 destroy_main_window();
648
649 SetIsoFile(NULL);
650 LoadPlugins();
651 NetOpened = FALSE;
652
653 if (OpenPlugins() == -1) {
654 SysRunGui();
655 return;
656 }
657
658 if (CheckCdrom() == -1) {
659 /* Only check the CD if we are starting the console with a CD */
660 ClosePlugins();
661 SysErrorMessage (_("CD ROM failed"), _("The CD does not appear to be a valid Playstation CD"));
662 SysRunGui();
663 return;
664 }
665
666 // Auto-detect: get region first, then rcnt-bios reset
667 SysReset();
668
669 // Read main executable directly from CDRom and start it
670 if (LoadCdrom() == -1) {
671 ClosePlugins();
672 SysErrorMessage(_("Could not load CD-ROM!"), _("The CD-ROM could not be loaded"));
673 SysRunGui();
674 }
675
676 clear_change_image();
677 psxCpu->Execute();
678 }
679
OnFile_RunBios()680 void OnFile_RunBios() {
681 if (plugins_configured() == FALSE) {
682 ConfigurePlugins();
683 return;
684 }
685
686 if (strcmp(Config.Bios, "HLE") == 0) {
687 SysErrorMessage (_("Could not run BIOS"), _("Running BIOS is not supported with Internal HLE BIOS."));
688 return;
689 }
690
691 destroy_main_window();
692
693 SetIsoFile(NULL);
694 LoadPlugins();
695 NetOpened = FALSE;
696
697 if (OpenPlugins() == -1) {
698 SysRunGui();
699 return;
700 }
701
702 SysReset();
703
704 CdromId[0] = '\0';
705 CdromLabel[0] = '\0';
706
707 clear_change_image();
708 psxCpu->Execute();
709 }
710
Open_Iso_Proc()711 static gchar *Open_Iso_Proc() {
712 struct stat sb;
713 GtkWidget *chooser;
714 gchar *filename;
715 GtkFileFilter *psxfilter, *allfilter;
716 static char current_folder[MAXPATHLEN] = "";
717
718 chooser = gtk_file_chooser_dialog_new (_("Open PSX Disc Image File"),
719 NULL, GTK_FILE_CHOOSER_ACTION_OPEN, "_Cancel", GTK_RESPONSE_CANCEL,
720 "_Open", GTK_RESPONSE_ACCEPT,
721 NULL);
722
723 if (stat(Config.IsoImgDir, &sb) == 0 && S_ISDIR(sb.st_mode)) {
724 strcpy(current_folder, Config.IsoImgDir);
725 } else if (strlen(Config.IsoImgDir) <= 0) {
726 strcpy(current_folder, getenv("HOME"));
727 } else {
728 /* Using static (recent) PATH */
729 }
730
731 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (chooser), current_folder);
732
733 psxfilter = gtk_file_filter_new();
734 gtk_file_filter_add_pattern(psxfilter, "*.bin");
735 gtk_file_filter_add_pattern(psxfilter, "*.img");
736 gtk_file_filter_add_pattern(psxfilter, "*.mdf");
737 gtk_file_filter_add_pattern(psxfilter, "*.iso");
738 gtk_file_filter_add_pattern(psxfilter, "*.cue");
739 gtk_file_filter_add_pattern(psxfilter, "*.pbp");
740 gtk_file_filter_add_pattern(psxfilter, "*.cbn");
741 gtk_file_filter_add_pattern(psxfilter, "*.BIN");
742 gtk_file_filter_add_pattern(psxfilter, "*.IMG");
743 gtk_file_filter_add_pattern(psxfilter, "*.MDF");
744 gtk_file_filter_add_pattern(psxfilter, "*.ISO");
745 gtk_file_filter_add_pattern(psxfilter, "*.CUE");
746 gtk_file_filter_add_pattern(psxfilter, "*.PBP");
747 gtk_file_filter_add_pattern(psxfilter, "*.CBN");
748 gtk_file_filter_add_pattern(psxfilter, "*.ecm");
749 gtk_file_filter_set_name(psxfilter, _("PSX Image Files (*.bin, *.img, *.mdf, *.iso, *.ecm, *.cue, *.pbp, *.cbn)"));
750 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (chooser), psxfilter);
751
752 allfilter = gtk_file_filter_new();
753 gtk_file_filter_add_pattern(allfilter, "*");
754 gtk_file_filter_set_name(allfilter, _("All Files"));
755 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (chooser), allfilter);
756
757 if (gtk_dialog_run(GTK_DIALOG(chooser)) == GTK_RESPONSE_ACCEPT) {
758 gchar *path = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(chooser));
759
760 /* Workaround:
761 for some reasons gtk_file_chooser_get_current_folder return NULL
762 if a file is selected from "Recently Used" or "Searsh"*/
763 if(path != NULL) {
764 strcpy(current_folder, path);
765 g_free(path);
766 }
767
768 GSList * l = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER (chooser));
769 if(l) {
770 filename = l->data;
771
772 /* if the file was selected from "Recently Used" or "Searsh"
773 we need to extract the path from the filename to set it to current_folder*/
774 if(path == NULL) {
775 strncpy(current_folder, filename, strrchr(filename, '/') - filename);
776 }
777
778 /* Save current path. */
779 strcpy(Config.IsoImgDir, current_folder);
780 SaveConfig();
781
782 /* free useless data */
783 GSList * ll = l;
784 while(l->next) {
785 l = l->next;
786 g_free(l->data);
787 }
788 g_slist_free(ll);
789
790 gtk_widget_destroy(GTK_WIDGET(chooser));
791 while (gtk_events_pending()) gtk_main_iteration();
792 return filename;
793 } else {
794 gtk_widget_destroy (GTK_WIDGET(chooser));
795 while (gtk_events_pending()) gtk_main_iteration();
796 return NULL;
797 }
798 } else {
799 gtk_widget_destroy (GTK_WIDGET(chooser));
800 while (gtk_events_pending()) gtk_main_iteration();
801 return NULL;
802 }
803 }
804
OnFile_RunImage()805 void OnFile_RunImage() {
806 gchar *filename;
807
808 if (plugins_configured() == FALSE) {
809 ConfigurePlugins();
810 return;
811 }
812
813 filename = Open_Iso_Proc();
814 if (filename == NULL) {
815 return;
816 }
817
818 destroy_main_window();
819
820 SetIsoFile(filename);
821 g_free(filename);
822
823 LoadPlugins();
824 NetOpened = FALSE;
825
826 if (OpenPlugins() == -1) {
827 SysRunGui();
828 return;
829 }
830
831 if (CheckCdrom() == -1) {
832 // Only check the CD if we are starting the console with a CD
833 ClosePlugins();
834 SysErrorMessage (_("CD ROM failed"), _("The CD does not appear to be a valid Playstation CD"));
835 SysRunGui();
836 return;
837 }
838
839 // Auto-detect: get region first, then rcnt-bios reset
840 SysReset();
841
842 // Read main executable directly from CDRom and start it
843 if (LoadCdrom() == -1) {
844 ClosePlugins();
845 SysErrorMessage(_("Could not load CD-ROM!"), _("The CD-ROM could not be loaded"));
846 SysRunGui();
847 }
848
849 clear_change_image();
850 psxCpu->Execute();
851 }
852
OnEmu_Run()853 void OnEmu_Run() {
854 if (plugins_configured() == FALSE) {
855 ConfigurePlugins();
856 return;
857 }
858
859 destroy_main_window();
860
861 if (OpenPlugins() == -1) {
862 SysRunGui();
863 return;
864 }
865
866 CheatSearchBackupMemory();
867 psxCpu->Execute();
868 }
869
OnEmu_Reset()870 void OnEmu_Reset() {
871 if (plugins_configured() == FALSE) {
872 ConfigurePlugins();
873 return;
874 }
875
876 destroy_main_window();
877
878 if (OpenPlugins() == -1) {
879 SysRunGui();
880 return;
881 }
882
883 // No extra checks here since this is reset and target has been verified already once
884 if (reset_load_info) {
885 SysPrintf("RESET/reloading %s\n", reset_load_info);
886 SysReset();
887 Load(reset_load_info);
888 } else {
889 SysPrintf("RESET/reloading %s %s\n", CdromId, CdromLabel);
890 CheckCdrom();
891 SysReset();
892 LoadCdrom();
893 }
894
895 psxCpu->Execute();
896 }
897
OnEmu_Shutdown()898 void OnEmu_Shutdown() {
899 ReleasePlugins();
900 SetIsoFile(NULL);
901 CdromId[0] = '\0';
902 CdromLabel[0] = '\0';
903 ResetMenuSlots();
904 g_free(reset_load_info);
905 reset_load_info = NULL;
906 }
907
OnEmu_SwitchImage()908 void OnEmu_SwitchImage() {
909 gchar *filename;
910
911 if (plugins_configured() == FALSE) {
912 ConfigurePlugins();
913 return;
914 }
915
916 filename = Open_Iso_Proc();
917 if (filename == NULL) {
918 return;
919 }
920
921 destroy_main_window();
922
923 SetIsoFile(filename);
924 g_free(filename);
925
926 if (OpenPlugins() == -1) {
927 SysRunGui();
928 return;
929 }
930
931 SetCdOpenCaseTime(time(NULL) + 2);
932 LidInterrupt(); // causes CD lid open event
933
934 CheatSearchBackupMemory();
935 psxCpu->Execute();
936 }
937
OnFile_Exit()938 void OnFile_Exit() {
939 DIR *dir;
940 struct dirent *ent;
941 void *Handle;
942 gchar *plugin = NULL;
943 gchar *dotdir;
944
945 dotdir = g_build_filename(getenv("HOME"), PLUGINS_DIR, NULL);
946
947 // with this the problem with plugins that are linked with the pthread
948 // library is solved
949
950 dir = opendir(dotdir);
951 if (dir != NULL) {
952 while ((ent = readdir(dir)) != NULL) {
953 plugin = g_build_filename(dotdir, ent->d_name, NULL);
954
955 if (strstr(plugin, ".so") == NULL && strstr(plugin, ".dylib") == NULL)
956 continue;
957 Handle = dlopen(plugin, RTLD_NOW);
958 if (Handle == NULL)
959 continue;
960
961 g_free(plugin);
962 }
963 }
964 g_free(dotdir);
965
966 bind_textdomain_codeset(PACKAGE_NAME, "");
967 if (UseGui)
968 gtk_main_quit();
969 SysClose();
970 exit(0);
971 }
972
state_load(gchar * state_filename)973 void state_load(gchar *state_filename) {
974 int ret;
975 char Text[MAXPATHLEN + 20];
976 FILE *fp;
977
978 // check if the state file actually exists
979 fp = fopen(state_filename, "rb");
980 if (fp == NULL) {
981 // file does not exist
982 return;
983 }
984
985 fclose(fp);
986
987 // If the window exists, then we are loading the state from within
988 // the PCSXR GUI. We need to initialise the plugins first.
989 if (Window) {
990 destroy_main_window();
991
992 if (OpenPlugins() == -1) {
993 SysRunGui();
994 return;
995 }
996 }
997
998 ret = CheckState(state_filename);
999
1000 if (ret == 0) {
1001 // Check the CD-ROM is valid
1002 if (CheckCdrom() == -1) {
1003 ClosePlugins();
1004 SysRunGui();
1005 return;
1006 }
1007
1008 // Auto-detect: region first, then rcnt reset
1009 SysReset();
1010 ret = LoadState(state_filename);
1011
1012 sprintf(Text, _("Loaded state %s."), state_filename);
1013 GPU_displayText(Text);
1014 } else {
1015 sprintf(Text, _("Error loading state %s!"), state_filename);
1016 GPU_displayText(Text);
1017 }
1018 }
1019
state_save(gchar * state_filename)1020 void state_save(gchar *state_filename) {
1021 char Text[MAXPATHLEN + 20];
1022
1023 // If the window exists, then we are saving the state from within
1024 // the PCSXR GUI. We need to initialise the plugins first.
1025 if (Window) {
1026 destroy_main_window();
1027
1028 if (OpenPlugins() == -1) {
1029 SysRunGui();
1030 return;
1031 }
1032 }
1033
1034 GPU_updateLace();
1035
1036 if (SaveState(state_filename) == 0)
1037 sprintf(Text, _("Saved state %s."), state_filename);
1038 else
1039 sprintf(Text, _("Error saving state %s!"), state_filename);
1040
1041 GPU_displayText(Text);
1042 }
1043
on_states_load(GtkWidget * widget,gpointer user_data)1044 void on_states_load (GtkWidget *widget, gpointer user_data) {
1045 (void)widget; // unused
1046
1047 gchar *state_filename;
1048 gint state = GPOINTER_TO_INT(user_data);
1049
1050 state_filename = get_state_filename(state);
1051
1052 state_load(state_filename);
1053
1054 g_free(state_filename);
1055
1056 psxCpu->Execute();
1057 }
1058
on_states_save(GtkWidget * widget,gpointer user_data)1059 void on_states_save (GtkWidget *widget, gpointer user_data) {
1060 (void)widget; // unused
1061
1062 gchar *state_filename;
1063 gint state = GPOINTER_TO_INT(user_data);
1064
1065 state_filename = get_state_filename(state);
1066
1067 state_save(state_filename);
1068
1069 g_free(state_filename);
1070 }
1071
on_states_load_recent()1072 void on_states_load_recent() {
1073 gchar *state_filename;
1074 gint state = StatesC = recent_load_slot;
1075
1076 state_filename = get_state_filename(state);
1077
1078 state_load(state_filename);
1079
1080 g_free(state_filename);
1081
1082 psxCpu->Execute();
1083 }
1084
on_states_load_other()1085 void on_states_load_other() {
1086 GtkWidget *file_chooser;
1087 gchar *SStateFile;
1088
1089 SStateFile = g_strconcat(getenv("HOME"), STATES_DIR, NULL);
1090
1091 file_chooser = gtk_file_chooser_dialog_new(_("Select State File"), NULL, GTK_FILE_CHOOSER_ACTION_OPEN,
1092 "_Cancel", GTK_RESPONSE_CANCEL,
1093 "_Open", GTK_RESPONSE_ACCEPT,
1094 NULL);
1095 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (file_chooser), SStateFile);
1096 g_free(SStateFile);
1097
1098 if (gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT) {
1099 gchar *filename;
1100
1101 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_chooser));
1102 gtk_widget_destroy(file_chooser);
1103
1104 state_load(filename);
1105
1106 g_free(filename);
1107
1108 psxCpu->Execute();
1109 } else
1110 gtk_widget_destroy(file_chooser);
1111 }
1112
on_states_save_other()1113 void on_states_save_other() {
1114 GtkWidget *file_chooser;
1115 gchar *SStateFile;
1116
1117 SStateFile = g_strconcat (getenv("HOME"), STATES_DIR, NULL);
1118
1119 file_chooser = gtk_file_chooser_dialog_new(_("Select State File"),
1120 NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
1121 "_Cancel", GTK_RESPONSE_CANCEL,
1122 "_Save", GTK_RESPONSE_OK,
1123 NULL);
1124 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_chooser), SStateFile);
1125 g_free(SStateFile);
1126
1127 if (gtk_dialog_run (GTK_DIALOG(file_chooser)) == GTK_RESPONSE_OK) {
1128 gchar *filename;
1129
1130 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (file_chooser));
1131 gtk_widget_destroy(file_chooser);
1132
1133 state_save(filename);
1134
1135 g_free(filename);
1136 }
1137 else
1138 gtk_widget_destroy(file_chooser);
1139 }
1140
OnHelp_About(GtkWidget * widget,gpointer user_data)1141 void OnHelp_About(GtkWidget *widget, gpointer user_data) {
1142 RunAboutDialog();
1143 }
1144
SysMessage(const char * fmt,...)1145 void SysMessage(const char *fmt, ...) {
1146 GtkWidget *Txt, *MsgDlg;
1147 va_list list;
1148 char msg[512];
1149
1150 va_start(list, fmt);
1151 vsprintf(msg, fmt, list);
1152 va_end(list);
1153
1154 if (msg[strlen(msg) - 1] == '\n')
1155 msg[strlen(msg) - 1] = 0;
1156
1157 if (!UseGui) {
1158 fprintf(stderr, "%s\n", msg);
1159 return;
1160 }
1161
1162 MsgDlg = gtk_dialog_new_with_buttons(_("Notice"), NULL,
1163 GTK_DIALOG_DESTROY_WITH_PARENT, "_OK", GTK_RESPONSE_NONE, NULL);
1164
1165 gtk_window_set_position (GTK_WINDOW(MsgDlg), GTK_WIN_POS_CENTER);
1166
1167 Txt = gtk_label_new (msg);
1168 gtk_label_set_line_wrap(GTK_LABEL(Txt), TRUE);
1169 gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area(GTK_DIALOG(MsgDlg))), Txt);
1170
1171 gtk_widget_show (Txt);
1172 gtk_widget_show_all (MsgDlg);
1173
1174 g_signal_connect_swapped(G_OBJECT(MsgDlg), "destroy", G_CALLBACK(gtk_main_quit), NULL);
1175 g_signal_connect_swapped (MsgDlg,
1176 "response",
1177 G_CALLBACK (gtk_widget_destroy),
1178 MsgDlg);
1179
1180 gtk_main();
1181 }
1182
SysErrorMessage(gchar * primary,gchar * secondary)1183 void SysErrorMessage(gchar *primary, gchar *secondary) {
1184 GtkWidget *message_dialog;
1185 if (!UseGui)
1186 printf ("%s - %s\n", primary, secondary);
1187 else {
1188 message_dialog = gtk_message_dialog_new(NULL,
1189 GTK_DIALOG_MODAL,
1190 GTK_MESSAGE_ERROR,
1191 GTK_BUTTONS_CLOSE,
1192 primary,
1193 NULL);
1194 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(message_dialog),
1195 "%s", secondary);
1196
1197 gtk_dialog_run(GTK_DIALOG(message_dialog));
1198 gtk_widget_destroy(message_dialog);
1199 }
1200 }
1201
SysInfoMessage(gchar * primary,gchar * secondary)1202 void SysInfoMessage(gchar *primary, gchar *secondary) {
1203 GtkWidget *message_dialog;
1204 if (!UseGui)
1205 printf ("%s - %s\n", primary, secondary);
1206 else {
1207 message_dialog = gtk_message_dialog_new(NULL,
1208 GTK_DIALOG_MODAL,
1209 GTK_MESSAGE_INFO,
1210 GTK_BUTTONS_CLOSE,
1211 primary,
1212 NULL);
1213 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(message_dialog),
1214 "%s", secondary);
1215
1216 gtk_dialog_run(GTK_DIALOG(message_dialog));
1217 gtk_widget_destroy(message_dialog);
1218 }
1219 }
1220