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