| 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 | |
| 37 | static void OnBiosPath_Changed(GtkWidget *wdg, gpointer data); |
| 38 | static void OnConf_Clicked(GtkDialog *dialog, gint arg1, gpointer user_data); |
| 39 | static void OnPluginPath_Changed(GtkWidget *wdg, gpointer data); |
| 40 | static void OnConfConf_Pad1About(GtkWidget *widget, gpointer user_data); |
| 41 | static void OnConfConf_Pad2About(GtkWidget *widget, gpointer user_data); |
| 42 | static void OnConfConf_Pad1Conf(GtkWidget *widget, gpointer user_data); |
| 43 | static void OnConfConf_Pad2Conf(GtkWidget *widget, gpointer user_data); |
| 44 | static void OnNet_Conf(GtkWidget *widget, gpointer user_data); |
| 45 | static void OnNet_About(GtkWidget *widget, gpointer user_data); |
| 46 | static void on_configure_plugin(GtkWidget *widget, gpointer user_data); |
| 47 | static void on_about_plugin(GtkWidget *widget, gpointer user_data); |
| 48 | static void UpdatePluginsBIOS_UpdateGUI(GladeXML *xml); |
| 49 | static void FindNetPlugin(GladeXML *xml); |
| 50 | |
| 51 | PSEgetLibType PSE_getLibType = NULL; |
| 52 | PSEgetLibVersion PSE_getLibVersion = NULL; |
| 53 | PSEgetLibName PSE_getLibName = NULL; |
| 54 | |
| 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 | PluginConf 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 | |
| 85 | void 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 | |
| 181 | void 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 | |
| 188 | void 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 | |
| 221 | void 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 | |
| 242 | void 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 | |
| 263 | void 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 | |
| 284 | void 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 | |
| 320 | static 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 | |
| 360 | static 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 | |
| 381 | static 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 | |
| 402 | static void OnConfConf_Pad1About(GtkWidget *widget, gpointer user_data) { |
| 403 | ConfPlugin(PADabout, Pad1ConfS, Config.Pad1, "PADabout", ConfDlg); |
| 404 | } |
| 405 | |
| 406 | static void OnConfConf_Pad2About(GtkWidget *widget, gpointer user_data) { |
| 407 | ConfPlugin(PADabout, Pad2ConfS, Config.Pad2, "PADabout", ConfDlg); |
| 408 | } |
| 409 | |
| 410 | static void OnConfConf_Pad1Conf(GtkWidget *widget, gpointer user_data) { |
| 411 | ConfPlugin(PADabout, Pad1ConfS, Config.Pad1, "PADconfigure", ConfDlg); |
| 412 | } |
| 413 | |
| 414 | static void OnConfConf_Pad2Conf(GtkWidget *widget, gpointer user_data) { |
| 415 | ConfPlugin(PADabout, Pad2ConfS, Config.Pad2, "PADconfigure", ConfDlg); |
| 416 | } |
| 417 | |
| 418 | static void OnNet_Conf(GtkWidget *widget, gpointer user_data) { |
| 419 | ConfPlugin(NETconfigure, NetConfS, Config.Net, "NETconfigure", NetDlg); |
| 420 | } |
| 421 | |
| 422 | static void OnNet_About(GtkWidget *widget, gpointer user_data) { |
| 423 | ConfPlugin(NETabout, NetConfS, Config.Net, "NETabout", NetDlg); |
| 424 | } |
| 425 | |
| 426 | static 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 | |
| 437 | static 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 | |
| 449 | void 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 | |
| 470 | void 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 | |
| 518 | int 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 | |
| 535 | int 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 | |
| 552 | int 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 |
| 567 | void 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 | |
| 574 | void 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 | |
| 594 | void 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 | |
| 678 | static 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 | |
| 688 | static 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 | |
| 748 | GtkWidget *CpuDlg; |
| 749 | GtkWidget *PsxCombo; |
| 750 | GList *psxglist; |
| 751 | char *psxtypes[] = { |
| 752 | "NTSC", |
| 753 | "PAL" |
| 754 | }; |
| 755 | |
| 756 | // When the auto-detect CPU type is selected, disable the NTSC/PAL selection |
| 757 | static 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 |
| 767 | static 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 | |
| 780 | void 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 | |
| 841 | void 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 | } |