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 "Linux.h"
32 #include "ConfDlg.h"
33 
34 #include "../libpcsxcore/plugins.h"
35 
36 static void OnBiosPath_Changed(GtkWidget *wdg, gpointer data);
37 static void OnConf_Clicked(GtkDialog *dialog, gint arg1, gpointer user_data);
38 static void OnPluginPath_Changed(GtkWidget *wdg, gpointer data);
39 static void OnConfConf_Pad1About(GtkWidget *widget, gpointer user_data);
40 static void OnConfConf_Pad2About(GtkWidget *widget, gpointer user_data);
41 static void OnConfConf_Pad1Conf(GtkWidget *widget, gpointer user_data);
42 static void OnConfConf_Pad2Conf(GtkWidget *widget, gpointer user_data);
43 static void OnNet_Conf(GtkWidget *widget, gpointer user_data);
44 static void OnNet_About(GtkWidget *widget, gpointer user_data);
45 static void on_configure_plugin(GtkWidget *widget, gpointer user_data);
46 static void on_about_plugin(GtkWidget *widget, gpointer user_data);
47 static void UpdatePluginsBIOS_UpdateGUI();
48 static void FindNetPlugin();
49 
50 PSEgetLibType		PSE_getLibType = NULL;
51 PSEgetLibVersion	PSE_getLibVersion = NULL;
52 PSEgetLibName		PSE_getLibName = NULL;
53 
54 static GtkBuilder *builder;
55 GtkWidget *ConfDlg = NULL;
56 GtkWidget *NetDlg = NULL;
57 GtkWidget *controlwidget = NULL;
58 
59 PluginConf GpuConfS;
60 PluginConf SpuConfS;
61 PluginConf CdrConfS;
62 PluginConf Pad1ConfS;
63 PluginConf Pad2ConfS;
64 PluginConf NetConfS;
65 #ifdef ENABLE_SIO1API
66 PluginConf Sio1ConfS;
67 #endif
68 PluginConf BiosConfS;
69 
70 #define FindComboText(combo, list, conf) \
71 	if (strlen(conf) > 0) { \
72 		int i; \
73 		for (i = 2; i < 255; i += 2) { \
74 			if (!strcmp(conf, list[i - 2])) { \
75 				gtk_combo_box_set_active(GTK_COMBO_BOX(combo), i / 2 - 1); \
76 				break; \
77 			} \
78 		} \
79 	}
80 
81 #define GetComboText(combo, list, conf) \
82 	{ \
83 		int row; \
84 		row = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); \
85 		strcpy(conf, (char *)list[row * 2]); \
86 	}
87 
ConfigurePlugins()88 void ConfigurePlugins() {
89 	if (!UseGui) {
90 		/* How do we get here if we're not running the GUI? */
91 		/* Ryan: we're going to imagine that someday, there will be a way
92 		 * to configure plugins from the commandline */
93 		printf("ERROR: Plugins cannot be configured without the GUI.");
94 		return;
95 	}
96 
97 	GtkWidget *widget;
98 
99 	gchar *path;
100 
101 	UpdatePluginsBIOS();
102 
103 	builder = gtk_builder_new();
104 	if (!gtk_builder_add_from_resource(builder, "/org/pcsxr/gui/pcsxr.ui", NULL)) {
105 		g_warning("Error: interface could not be loaded!");
106 		return;
107 	}
108 
109 	UpdatePluginsBIOS_UpdateGUI(builder);
110 
111 	ConfDlg = GTK_WIDGET(gtk_builder_get_object(builder, "ConfDlg"));
112 
113 	gtk_window_set_title(GTK_WINDOW(ConfDlg), _("Configure PCSXR"));
114 	gtk_widget_show (ConfDlg);
115 
116 	/* Set the paths in the file choosers to be based on the saved configurations */
117 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkFileChooser_Bios"));
118 	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (widget), Config.BiosDir);
119 
120 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkFileChooser_Plugin"));
121 	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (widget), Config.PluginsDir);
122 
123 	if (strlen(Config.PluginsDir) == 0) {
124 		if((path = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (widget))) != NULL) {
125 			strcpy(Config.PluginsDir, path);
126 			g_free(path);
127 		}
128 	}
129 
130 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_ConfGpu"));
131 	g_signal_connect_data(G_OBJECT(widget), "clicked",
132 			G_CALLBACK(on_configure_plugin), GINT_TO_POINTER(PSE_LT_GPU), NULL, G_CONNECT_AFTER);
133 
134 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_ConfSpu"));
135 	g_signal_connect_data(G_OBJECT(widget), "clicked",
136 			G_CALLBACK(on_configure_plugin), GINT_TO_POINTER(PSE_LT_SPU), NULL, G_CONNECT_AFTER);
137 
138 	/* ADB TODO Does pad 1 and 2 need to be different? */
139 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_ConfPad1"));
140 	g_signal_connect_data(G_OBJECT(widget), "clicked",
141 						  G_CALLBACK(OnConfConf_Pad1Conf), builder, NULL, G_CONNECT_AFTER);
142 
143 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_ConfPad2"));
144 	g_signal_connect_data(G_OBJECT(widget), "clicked",
145 			G_CALLBACK(OnConfConf_Pad2Conf), builder, NULL, G_CONNECT_AFTER);
146 
147 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_ConfCdr"));
148 	g_signal_connect_data(G_OBJECT(widget), "clicked",
149 			G_CALLBACK(on_configure_plugin), GINT_TO_POINTER(PSE_LT_CDR), NULL, G_CONNECT_AFTER);
150 #ifdef ENABLE_SIO1API
151 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_ConfSio1"));
152 	g_signal_connect_data(G_OBJECT(widget), "clicked",
153 			G_CALLBACK(on_configure_plugin), (gpointer) PSE_LT_SIO1, NULL, G_CONNECT_AFTER);
154 #else
155 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "label18"));
156 	gtk_widget_set_sensitive(widget, FALSE);
157 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkCombo_Sio1"));
158 	gtk_widget_set_sensitive(widget, FALSE);
159 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_ConfSio1"));
160 	gtk_widget_set_sensitive(widget, FALSE);
161 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_AboutSio1"));
162 	gtk_widget_set_sensitive(widget, FALSE);
163 #endif
164 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_AboutGpu"));
165 	g_signal_connect_data(G_OBJECT(widget), "clicked",
166 			G_CALLBACK(on_about_plugin), GINT_TO_POINTER(PSE_LT_GPU), NULL, G_CONNECT_AFTER);
167 
168 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_AboutSpu"));
169 	g_signal_connect_data(G_OBJECT(widget), "clicked",
170 			G_CALLBACK(on_about_plugin), GINT_TO_POINTER(PSE_LT_SPU), NULL, G_CONNECT_AFTER);
171 
172 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_AboutPad1"));
173 	g_signal_connect_data(G_OBJECT(widget), "clicked",
174 			G_CALLBACK(OnConfConf_Pad1About), builder, NULL, G_CONNECT_AFTER);
175 
176 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_AboutPad2"));
177 	g_signal_connect_data(G_OBJECT(widget), "clicked",
178 			G_CALLBACK(OnConfConf_Pad2About), builder, NULL, G_CONNECT_AFTER);
179 
180 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_AboutCdr"));
181 	g_signal_connect_data(G_OBJECT(widget), "clicked",
182 			G_CALLBACK(on_about_plugin), GINT_TO_POINTER(PSE_LT_CDR), NULL, G_CONNECT_AFTER);
183 #ifdef ENABLE_SIO1API
184 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_AboutSio1"));
185 	g_signal_connect_data(G_OBJECT(widget), "clicked",
186 			G_CALLBACK(on_about_plugin), (gpointer) PSE_LT_SIO1, NULL, G_CONNECT_AFTER);
187 #endif
188 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkFileChooser_Bios"));
189 	g_signal_connect_data(G_OBJECT(widget), "current_folder_changed",
190 			G_CALLBACK(OnBiosPath_Changed), builder, NULL, G_CONNECT_AFTER);
191 
192 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkFileChooser_Plugin"));
193 	g_signal_connect_data(G_OBJECT(widget), "current_folder_changed",
194 			G_CALLBACK(OnPluginPath_Changed), builder, NULL, G_CONNECT_AFTER);
195 
196 	g_signal_connect_data(G_OBJECT(ConfDlg), "response",
197 			G_CALLBACK(OnConf_Clicked), builder, (GClosureNotify)g_object_unref, G_CONNECT_AFTER);
198 }
199 
OnNet_Clicked(GtkDialog * dialog,gint arg1,gpointer user_data)200 void OnNet_Clicked(GtkDialog *dialog, gint arg1, gpointer user_data) {
201 	GetComboText(NetConfS.Combo, NetConfS.plist, Config.Net);
202 	SaveConfig();
203 	gtk_widget_destroy(GTK_WIDGET(dialog));
204 	NetDlg = NULL;
205 }
206 
OnConf_Net()207 void OnConf_Net() {
208 	GtkWidget *widget;
209 
210 	if (NetDlg != NULL) {
211 		gtk_window_present (GTK_WINDOW (NetDlg));
212 		return;
213 	}
214 
215 	builder = gtk_builder_new();
216 	if (!gtk_builder_add_from_resource(builder, "/org/pcsxr/gui/pcsxr.ui", NULL)) {
217 		g_warning("Error: interface could not be loaded!");
218 		return;
219 	}
220 
221 	NetDlg = GTK_WIDGET(gtk_builder_get_object(builder, "NetDlg"));
222 
223 	gtk_widget_show (NetDlg);
224 
225 	FindNetPlugin(builder);
226 
227 	/* Setup a handler for when Close or Cancel is clicked */
228 	g_signal_connect_data(G_OBJECT(NetDlg), "response",
229 			G_CALLBACK(OnNet_Clicked), builder, (GClosureNotify)g_object_unref, G_CONNECT_AFTER);
230 
231 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_ConfNet"));
232 	g_signal_connect_data(G_OBJECT(widget), "clicked",
233 			G_CALLBACK(OnNet_Conf), builder, NULL, G_CONNECT_AFTER);
234 
235 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_AboutNet"));
236 	g_signal_connect_data(G_OBJECT(widget), "clicked",
237 			G_CALLBACK(OnNet_About), builder, NULL, G_CONNECT_AFTER);
238 }
239 
OnConf_Graphics()240 void OnConf_Graphics() {
241 	void *drv;
242 	GPUconfigure conf;
243 	char Plugin[MAXPATHLEN];
244 
245 	sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Gpu);
246 	drv = SysLoadLibrary(Plugin);
247 	if (drv == NULL) { printf("Error with file %s\n", Plugin); return; }
248 
249 	while (gtk_events_pending()) gtk_main_iteration();
250 
251 	conf = (GPUconfigure)SysLoadSym(drv, "GPUconfigure");
252 	if (conf != NULL) {
253 		conf();
254 	}
255 	else
256 		SysInfoMessage (_("No configuration required"), _("This plugin doesn't need to be configured."));
257 
258 	SysCloseLibrary(drv);
259 }
260 
OnConf_Sound()261 void OnConf_Sound() {
262 	void *drv;
263 	SPUconfigure conf;
264 	char Plugin[MAXPATHLEN];
265 
266 	sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Spu);
267 	drv = SysLoadLibrary(Plugin);
268 	if (drv == NULL) { printf("Error with file %s\n", Plugin); return; }
269 
270 	while (gtk_events_pending()) gtk_main_iteration();
271 
272 	conf = (GPUconfigure)SysLoadSym(drv, "SPUconfigure");
273 	if (conf != NULL) {
274 		conf();
275 	}
276 	else
277 		SysInfoMessage (_("No configuration required"), _("This plugin doesn't need to be configured."));
278 
279 	SysCloseLibrary(drv);
280 }
281 
OnConf_CdRom()282 void OnConf_CdRom() {
283 	void *drv;
284 	CDRconfigure conf;
285 	char Plugin[MAXPATHLEN];
286 
287 	sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
288 	drv = SysLoadLibrary(Plugin);
289 	if (drv == NULL) { printf("Error with file %s\n", Plugin); return; }
290 
291 	while (gtk_events_pending()) gtk_main_iteration();
292 
293 	conf = (GPUconfigure)SysLoadSym(drv, "CDRconfigure");
294 	if (conf != NULL) {
295 		conf();
296 	}
297 	else
298 		SysInfoMessage (_("No configuration required"), _("This plugin doesn't need to be configured."));
299 
300 	SysCloseLibrary(drv);
301 }
302 #ifdef ENABLE_SIO1API
OnConf_Sio1()303 void OnConf_Sio1() {
304 	void *drv;
305 	SIO1configure conf;
306 	char Plugin[MAXPATHLEN];
307 
308 	sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Sio1);
309 	drv = SysLoadLibrary(Plugin);
310 	if (drv == NULL) { printf("Error with file %s\n", Plugin); return; }
311 
312 	while (gtk_events_pending()) gtk_main_iteration();
313 
314 	conf = (SIO1configure)SysLoadSym(drv, "SIO1configure");
315 	if (conf != NULL) {
316 		conf();
317 	}
318 	else
319 		SysInfoMessage (_("No configuration required"), _("This plugin doesn't need to be configured."));
320 
321 	SysCloseLibrary(drv);
322 }
323 #endif
OnConf_Pad()324 void OnConf_Pad() {
325 	void *drv;
326 	PADconfigure conf;
327 	char Plugin[MAXPATHLEN];
328 
329 	// PAD 1
330 	sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad1);
331 	drv = SysLoadLibrary(Plugin);
332 	if (drv == NULL) { printf("Error with file %s\n", Plugin); return; }
333 
334 	while (gtk_events_pending()) gtk_main_iteration();
335 
336 	conf = (PADconfigure)SysLoadSym(drv, "PADconfigure");
337 	if (conf != NULL) {
338 		conf();
339 	}
340 	else
341 		SysInfoMessage (_("No configuration required"), _("This plugin doesn't need to be configured."));
342 
343 	SysCloseLibrary(drv);
344 
345 	// PAD 2
346 	if (strcmp(Config.Pad1, Config.Pad2) != 0) {
347 		sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad2);
348 		drv = SysLoadLibrary(Plugin);
349 		if (drv == NULL) { printf("Error with file %s\n", Plugin); return; }
350 
351 		while (gtk_events_pending()) gtk_main_iteration();
352 
353 		conf = (PADconfigure)SysLoadSym(drv, "PADconfigure");
354 		if (conf != NULL) {
355 			conf();
356 		}
357 
358 		SysCloseLibrary(drv);
359 	}
360 }
361 
all_config_set()362 static int all_config_set() {
363 	int retval;
364 
365 	if ((strlen(Config.Gpu) != 0) &&
366 		(strlen(Config.Spu) != 0) &&
367 		(strlen(Config.Cdr) != 0) &&
368 #ifdef ENABLE_SIO1API
369 		(strlen(Config.Sio1) != 0) &&
370 #endif
371 		(strlen(Config.Pad1) != 0) &&
372 		(strlen(Config.Pad2) != 0))
373 		retval = TRUE;
374 	else
375 		retval = FALSE;
376 
377 	return retval;
378 }
379 
380 /* TODO Check whether configuration is required when we choose the plugin, and set the state of the
381     button appropriately. New gtk tooltip API should allow us to put a tooltip explanation for
382     disabled widgets */
383 /* TODO If combo screen hasn't been opened and the user chooses the menu config option, confs.Combo will be null and cause a segfault */
384 #define ConfPlugin(src, confs, plugin, name, parent)  { \
385 	void *drv; \
386 	src conf; \
387 	gchar *filename; \
388  \
389 	GetComboText(confs.Combo, confs.plist, plugin); \
390 	if (strlen(plugin) > 0) { \
391 		filename = g_build_filename (getenv("HOME"), PLUGINS_DIR, plugin, NULL); \
392 		/*printf("Configuring plugin %s\n", filename);*/ \
393 		drv = SysLoadLibrary(filename); \
394 		if (drv == NULL) {printf("Error with file %s\n", filename);return; } \
395 \
396 		while (gtk_events_pending()) gtk_main_iteration(); \
397 			conf = (src) SysLoadSym(drv, name); \
398 		if (conf) { \
399 			conf(); \
400 		} else \
401 			SysInfoMessage (_("No configuration required"), _("This plugin doesn't need to be configured.")); \
402 		SysCloseLibrary(drv); \
403 		g_free (filename); \
404 	} else SysInfoMessage (name, _("Please select a plugin.")); \
405 }
406 
on_configure_plugin(GtkWidget * widget,gpointer user_data)407 static void on_configure_plugin(GtkWidget *widget, gpointer user_data) {
408 	gint plugin_type = GPOINTER_TO_INT(user_data);
409 
410 	while (gtk_events_pending())
411 		gtk_main_iteration();
412 
413 	switch (plugin_type) {
414 		case PSE_LT_GPU:
415 			ConfPlugin(GPUconfigure, GpuConfS, Config.Gpu, "GPUconfigure", ConfDlg);
416 			break;
417 		case PSE_LT_SPU:
418 			ConfPlugin(SPUconfigure, SpuConfS, Config.Spu, "SPUconfigure", ConfDlg);
419 			break;
420 		case PSE_LT_CDR:
421 			ConfPlugin(CDRconfigure, CdrConfS, Config.Cdr, "CDRconfigure", ConfDlg);
422 			break;
423 #ifdef ENABLE_SIO1API
424 		case PSE_LT_SIO1:
425 			ConfPlugin(SIO1configure, Sio1ConfS, Config.Sio1, "SIO1configure", ConfDlg);
426 			break;
427 #endif
428 	}
429 }
430 
on_about_plugin(GtkWidget * widget,gpointer user_data)431 static void on_about_plugin(GtkWidget *widget, gpointer user_data) {
432 	gint plugin_type = GPOINTER_TO_INT(user_data);
433 
434 	while (gtk_events_pending())
435 		gtk_main_iteration();
436 
437 	switch (plugin_type) {
438 		case PSE_LT_GPU:
439 			ConfPlugin(GPUconfigure, GpuConfS, Config.Gpu, "GPUabout", ConfDlg);
440 			break;
441 		case PSE_LT_SPU:
442 			ConfPlugin(SPUconfigure, SpuConfS, Config.Spu, "SPUabout", ConfDlg);
443 			break;
444 		case PSE_LT_CDR:
445 			ConfPlugin(CDRconfigure, CdrConfS, Config.Cdr, "CDRabout", ConfDlg);
446 			break;
447 #ifdef ENABLE_SIO1API
448 		case PSE_LT_SIO1:
449 			ConfPlugin(SIO1configure, Sio1ConfS, Config.Sio1, "SIO1about", ConfDlg);
450 			break;
451 #endif
452 	}
453 }
454 
OnConfConf_Pad1About(GtkWidget * widget,gpointer user_data)455 static void OnConfConf_Pad1About(GtkWidget *widget, gpointer user_data) {
456 	ConfPlugin(PADabout, Pad1ConfS, Config.Pad1, "PADabout", ConfDlg);
457 }
458 
OnConfConf_Pad2About(GtkWidget * widget,gpointer user_data)459 static void OnConfConf_Pad2About(GtkWidget *widget, gpointer user_data) {
460 	ConfPlugin(PADabout, Pad2ConfS, Config.Pad2, "PADabout", ConfDlg);
461 }
462 
OnConfConf_Pad1Conf(GtkWidget * widget,gpointer user_data)463 static void OnConfConf_Pad1Conf(GtkWidget *widget, gpointer user_data) {
464 	ConfPlugin(PADabout, Pad1ConfS, Config.Pad1, "PADconfigure", ConfDlg);
465 }
466 
OnConfConf_Pad2Conf(GtkWidget * widget,gpointer user_data)467 static void OnConfConf_Pad2Conf(GtkWidget *widget, gpointer user_data) {
468 	ConfPlugin(PADabout, Pad2ConfS, Config.Pad2, "PADconfigure", ConfDlg);
469 }
470 
OnNet_Conf(GtkWidget * widget,gpointer user_data)471 static void OnNet_Conf(GtkWidget *widget, gpointer user_data) {
472 	ConfPlugin(NETconfigure, NetConfS, Config.Net, "NETconfigure", NetDlg);
473 }
474 
OnNet_About(GtkWidget * widget,gpointer user_data)475 static void OnNet_About(GtkWidget *widget, gpointer user_data) {
476 	ConfPlugin(NETabout, NetConfS, Config.Net, "NETabout", NetDlg);
477 }
478 
OnPluginPath_Changed(GtkWidget * wdg,gpointer data)479 static void OnPluginPath_Changed(GtkWidget *wdg, gpointer data) {
480 	gchar *path;
481 
482 	path = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (wdg));
483 	GSList * l = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER (wdg));
484 	//printf(("%s and %s\n"), path, l->data);
485 
486     if (l) path = l->data;
487 	strcpy(Config.PluginsDir, path);
488 
489     UpdatePluginsBIOS();
490 	UpdatePluginsBIOS_UpdateGUI(data);
491 
492 	g_free(path);
493 }
494 
OnBiosPath_Changed(GtkWidget * wdg,gpointer data)495 static void OnBiosPath_Changed(GtkWidget *wdg, gpointer data) {
496 	gchar *foldername;
497 
498 	foldername = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (wdg));
499 	GSList * l = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER (wdg));
500 	//printf(("%s and %s\n"), foldername, l->data);
501 
502 	if (l) foldername = l->data;
503 	strcpy(Config.BiosDir, foldername);
504 
505 	UpdatePluginsBIOS();
506 	UpdatePluginsBIOS_UpdateGUI(data);
507 
508 	g_free(foldername);
509 }
510 
OnConf_Clicked(GtkDialog * dialog,gint arg1,gpointer user_data)511 void OnConf_Clicked(GtkDialog *dialog, gint arg1, gpointer user_data) {
512 	GetComboText(GpuConfS.Combo, GpuConfS.plist, Config.Gpu);
513 	GetComboText(SpuConfS.Combo, SpuConfS.plist, Config.Spu);
514 	GetComboText(CdrConfS.Combo, CdrConfS.plist, Config.Cdr);
515 #ifdef ENABLE_SIO1API
516 	GetComboText(Sio1ConfS.Combo, Sio1ConfS.plist, Config.Sio1);
517 #endif
518 	GetComboText(Pad1ConfS.Combo, Pad1ConfS.plist, Config.Pad1);
519 	GetComboText(Pad2ConfS.Combo, Pad2ConfS.plist, Config.Pad2);
520 	GetComboText(BiosConfS.Combo, BiosConfS.plist, Config.Bios);
521 
522 	SaveConfig();
523 
524 	gtk_widget_destroy(ConfDlg);
525 	ConfDlg = NULL;
526 }
527 
528 #define ComboAddPlugin(type) { \
529 	type##ConfS.plugins += 2; \
530 	strcpy(type##ConfS.plist[type##ConfS.plugins - 1], name); \
531 	strcpy(type##ConfS.plist[type##ConfS.plugins - 2], ent->d_name); \
532 	type##ConfS.glist = g_list_append(type##ConfS.glist, type##ConfS.plist[type##ConfS.plugins-1]); \
533 }
534 
populate_combo_box(GtkWidget * widget,GList * list)535 void populate_combo_box(GtkWidget *widget, GList *list) {
536 	GtkListStore *store;
537 	GtkCellRenderer *renderer;
538 	store = gtk_list_store_new(1, G_TYPE_STRING);
539 
540 	// Clear existing data from combo box
541 	gtk_cell_layout_clear(GTK_CELL_LAYOUT(widget));
542 
543 	renderer = gtk_cell_renderer_text_new();
544 	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, FALSE);
545 	gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 0);
546 
547 	while (list != NULL) {
548 		GtkTreeIter iter;
549 		gtk_list_store_append(store, &iter);
550 		gtk_list_store_set(store, &iter, 0, (char *)list->data, -1);
551 		list = list->next;
552 	}
553 
554 	gtk_combo_box_set_model(GTK_COMBO_BOX(widget), GTK_TREE_MODEL(store));
555 }
556 
557 #define ConfCreatePConf(name, type) \
558 	/* Populate the relevant combo widget with the list of plugins. \
559 	   If no plugins available, disable the combo and its controls. \
560 	   Note that the Bios plugin has no About/Conf control. */ \
561 	type##ConfS.Combo = GTK_WIDGET(gtk_builder_get_object(builder, "GtkCombo_" name)); \
562 	if (type##ConfS.glist != NULL) { \
563 		populate_combo_box (type##ConfS.Combo, type##ConfS.glist); \
564 		FindComboText(type##ConfS.Combo, type##ConfS.plist, Config.type); \
565 		gtk_widget_set_sensitive (type##ConfS.Combo, TRUE); \
566 		if (g_ascii_strcasecmp (name, "Bios") != 0) { \
567 			controlwidget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_Conf" name)); \
568 			gtk_widget_set_sensitive (controlwidget, TRUE); \
569 			controlwidget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_About" name)); \
570 			gtk_widget_set_sensitive (controlwidget, TRUE); \
571 		} \
572 	} else { \
573 		if (g_ascii_strcasecmp (name, "Bios") != 0) { \
574 			gtk_combo_box_set_model(GTK_COMBO_BOX(type##ConfS.Combo), NULL); \
575 			gtk_widget_set_sensitive (type##ConfS.Combo, FALSE); \
576 			controlwidget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_Conf" name)); \
577 			gtk_widget_set_sensitive (controlwidget, FALSE); \
578 			controlwidget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_About" name)); \
579 			gtk_widget_set_sensitive (controlwidget, FALSE); \
580 		} \
581 	}
582 
plugin_is_available(gchar * plugin)583 int plugin_is_available(gchar *plugin) {
584 	int retval;
585 	gchar *pluginfile;
586 	struct stat stbuf;
587 
588 	pluginfile = g_strconcat(getenv("HOME"), PLUGINS_DIR, plugin, NULL);
589 
590 	if (stat(pluginfile, &stbuf) == -1)
591 		retval = FALSE;
592 	else
593 		retval = TRUE;
594 
595 	g_free(pluginfile);
596 
597 	return retval;
598 }
599 
plugins_configured()600 int plugins_configured() {
601 	// make sure there are choices for all of the plugins!!
602 	if (all_config_set() == FALSE)
603 		return FALSE;
604 
605 	// and make sure they can all be accessed
606 	// if they can't be, wipe the variable and return FALSE
607 	if (plugin_is_available (Config.Gpu) == FALSE) { Config.Gpu[0] = '\0'; return FALSE; }
608 	if (plugin_is_available (Config.Spu) == FALSE) { Config.Spu[0] = '\0'; return FALSE; }
609 	if (plugin_is_available (Config.Cdr) == FALSE) { Config.Cdr[0] = '\0'; return FALSE; }
610 #ifdef ENABLE_SIO1API
611 	if (plugin_is_available (Config.Sio1) == FALSE) { Config.Sio1[0] = '\0'; return FALSE; }
612 #endif
613 	if (plugin_is_available (Config.Pad1) == FALSE) { Config.Pad1[0] = '\0'; return FALSE; }
614 	if (plugin_is_available (Config.Pad2) == FALSE) { Config.Pad2[0] = '\0'; return FALSE; }
615 
616 	// if everything is happy, return TRUE
617 	return TRUE;
618 }
619 
is_valid_bios_file(gchar * filename)620 int is_valid_bios_file(gchar *filename) {
621 	int valid;
622 	struct stat buf;
623 
624 	if ((stat(filename, &buf) == -1) || (buf.st_size != (1024*512)))
625 		valid = FALSE;
626 	else {
627 		valid = TRUE;
628 	}
629 
630 	return valid;
631 }
632 
633 // Add the name of the BIOS file to the drop-down list. This will
634 // be the filename, not the full path to the file
add_bios_to_list(gchar * bios_name,gchar * internal_name)635 void add_bios_to_list(gchar *bios_name, gchar *internal_name) {
636 	BiosConfS.plugins += 2;
637 	strcpy(BiosConfS.plist[BiosConfS.plugins - 1], bios_name);
638 	strcpy(BiosConfS.plist[BiosConfS.plugins - 2], internal_name);
639 	BiosConfS.glist = g_list_append(BiosConfS.glist, BiosConfS.plist[BiosConfS.plugins - 1]);
640 }
641 
scan_bios_dir(gchar * dirname)642 void scan_bios_dir(gchar *dirname) {
643 	DIR *dir;
644 	struct dirent *ent;
645 	gchar *filename;
646 
647 	dir = opendir(dirname);
648 	if (dir == NULL) {
649 		SysMessage(_("Could not open BIOS directory: '%s'\n"), dirname);
650 		return;
651 	}
652 
653 	while ((ent = readdir(dir)) != NULL) {
654 		filename = g_build_filename(dirname, ent->d_name, NULL);
655 		if (is_valid_bios_file(filename))
656 			add_bios_to_list(g_path_get_basename(filename), g_path_get_basename (filename));
657 		g_free(filename);
658 	}
659 	closedir(dir);
660 }
661 
UpdatePluginsBIOS()662 void UpdatePluginsBIOS() {
663 	DIR *dir;
664 	struct dirent *ent;
665 	void *Handle;
666 	char name[256];
667 	gchar *linkname;
668 
669 	GpuConfS.plugins  = 0;
670 	SpuConfS.plugins  = 0;
671 	CdrConfS.plugins  = 0;
672 #ifdef ENABLE_SIO1API
673 	Sio1ConfS.plugins = 0;
674 #endif
675 	Pad1ConfS.plugins = 0;
676 	Pad2ConfS.plugins = 0;
677 	BiosConfS.plugins = 0;
678 	GpuConfS.glist  = NULL;
679 	SpuConfS.glist  = NULL;
680 	CdrConfS.glist  = NULL;
681 #ifdef ENABLE_SIO1API
682 	Sio1ConfS.glist  = NULL;
683 #endif
684 	Pad1ConfS.glist = NULL;
685 	Pad2ConfS.glist = NULL;
686 	BiosConfS.glist = NULL;
687 	GpuConfS.plist[0][0]  = '\0';
688 	SpuConfS.plist[0][0]  = '\0';
689 	CdrConfS.plist[0][0]  = '\0';
690 #ifdef ENABLE_SIO1API
691 	Sio1ConfS.plist[0][0]  = '\0';
692 #endif
693 	Pad1ConfS.plist[0][0] = '\0';
694 	Pad2ConfS.plist[0][0] = '\0';
695 	BiosConfS.plist[0][0] = '\0';
696 
697 	// Load and get plugin info
698 	dir = opendir(Config.PluginsDir);
699 	if (dir == NULL) {
700 		printf(_("Could not open directory: '%s'\n"), Config.PluginsDir);
701 		return;
702 	}
703 	while ((ent = readdir(dir)) != NULL) {
704 		long type, v;
705 		linkname = g_build_filename(Config.PluginsDir, ent->d_name, NULL);
706 
707 		// only libraries past this point, not config tools
708 		if (strstr(linkname, ".so") == NULL && strstr(linkname, ".dylib") == NULL)
709 			continue;
710 
711 		Handle = dlopen(linkname, RTLD_NOW);
712 		if (Handle == NULL) {
713 			printf("%s\n", dlerror());
714 			g_free(linkname);
715 			continue;
716 		}
717 
718 		PSE_getLibType = (PSEgetLibType)dlsym(Handle, "PSEgetLibType");
719 		if (PSE_getLibType == NULL) {
720 			if (strstr(linkname, "gpu") != NULL) type = PSE_LT_GPU;
721 			else if (strstr(linkname, "cdr") != NULL) type = PSE_LT_CDR;
722 #ifdef ENABLE_SIO1API
723 			else if (strstr(linkname, "sio1") != NULL) type = PSE_LT_SIO1;
724 #endif
725 			else if (strstr(linkname, "spu") != NULL) type = PSE_LT_SPU;
726 			else if (strstr(linkname, "pad") != NULL) type = PSE_LT_PAD;
727 			else { g_free(linkname); continue; }
728 		}
729 		else type = PSE_getLibType();
730 
731 		PSE_getLibName = (PSEgetLibName) dlsym(Handle, "PSEgetLibName");
732 		if (PSE_getLibName != NULL) {
733 			sprintf(name, "%s", PSE_getLibName());
734 			PSE_getLibVersion = (PSEgetLibVersion) dlsym(Handle, "PSEgetLibVersion");
735 			if (PSE_getLibVersion != NULL) {
736 				char ver[32];
737 
738 				v = PSE_getLibVersion();
739 				sprintf(ver, " %ld.%ld.%ld", v >> 16, (v >> 8) & 0xff, v & 0xff);
740 				strcat(name, ver);
741 			}
742 		}
743 		else strcpy(name, ent->d_name);
744 
745 		if (type & PSE_LT_CDR)
746 			ComboAddPlugin(Cdr);
747 #ifdef ENABLE_SIO1API
748 		if (type & PSE_LT_SIO1)
749 			ComboAddPlugin(Sio1);
750 #endif
751 		if (type & PSE_LT_GPU)
752 			ComboAddPlugin(Gpu);
753 		if (type & PSE_LT_SPU)
754 			ComboAddPlugin(Spu);
755 		if (type & PSE_LT_PAD) {
756 			PADquery query = (PADquery)dlsym(Handle, "PADquery");
757 			if (query() & 0x1) {
758 				ComboAddPlugin(Pad1);
759 			}
760 			if (query() & 0x2) {
761 				ComboAddPlugin(Pad2);
762 			}
763 		}
764 		g_free(linkname);
765 	}
766 	closedir(dir);
767 
768 	scan_bios_dir(Config.BiosDir);
769 
770 	// The BIOS list always contains the PCSXR internal BIOS
771 	add_bios_to_list(_("Simulate PSX BIOS"), "HLE");
772 }
773 
UpdatePluginsBIOS_UpdateGUI()774 static void UpdatePluginsBIOS_UpdateGUI() {
775 	// Populate the plugin combo boxes
776 	ConfCreatePConf("Gpu", Gpu);
777 	ConfCreatePConf("Spu", Spu);
778 	ConfCreatePConf("Pad1", Pad1);
779 	ConfCreatePConf("Pad2", Pad2);
780 	ConfCreatePConf("Cdr", Cdr);
781 #ifdef ENABLE_SIO1API
782 	ConfCreatePConf("Sio1", Sio1);
783 #endif
784 	ConfCreatePConf("Bios", Bios);
785 }
786 
FindNetPlugin()787 static void FindNetPlugin() {
788 	DIR *dir;
789 	struct dirent *ent;
790 	void *Handle;
791 	char plugin[MAXPATHLEN],name[MAXPATHLEN];
792 
793 	NetConfS.plugins  = 0;
794 	NetConfS.glist = NULL;
795 
796 	NetConfS.plugins += 2;
797 	strcpy(NetConfS.plist[NetConfS.plugins - 1], "Disabled");
798 	strcpy(NetConfS.plist[NetConfS.plugins - 2], "Disabled");
799 	NetConfS.glist = g_list_append(NetConfS.glist, NetConfS.plist[NetConfS.plugins - 1]);
800 
801 	dir = opendir(Config.PluginsDir);
802 	if (dir == NULL)
803 		SysMessage(_("Could not open directory: '%s'\n"), Config.PluginsDir);
804 	else {
805 		/* ADB TODO Replace the following with a function */
806 		while ((ent = readdir(dir)) != NULL) {
807 			long type, v;
808 
809 			sprintf(plugin, "%s/%s", Config.PluginsDir, ent->d_name);
810 
811 			if (strstr(plugin, ".so") == NULL && strstr(plugin, ".dylib") == NULL)
812 				continue;
813 			Handle = dlopen(plugin, RTLD_NOW);
814 			if (Handle == NULL) continue;
815 
816 			PSE_getLibType = (PSEgetLibType) dlsym(Handle, "PSEgetLibType");
817 			if (PSE_getLibType == NULL) {
818 				if (strstr(plugin, "net") != NULL) type = PSE_LT_NET;
819 				else continue;
820 			}
821 			else type = PSE_getLibType();
822 
823 			PSE_getLibName = (PSEgetLibName) dlsym(Handle, "PSEgetLibName");
824 			if (PSE_getLibName != NULL) {
825 				sprintf(name, "%s", PSE_getLibName());
826 				PSE_getLibVersion = (PSEgetLibVersion) dlsym(Handle, "PSEgetLibVersion");
827 				if (PSE_getLibVersion != NULL) {
828 					char ver[32];
829 
830 					v = PSE_getLibVersion();
831 					sprintf(ver, " %ld.%ld.%ld",v>>16,(v>>8)&0xff,v&0xff);
832 					strcat(name, ver);
833 				}
834 			}
835 			else strcpy(name, ent->d_name);
836 
837 			if (type & PSE_LT_NET) {
838 				ComboAddPlugin(Net);
839 			}
840 		}
841 		closedir(dir);
842 
843 		ConfCreatePConf("Net", Net);
844 	}
845 }
846 
847 GtkWidget *CpuDlg;
848 GList *psxglist;
849 char *psxtypes[] = {
850 	"NTSC",
851 	"PAL"
852 };
853 
854 // When the auto-detect CPU type is selected, disable the NTSC/PAL selection
OnCpu_PsxAutoClicked(GtkWidget * widget,gpointer user_data)855 static void OnCpu_PsxAutoClicked (GtkWidget *widget, gpointer user_data) {
856 	GtkWidget *combo;
857 	combo = GTK_WIDGET(gtk_builder_get_object(builder, "GtkCombo_PsxType"));
858 
859 	gtk_widget_set_sensitive (combo,
860 			!(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))));
861 }
862 
863 // When the interpreter core is deselected, disable the debugger checkbox & rewind
OnCpu_CpuClicked(GtkWidget * widget,gpointer user_data)864 static void OnCpu_CpuClicked(GtkWidget *widget, gpointer user_data) {
865 	GtkWidget *check, *rew;
866 	check = GTK_WIDGET(gtk_builder_get_object(builder, "GtkCheckButton_Dbg"));
867 	rew = GTK_WIDGET(gtk_builder_get_object(builder, "frame_rew"));
868 
869 	// Debugger is only working with interpreter not recompiler, so let's set it
870 	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
871 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), FALSE);
872 	}
873 	gtk_widget_set_sensitive (check,
874 			gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
875 	gtk_widget_set_sensitive (rew,
876 			gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
877 }
878 
OnCpu_Clicked(GtkDialog * dialog,gint arg1,gpointer user_data)879 void OnCpu_Clicked(GtkDialog *dialog, gint arg1, gpointer user_data) {
880 	GtkWidget *widget;
881 	long unsigned int tmp;
882 	long t;
883 
884 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkCombo_PsxType"));
885 
886 	// If nothing chosen, default to NTSC
887 	tmp = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
888 	if (tmp == -1)
889 		tmp = PSX_TYPE_NTSC;
890 
891 	if (!strcmp("NTSC", psxtypes[tmp]))
892 		Config.PsxType = PSX_TYPE_NTSC;
893 	else
894 		Config.PsxType = PSX_TYPE_PAL;
895 
896 	sscanf(gtk_entry_get_text(GTK_ENTRY(gtk_builder_get_object(builder, "GtkEntry_RewindCount"))), "%lu", &tmp);
897 	Config.RewindCount = tmp;
898 
899 	sscanf(gtk_entry_get_text(GTK_ENTRY(gtk_builder_get_object(builder, "GtkEntry_RewindInterval"))), "%lu", &tmp);
900 	Config.RewindInterval = tmp;
901 
902 	sscanf(gtk_entry_get_text(GTK_ENTRY(gtk_builder_get_object(builder, "GtkEntry_AltSpeed1"))), "%lu", &tmp);
903 	Config.AltSpeed1 = tmp;
904 
905 	sscanf(gtk_entry_get_text(GTK_ENTRY(gtk_builder_get_object(builder, "GtkEntry_AltSpeed2"))), "%lu", &tmp);
906 	Config.AltSpeed2 = tmp;
907 
908 	Config.Xa = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_Xa")));
909 	Config.SioIrq = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_SioIrq")));
910 	Config.Mdec = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_Mdec")));
911 	Config.Cdda = gtk_combo_box_get_active(GTK_COMBO_BOX(gtk_builder_get_object(builder, "GtkCombo_CDDA")));
912 	Config.SlowBoot = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_SlowBoot")));
913 	Config.PsxAuto = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_PsxAuto")));
914 
915 	t = Config.Debug;
916 	Config.Debug = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_Dbg")));
917 	if (t != Config.Debug) {
918 		if (Config.Debug) StartDebugger();
919 		else StopDebugger();
920 	}
921 
922 	t = Config.Cpu;
923 	Config.Cpu = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_Cpu")));
924 	if (t != Config.Cpu) {
925 		psxCpu->Shutdown();
926 #ifdef PSXREC
927 		if (Config.Cpu == CPU_INTERPRETER) {
928 			psxCpu = &psxInt;
929 		}
930 		else psxCpu = &psxRec;
931 #else
932 		psxCpu = &psxInt;
933 #endif
934 		if (psxCpu->Init() == -1) {
935 			SysClose();
936 			exit(1);
937 		}
938 		psxCpu->Reset();
939 	}
940 
941 	Config.PsxOut = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_PsxOut")));
942 	Config.SpuIrq = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_SpuIrq")));
943 	Config.RCntFix = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_RCntFix")));
944 	Config.VSyncWA = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_VSyncWA")));
945 	Config.NoMemcard = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_NoMemcard")));
946 	Config.Widescreen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_Widescreen")));
947 	Config.HackFix = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_HackFix")));
948 
949 	SaveConfig();
950 
951 	gtk_widget_destroy(CpuDlg);
952 	CpuDlg = NULL;
953 }
954 
OnConf_Cpu()955 void OnConf_Cpu() {
956 	GtkWidget *widget;
957 	char buf[25];
958 
959 	builder = gtk_builder_new();
960 
961 	if (!gtk_builder_add_from_resource(builder, "/org/pcsxr/gui/pcsxr.ui", NULL)) {
962 		g_warning("Error: interface could not be loaded!");
963 		return;
964 	}
965 
966 	CpuDlg = GTK_WIDGET(gtk_builder_get_object(builder, "CpuDlg"));
967 
968 	gtk_widget_show (CpuDlg);
969 
970 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkCombo_PsxType"));
971 	gtk_combo_box_set_active(GTK_COMBO_BOX (widget), Config.PsxType);
972 	gtk_widget_set_sensitive(GTK_WIDGET (widget), !Config.PsxAuto);
973 
974 	snprintf(buf, sizeof(buf), "%u", Config.RewindCount);
975 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkEntry_RewindCount"));
976 	gtk_entry_set_text(GTK_ENTRY(widget), buf);
977 
978 	snprintf(buf, sizeof(buf), "%u", Config.RewindInterval);
979 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkEntry_RewindInterval"));
980 	gtk_entry_set_text(GTK_ENTRY(widget), buf);
981 
982 	// Calculate estimated memory usage
983 	snprintf(buf, sizeof(buf), "%u", ((unsigned int)(((float)Config.RewindCount)*4.2f)));
984 	gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(builder, "GtkEntry_RewindMem")),
985 						buf);
986 
987 	// Enabled only if interpreter
988 	gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(builder, "frame_rew")), Config.Cpu);
989 
990 	snprintf(buf, sizeof(buf), "%u", Config.AltSpeed1);
991 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkEntry_AltSpeed1"));
992 	gtk_entry_set_text(GTK_ENTRY(widget), buf);
993 
994 	snprintf(buf, sizeof(buf), "%u", Config.AltSpeed2);
995 	widget = GTK_WIDGET(gtk_builder_get_object(builder, "GtkEntry_AltSpeed2"));
996 	gtk_entry_set_text(GTK_ENTRY(widget), buf);
997 
998 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_Xa")), Config.Xa);
999 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_SioIrq")), Config.SioIrq);
1000 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_Mdec")), Config.Mdec);
1001 	gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(builder, "GtkCombo_CDDA")), Config.Cdda);
1002 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_SlowBoot")), Config.SlowBoot);
1003 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_PsxAuto")), Config.PsxAuto);
1004 
1005 	g_signal_connect_data(G_OBJECT(gtk_builder_get_object(builder, "GtkCheckButton_PsxAuto")), "toggled",
1006 			G_CALLBACK(OnCpu_PsxAutoClicked), builder, NULL, G_CONNECT_AFTER);
1007 
1008 #ifdef PSXREC
1009 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (gtk_builder_get_object(builder, "GtkCheckButton_Cpu")), Config.Cpu);
1010 
1011 	g_signal_connect_data(G_OBJECT(gtk_builder_get_object(builder, "GtkCheckButton_Cpu")), "toggled",
1012 			G_CALLBACK(OnCpu_CpuClicked), builder, NULL, G_CONNECT_AFTER);
1013 #else
1014 	Config.Cpu = CPU_INTERPRETER;
1015 
1016 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (gtk_builder_get_object(builder, "GtkCheckButton_Cpu")), TRUE);
1017 	gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder, "GtkCheckButton_Cpu")), FALSE);
1018 #endif
1019 
1020 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (gtk_builder_get_object(builder, "GtkCheckButton_Dbg")), Config.Cpu && Config.Debug);
1021 	gtk_widget_set_sensitive(GTK_WIDGET (gtk_builder_get_object(builder, "GtkCheckButton_Dbg")), Config.Cpu);
1022 
1023 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_PsxOut")), Config.PsxOut);
1024 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_SpuIrq")), Config.SpuIrq);
1025 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_RCntFix")), Config.RCntFix);
1026 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_VSyncWA")), Config.VSyncWA);
1027 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_NoMemcard")), Config.NoMemcard);
1028 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_Widescreen")), Config.Widescreen);
1029 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_HackFix")), Config.HackFix);
1030 
1031 	// Setup a handler for when Close or Cancel is clicked
1032 	g_signal_connect_data(G_OBJECT(CpuDlg), "response",
1033 			G_CALLBACK(OnCpu_Clicked), builder, (GClosureNotify)g_object_unref, G_CONNECT_AFTER);
1034 }
1035