1 /*  Copyright 2006-2011 Guillaume Duhamel
2     Copyright 2006 Fabien Coulon
3 
4     This file is part of Yabause.
5 
6     Yabause is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     Yabause is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with Yabause; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
19 */
20 
21 #include "settings.h"
22 
23 #include "yuicheckbutton.h"
24 #include "yuifileentry.h"
25 #include "yuirange.h"
26 #include "yuipage.h"
27 #include "yuiinputentry.h"
28 #include "yuiresolution.h"
29 
30 #include "../scsp.h"
31 
32 typedef struct {
33 	int id;
34 	const char *Name;
35 } GenericInterface_struct;
36 
cores_to_range(void * pointer,YuiRangeItem ** items)37 void cores_to_range(void * pointer, YuiRangeItem ** items) {
38 	GenericInterface_struct ** cores;
39 	GenericInterface_struct * core;
40 	int i;
41 
42 	if (*items != NULL) return;
43 
44 	cores = pointer;
45 
46 	i = 0;
47 	core = cores[i];
48 	while(core) {
49 		i++;
50 		core = cores[i];
51 	}
52 	*items = malloc(sizeof(YuiRangeItem) * (i + 1));
53 	i = 0;
54 	core = cores[i];
55 	while(core) {
56 		char buffer[1024];
57 		(*items)[i].name = strdup(core->Name);
58 		sprintf(buffer, "%d", core->id);
59 		(*items)[i].value = strdup(buffer);
60 		i++;
61 		core = cores[i];
62 	}
63 	(*items)[i].name = NULL;
64 	(*items)[i].value = NULL;
65 }
66 
67 extern CDInterface *SH2CoreList[];
68 extern CDInterface *M68KCoreList[];
69 extern CDInterface *CDCoreList[];
70 extern CDInterface *VIDCoreList[];
71 extern CDInterface *OSDCoreList[];
72 extern CDInterface *SNDCoreList[];
73 extern CDInterface *PERCoreList[];
74 
75 YuiRangeItem * sh2interpreters = NULL;
76 YuiRangeItem * m68kinterpreters = NULL;
77 YuiRangeItem * cdcores = NULL;
78 YuiRangeItem * vidcores = NULL;
79 YuiRangeItem * osdcores = NULL;
80 YuiRangeItem * sndcores = NULL;
81 YuiRangeItem * percores = NULL;
82 
83 YuiRangeItem regions[] = {
84 	{ "Auto" , "Auto-detect" },
85 	{ "J" , "Japan (NTSC)" },
86 	{ "T", "Asia (NTSC)" },
87 	{ "U", "North America (NTSC)" },
88 	{ "B", "Central/South America (NTSC)" },
89 	{ "K", "Korea (NTSC)" },
90 	{ "A", "Asia (PAL)" },
91 	{ "E", "Europe + others (PAL)" },
92 	{ "L", "Central/South America (PAL)" },
93 	{ 0, 0 }
94 };
95 
96 YuiRangeItem carttypes[] = {
97 	{ "0", "None" },
98 	{ "1", "Pro Action Replay" },
99 	{ "2", "4 Mbit Backup Ram" },
100 	{ "3", "8 Mbit Backup Ram" },
101 	{ "4", "16 Mbit Backup Ram" },
102 	{ "5", "32 Mbit Backup Ram" },
103 	{ "6", "8 Mbit Dram" },
104 	{ "7", "32 Mbit Dram" },
105 	{ "8", "Netlink" },
106 	{ "9", "16 Mbit ROM" },
107 	{ 0, 0 }
108 };
109 
110 const gchar * keys1[] = { "Up", "Right", "Down", "Left", "R", "L", 0 };
111 const gchar * keys2[] = { "A", "B", "C", "X", "Y", "Z", "Start", 0 };
112 
113 YuiRangeItem vidformats[] = {
114 	{ "0", "NTSC" },
115 	{ "1", "PAL" },
116 	{ 0, 0 }
117 };
118 
119 YuiRangeItem mousepercores[] = {
120 	{ "2", "Gtk Input Interface" },
121 	{ 0, 0 }
122 };
123 
hide_show_cart_path(YuiRange * instance,gpointer data)124 static void hide_show_cart_path(YuiRange * instance, gpointer data) {
125 	gint i = yui_range_get_active(instance);
126 
127 	if (i == 8) {
128 		gtk_widget_hide(data);
129 	} else {
130 		gtk_widget_show(data);
131 	}
132 }
133 
hide_show_netlink(YuiRange * instance,gpointer data)134 static void hide_show_netlink(YuiRange * instance, gpointer data) {
135 	gint i = yui_range_get_active(instance);
136 
137 	if (i != 8) {
138 		gtk_widget_hide(data);
139 	} else {
140 		gtk_widget_show(data);
141 	}
142 }
143 
percore_changed(GtkWidget * widget,gpointer data)144 static void percore_changed(GtkWidget * widget, gpointer data) {
145 	const char * core_s = percores[gtk_combo_box_get_active(GTK_COMBO_BOX(widget))].value;
146 	GList * entrylist = data;
147 	int core;
148 	sscanf(core_s, "%d", &core);
149 
150 	PerDeInit();
151 	PerInit(core);
152 
153 	while(entrylist) {
154 		yui_input_entry_update(entrylist->data);
155 		entrylist = g_list_next(entrylist);
156 	}
157 }
158 
pertype_display_pad(GtkWidget * box)159 static void pertype_display_pad(GtkWidget * box)
160 {
161    GtkWidget * table4, * table5;
162    GtkWidget * box_percore = gtk_vbox_new(FALSE, 10);
163    GtkWidget * select_percore = yui_range_new(keyfile, "General", "PerCore", percores);
164    GList * entrylist = NULL;
165 
166    gtk_container_set_border_width(GTK_CONTAINER(select_percore), 0);
167 
168    gtk_container_set_border_width(GTK_CONTAINER(box_percore), 10);
169 
170    gtk_box_pack_start(GTK_BOX (box_percore), select_percore, FALSE, FALSE, 0);
171 
172    table4 = yui_input_entry_new(keyfile, "Pad", keys1);
173    entrylist = g_list_append(entrylist, table4);
174 
175    gtk_box_pack_start (GTK_BOX (box_percore), table4, TRUE, TRUE, 0);
176 
177    gtk_box_pack_start (GTK_BOX (box), box_percore, TRUE, TRUE, 0);
178 
179    gtk_box_pack_start (GTK_BOX (box), gtk_vseparator_new(), TRUE, TRUE, 0);
180 
181    table5 = yui_input_entry_new(keyfile, "Pad", keys2);
182    entrylist = g_list_append(entrylist, table5);
183 
184    gtk_container_set_border_width(GTK_CONTAINER(table5), 10);
185 
186    gtk_box_pack_start (GTK_BOX (box), table5, TRUE, TRUE, 0);
187 
188    g_signal_connect(GTK_COMBO_BOX(YUI_RANGE(select_percore)->combo), "changed", G_CALLBACK(percore_changed), entrylist);
189 
190    gtk_widget_show_all(box);
191 }
192 
mouse_speed_change(GtkWidget * range,gpointer data)193 static void mouse_speed_change(GtkWidget * range, gpointer data)
194 {
195    g_key_file_set_double(keyfile, "General", "MouseSpeed", gtk_range_get_value(GTK_RANGE(range)));
196 }
197 
pertype_display_mouse(GtkWidget * box)198 static void pertype_display_mouse(GtkWidget * box)
199 {
200    GtkWidget * scale;
201    GtkWidget * table5;
202    GtkWidget * box_percore = gtk_vbox_new(FALSE, 10);
203    GtkWidget * select_percore = yui_range_new(keyfile, "General", "MousePerCore", mousepercores);
204    GList * entrylist = NULL;
205 
206    gtk_container_set_border_width(GTK_CONTAINER(select_percore), 0);
207    gtk_container_set_border_width(GTK_CONTAINER(box_percore), 10);
208    gtk_box_pack_start(GTK_BOX (box_percore), select_percore, FALSE, FALSE, 0);
209 
210    scale = gtk_hscale_new_with_range(0, 10, 0.1);
211    gtk_range_set_value(GTK_RANGE(scale), g_key_file_get_double(keyfile, "General", "MouseSpeed", NULL));
212    g_signal_connect(scale, "value-changed", G_CALLBACK(mouse_speed_change), NULL);
213    gtk_box_pack_start(GTK_BOX (box_percore), scale, FALSE, FALSE, 0);
214 
215    gtk_box_pack_start (GTK_BOX (box), box_percore, TRUE, TRUE, 0);
216 
217    gtk_box_pack_start (GTK_BOX (box), gtk_vseparator_new(), TRUE, TRUE, 0);
218 
219    table5 = yui_input_entry_new(keyfile, "Mouse", PerMouseNames);
220    entrylist = g_list_append(entrylist, table5);
221    gtk_container_set_border_width(GTK_CONTAINER(table5), 10);
222    gtk_box_pack_start (GTK_BOX (box), table5, TRUE, TRUE, 0);
223 
224    g_signal_connect(GTK_COMBO_BOX(YUI_RANGE(select_percore)->combo), "changed", G_CALLBACK(percore_changed), entrylist);
225    gtk_widget_show_all(box);
226 }
227 
pertype_changed(GtkWidget * widget,gpointer data)228 static void pertype_changed(GtkWidget * widget, gpointer data) {
229 	GtkTreePath * path;
230 	gchar * strpath;
231 	int i;
232 	GtkWidget * box = data;
233 	GList * children;
234 	GtkWidget * child;
235 
236 	children = gtk_container_get_children(GTK_CONTAINER(box));
237 	for(i = 1;i < 4;i++) {
238 		child = g_list_nth_data(children, i);
239 		if (child != NULL) gtk_widget_destroy(child);
240 	}
241 
242 	gtk_tree_view_get_cursor(GTK_TREE_VIEW(widget), &path, NULL);
243 
244 	if (path) {
245 		int i;
246 
247 		strpath = gtk_tree_path_to_string(path);
248 		sscanf(strpath, "%d", &i);
249 
250 		switch(i) {
251 			case 0:
252 				g_key_file_set_integer(keyfile, "General", "PerType", PERPAD);
253 				pertype_display_pad(box);
254 				break;
255 			case 1:
256 				g_key_file_set_integer(keyfile, "General", "PerType", PERMOUSE);
257 				pertype_display_mouse(box);
258 				break;
259 		}
260 
261 		g_free(strpath);
262 		gtk_tree_path_free(path);
263 	}
264 }
265 
bilinear_toggled(GtkWidget * widget,gpointer data)266 static void bilinear_toggled(GtkWidget * widget, gpointer data) {
267 	g_key_file_set_integer(keyfile, "General", "Bilinear", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
268 }
269 
frameskip_toggled(GtkWidget * widget,gpointer data)270 static void frameskip_toggled(GtkWidget * widget, gpointer data) {
271 	g_key_file_set_integer(keyfile, "General", "Frameskip", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
272 }
273 
disable_enable_fixed_base_time(YuiCheckButton * clocksync,YuiCheckButton * fixedbasetime)274 static void disable_enable_fixed_base_time(YuiCheckButton *clocksync, YuiCheckButton *fixedbasetime) {
275 	gtk_widget_set_sensitive(GTK_WIDGET(fixedbasetime),
276 	                         yui_check_button_get_active(clocksync));
277 }
278 
volume_changed(GtkRange * range,gpointer data)279 static void volume_changed(GtkRange * range, gpointer data) {
280     g_key_file_set_integer(keyfile, "General", "Volume", (int) gtk_range_get_value(range));
281 }
282 
create_dialog1(void)283 GtkWidget* create_dialog1(void) {
284   GtkWidget *dialog1;
285   GtkWidget *notebook1;
286   GtkWidget *vbox17;
287   GtkWidget *hbox22;
288   GtkWidget *button11;
289   GtkWidget *button12;
290   GtkWidget * general, * video_sound, * cart_memory, *advanced, * sound;
291   GtkWidget * box;
292   u8 perid;
293 
294   cores_to_range(SH2CoreList, &sh2interpreters);
295   cores_to_range(M68KCoreList, &m68kinterpreters);
296   cores_to_range(CDCoreList, &cdcores);
297   cores_to_range(VIDCoreList, &vidcores);
298   cores_to_range(OSDCoreList, &osdcores);
299   cores_to_range(SNDCoreList, &sndcores);
300   cores_to_range(PERCoreList, &percores);
301 
302   dialog1 = gtk_dialog_new ();
303   gtk_window_set_title (GTK_WINDOW (dialog1), "Yabause configuration");
304   gtk_window_set_icon_name (GTK_WINDOW (dialog1), "gtk-preferences");
305   gtk_window_set_type_hint (GTK_WINDOW (dialog1), GDK_WINDOW_TYPE_HINT_DIALOG);
306   gtk_window_set_resizable(GTK_WINDOW(dialog1), FALSE);
307 
308   notebook1 = gtk_notebook_new ();
309   gtk_widget_show(notebook1);
310 
311   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog1)->vbox), notebook1, TRUE, TRUE, 0);
312 
313   /*
314    * General configuration
315    */
316   general = yui_page_new(keyfile);
317 
318   box = yui_page_add(YUI_PAGE(general), _("Bios"));
319   gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "BiosPath", YUI_FILE_ENTRY_BROWSE, NULL));
320 
321   box = yui_page_add(YUI_PAGE(general), _("Cdrom"));
322   gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "CDROMCore", cdcores));
323   gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "CDROMDrive", YUI_FILE_ENTRY_BROWSE, NULL));
324 
325   box = yui_page_add(YUI_PAGE(general), _("Save States"));
326   gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "StatePath", YUI_FILE_ENTRY_BROWSE | YUI_FILE_ENTRY_DIRECTORY, NULL));
327 
328   gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), general, gtk_label_new (_("General")));
329   gtk_widget_show_all(general);
330 
331   /*
332    * Video configuration
333    */
334   video_sound = yui_page_new(keyfile);
335 
336   box = yui_page_add(YUI_PAGE(video_sound), _("Video Core"));
337   gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "VideoCore", vidcores));
338 
339   box = yui_page_add(YUI_PAGE(video_sound), _("Bilinear Filtering"));
340   {
341     GtkWidget * bilinear = gtk_check_button_new_with_label("Enable Bilinear Filtering");
342     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bilinear), g_key_file_get_integer(keyfile, "General", "Bilinear", NULL));
343     gtk_container_set_border_width(GTK_CONTAINER(bilinear), 10);
344     g_signal_connect(bilinear, "toggled", G_CALLBACK(bilinear_toggled), NULL);
345     gtk_container_add(GTK_CONTAINER(box), bilinear);
346   }
347 
348 #ifdef YAB_PORT_OSD
349   box = yui_page_add(YUI_PAGE(video_sound), _("OSD Core"));
350   gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "OSDCore", osdcores));
351 #endif
352 
353   box = yui_page_add(YUI_PAGE(video_sound), _("Resolution"));
354   gtk_container_add(GTK_CONTAINER(box), yui_resolution_new(keyfile, "General"));
355 
356   box = yui_page_add(YUI_PAGE(video_sound), _("Video Format"));
357   gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "VideoFormat", vidformats));
358 
359   box = yui_page_add(YUI_PAGE(video_sound), _("Frame Skip/Limiter"));
360   {
361     GtkWidget * frameskip = gtk_check_button_new_with_label("Enable frame skipping/limiting");
362     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frameskip), g_key_file_get_integer(keyfile, "General", "Frameskip", NULL));
363     gtk_container_set_border_width(GTK_CONTAINER(frameskip), 10);
364     g_signal_connect(frameskip, "toggled", G_CALLBACK(frameskip_toggled), NULL);
365     gtk_container_add(GTK_CONTAINER(box), frameskip);
366   }
367 
368   gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), video_sound, gtk_label_new (_("Video")));
369   gtk_widget_show_all(video_sound);
370 
371   /*
372    * Sound configuration
373    */
374   sound = yui_page_new(keyfile);
375 
376   box = yui_page_add(YUI_PAGE(sound), _("Sound Core"));
377   gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "SoundCore", sndcores));
378 
379   {
380     GtkWidget * volume;
381 
382     box = yui_page_add(YUI_PAGE(sound), _("Volume"));
383     gtk_container_set_border_width(GTK_CONTAINER(box), 10);
384     volume = gtk_hscale_new_with_range(0, 100, 1);
385     gtk_range_set_value(GTK_RANGE(volume), g_key_file_get_integer(keyfile, "General", "Volume", NULL));
386     g_signal_connect(volume, "value-changed", G_CALLBACK(volume_changed), NULL);
387     gtk_container_add(GTK_CONTAINER(box), volume);
388   }
389 
390   gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), sound, gtk_label_new (_("Sound")));
391   gtk_widget_show_all(sound);
392 
393   /*
394    * Cart/Memory configuration
395    */
396   cart_memory = yui_page_new(keyfile);
397 
398   box = yui_page_add(YUI_PAGE(cart_memory), _("Cartridge"));
399   {
400      GtkWidget * w1, * w2, * w3;
401 
402      w1 = yui_range_new(keyfile, "General", "CartType", carttypes);
403      gtk_container_add(GTK_CONTAINER(box), w1);
404 
405      w2 = yui_file_entry_new(keyfile, "General", "CartPath", YUI_FILE_ENTRY_BROWSE, NULL);
406      gtk_container_add(GTK_CONTAINER(box), w2);
407 
408      w3 = gtk_hbox_new(FALSE, 0);
409      gtk_box_pack_start(GTK_BOX(w3), yui_file_entry_new(keyfile, "General", "NetlinkHost", 0, "Host"), TRUE, TRUE, 0);
410      gtk_box_pack_start(GTK_BOX(w3), yui_file_entry_new(keyfile, "General", "NetlinkPort", 0, "Port"), TRUE, TRUE, 0);
411      gtk_container_add(GTK_CONTAINER(box), w3);
412 
413      g_signal_connect(w1, "changed", G_CALLBACK(hide_show_cart_path), w2);
414      g_signal_connect(w1, "changed", G_CALLBACK(hide_show_netlink), w3);
415 
416      box = yui_page_add(YUI_PAGE(cart_memory), _("Memory"));
417      gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "BackupRamPath", YUI_FILE_ENTRY_BROWSE, NULL));
418 
419      box = yui_page_add(YUI_PAGE(cart_memory), _("Mpeg ROM"));
420      gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "MpegRomPath", YUI_FILE_ENTRY_BROWSE, NULL));
421 
422      gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), cart_memory, gtk_label_new (_("Cart/Memory")));
423      gtk_widget_show_all(cart_memory);
424 
425      if (yui_range_get_active(YUI_RANGE(w1)) == 8) gtk_widget_hide(w2);
426      else gtk_widget_hide(w3);
427   }
428 
429   /*
430    * Input Configuration
431    */
432   vbox17 = gtk_vbox_new (FALSE, 0);
433 
434   hbox22 = gtk_hbox_new (FALSE, 0);
435 
436   {
437     GtkWidget * controllerscroll;
438     GtkTreeStore * controllerlist;
439     GtkWidget * controllerlistview;
440     GtkCellRenderer * controllerrenderer;
441     GtkTreeViewColumn * controllercolumn;
442     GtkTreeIter iter;
443     GtkTreePath * path;
444 
445     controllerscroll = gtk_scrolled_window_new(NULL, NULL);
446     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(controllerscroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
447 
448     controllerlist = gtk_tree_store_new(1, G_TYPE_STRING);
449     controllerlistview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(controllerlist));
450     gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(controllerlistview), FALSE);
451 
452     controllerrenderer = gtk_cell_renderer_text_new();
453     controllercolumn = gtk_tree_view_column_new_with_attributes("Controller", controllerrenderer, "text", 0, NULL);
454     gtk_tree_view_append_column(GTK_TREE_VIEW (controllerlistview), controllercolumn);
455 
456     gtk_tree_store_append(controllerlist, &iter, NULL);
457     gtk_tree_store_set(controllerlist, &iter, 0, "Pad", -1);
458 
459     gtk_tree_store_append(controllerlist, &iter, NULL);
460     gtk_tree_store_set(controllerlist, &iter, 0, "Mouse", -1);
461 
462     gtk_container_add(GTK_CONTAINER(controllerscroll), controllerlistview);
463     gtk_box_pack_start (GTK_BOX (hbox22), controllerscroll, TRUE, TRUE, 0);
464 
465     gtk_tree_view_expand_all(GTK_TREE_VIEW(controllerlistview));
466 
467     g_signal_connect(controllerlistview, "cursor-changed", G_CALLBACK(pertype_changed), hbox22);
468     perid = g_key_file_get_integer(keyfile, "General", "PerType", NULL);
469     switch(perid)
470     {
471        case PERMOUSE:
472           path = gtk_tree_path_new_from_string("1");
473           break;
474        case PERPAD:
475        default:
476           path = gtk_tree_path_new_from_string("0");
477           break;
478     }
479 
480     gtk_tree_view_set_cursor(GTK_TREE_VIEW(controllerlistview), path, NULL, FALSE);
481     gtk_tree_path_free(path);
482   }
483 
484   gtk_box_pack_start (GTK_BOX (vbox17), hbox22, TRUE, TRUE, 0);
485 
486   //pertype_display_pad(hbox22);
487 
488   gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), vbox17, gtk_label_new (_("Input")));
489   gtk_widget_show_all(vbox17);
490 
491   /*
492    * Advanced configuration
493    */
494 
495   advanced = yui_page_new(keyfile);
496 
497   box = yui_page_add(YUI_PAGE(advanced), _("Region"));
498   gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "Region", regions));
499 
500   box = yui_page_add(YUI_PAGE(advanced), _("SH2 Interpreter"));
501   gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "SH2Int", sh2interpreters));
502 
503   box = yui_page_add(YUI_PAGE(advanced), _("M68k Interpreter"));
504   gtk_container_add(GTK_CONTAINER(box), yui_range_new(keyfile, "General", "M68kInt", m68kinterpreters));
505 
506   box = yui_page_add(YUI_PAGE(advanced), _("Clock Sync"));
507   {
508     GtkWidget *button1, *button2;
509 
510     button1 = yui_check_button_new(
511         _("Synchronize internal clock with emulation"),
512         keyfile, "General", "ClockSync"
513     );
514     gtk_container_add(GTK_CONTAINER(box), button1);
515 
516     button2 = yui_check_button_new(
517         _("Always start from 1998-01-01 12:00"),
518         keyfile, "General", "FixedBaseTime"
519     );
520     gtk_container_add(GTK_CONTAINER(box), button2);
521     if (!yui_check_button_get_active(YUI_CHECK_BUTTON(button1)))
522       gtk_widget_set_sensitive(button2, FALSE);
523 
524     g_signal_connect(button1, "changed",
525                      G_CALLBACK(disable_enable_fixed_base_time), button2);
526   }
527 
528   box = yui_page_add(YUI_PAGE(advanced), _("Threads"));
529   {
530     GtkWidget *button = yui_check_button_new(
531         _("Use multithreaded emulation (EXPERIMENTAL!)"),
532         keyfile, "General", "UseThreads"
533     );
534     gtk_container_add(GTK_CONTAINER(box), button);
535   }
536 
537 #ifdef HAVE_LIBMINI18N
538   box = yui_page_add(YUI_PAGE(advanced), _("Translation"));
539   gtk_container_add(GTK_CONTAINER(box), yui_file_entry_new(keyfile, "General", "TranslationPath", YUI_FILE_ENTRY_BROWSE, NULL));
540 #endif
541 
542   gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), advanced, gtk_label_new (_("Advanced")));
543   gtk_widget_show_all(advanced);
544 
545   /*
546    * Dialog buttons
547    */
548   button11 = gtk_button_new_from_stock ("gtk-cancel");
549 
550   gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), button11, GTK_RESPONSE_CANCEL);
551   GTK_WIDGET_SET_FLAGS (button11, GTK_CAN_DEFAULT);
552   gtk_widget_show(button11);
553 
554   button12 = gtk_button_new_from_stock ("gtk-ok");
555 
556   gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), button12, GTK_RESPONSE_OK);
557   GTK_WIDGET_SET_FLAGS (button12, GTK_CAN_DEFAULT);
558   gtk_widget_show(button12);
559 
560   gtk_widget_show(dialog1);
561 
562   return dialog1;
563 }
564 
yui_texture_free(guchar * pixels,gpointer data)565 void yui_texture_free(guchar *pixels, gpointer data) {
566   free(pixels);
567 }
568