2
#include <gdk/gdkkeysyms.h>
6
#include <gdk/gdkkeysyms-compat.h>
15
#include "../../types.h"
16
#include "../../fceu.h"
17
#include "../../driver.h"
18
#include "../../version.h"
19
#include "../../movie.h"
20
#include "../../palette.h"
21
#include "../../fds.h"
22
#include "../common/configSys.h"
32
#include "../../fceulua.h"
35
// Fix compliation errors for older version of GTK (Ubuntu 10.04 LTS)
36
#if GTK_MINOR_VERSION < 24 && GTK_MAJOR_VERSION == 2
37
#define GTK_COMBO_BOX_TEXT GTK_COMBO_BOX
38
#define gtk_combo_box_text_new gtk_combo_box_new
39
#define gtk_combo_box_text_get_active_text gtk_combo_box_get_active_text
40
#define gtk_combo_box_text_append_text gtk_combo_box_append_text
43
void toggleSound(GtkWidget* check, gpointer data);
46
extern Config *g_config;
48
GtkWidget* MainWindow = NULL;
49
GtkWidget* evbox = NULL;
50
GtkWidget* padNoCombo = NULL;
51
GtkWidget* configNoCombo = NULL;
52
GtkWidget* buttonMappings[10];
53
GtkRadioAction* stateSlot = NULL;
54
bool gtkIsStarted = false;
56
// check to see if a particular GTK version is available
57
// 2.24 is required for most of the dialogs -- ie: checkGTKVersion(2,24);
58
bool checkGTKVersion(int major_required, int minor_required)
60
int major = GTK_MAJOR_VERSION;
61
int minor = GTK_MINOR_VERSION;
63
if(major > major_required)
66
} else if (major == major_required)
68
if(minor >= minor_required)
82
// This function configures a single hotkey
83
int configHotkey(char* hotkeyString)
88
screen = SDL_SetVideoMode(420, 200, 8, 0);
89
//SDL_WM_SetCaption("Press a key to bind...", 0);
94
SDL_WaitEvent(&event);
99
newkey = event.key.keysym.sym;
100
g_config->setOption(hotkeyString, newkey);
101
extern FCEUGI *GameInfo;
109
// This function configures a single button on a gamepad
110
int configGamepadButton(GtkButton* button, gpointer p)
112
gint x = ((gint)(glong)(p));
113
//gint x = GPOINTER_TO_INT(p);
114
int padNo = atoi(gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(padNoCombo))) - 1;
115
int configNo = atoi(gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(configNoCombo))) - 1;
120
// only configure when the "Change" button is pressed in, not when it is unpressed
121
if(!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
126
snprintf(buf, sizeof(buf), "SDL.Input.GamePad.%d", padNo);
128
DWaitButton(NULL, &GamePadConfig[padNo][x], configNo);
130
g_config->setOption(prefix + GamePadNames[x], GamePadConfig[padNo][x].ButtonNum[configNo]);
132
if(GamePadConfig[padNo][x].ButtType[0] == BUTTC_KEYBOARD)
134
g_config->setOption(prefix + "DeviceType", "Keyboard");
135
} else if(GamePadConfig[padNo][x].ButtType[0] == BUTTC_JOYSTICK) {
136
g_config->setOption(prefix + "DeviceType", "Joystick");
138
g_config->setOption(prefix + "DeviceType", "Unknown");
140
g_config->setOption(prefix + "DeviceNum", GamePadConfig[padNo][x].DeviceNum[configNo]);
142
snprintf(buf, sizeof(buf), "<tt>%s</tt>", ButtonName(&GamePadConfig[padNo][x], configNo));
143
gtk_label_set_markup(GTK_LABEL(buttonMappings[x]), buf);
147
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
158
void closeVideoWin(GtkWidget* w, GdkEvent* e, gpointer p)
161
gtk_widget_destroy(w);
164
void closeDialog(GtkWidget* w, GdkEvent* e, gpointer p)
166
gtk_widget_destroy(w);
168
void toggleLowPass(GtkWidget* w, gpointer p)
170
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
172
g_config->setOption("SDL.Sound.LowPass", 1);
177
g_config->setOption("SDL.Sound.LowPass", 0);
183
// Wrapper for pushing GTK options into the config file
184
// p : pointer to the string that names the config option
186
void toggleOption(GtkWidget* w, gpointer p)
188
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
189
g_config->setOption((char*)p, 1);
191
g_config->setOption((char*)p, 0);
194
UpdateEMUCore(g_config);
197
int setTint(GtkWidget* w, gpointer p)
199
int v = gtk_range_get_value(GTK_RANGE(w));
200
g_config->setOption("SDL.Tint", v);
203
g_config->getOption("SDL.NTSCpalette", &c);
204
g_config->getOption("SDL.Hue", &h);
205
FCEUI_SetNTSCTH(c, v, h);
209
int setHue(GtkWidget* w, gpointer p)
211
int v = gtk_range_get_value(GTK_RANGE(w));
212
g_config->setOption("SDL.Hue", v);
215
g_config->getOption("SDL.Tint", &t);
216
g_config->getOption("SDL.SDL.NTSCpalette", &c);
217
FCEUI_SetNTSCTH(c, t, v);
221
void loadPalette (GtkWidget* w, gpointer p)
223
GtkWidget* fileChooser;
225
fileChooser = gtk_file_chooser_dialog_new ("Open NES Palette", GTK_WINDOW(MainWindow),
226
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
227
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
228
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fileChooser), getcwd(NULL, 0));
230
if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
234
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
235
g_config->setOption("SDL.Palette", filename);
236
g_config->setOption("SDL.SDL.NTSCpalette", 0);
237
LoadCPalette(filename);
239
gtk_entry_set_text(GTK_ENTRY(p), filename);
242
gtk_widget_destroy (fileChooser);
245
void clearPalette(GtkWidget* w, gpointer p)
247
g_config->setOption("SDL.Palette", 0);
248
gtk_entry_set_text(GTK_ENTRY(p), "");
251
void openPaletteConfig()
255
GtkWidget* paletteFrame;
256
GtkWidget* paletteHbox;
257
GtkWidget* paletteButton;
258
GtkWidget* paletteEntry;
259
GtkWidget* clearButton;
260
GtkWidget* ntscColorChk;
261
GtkWidget* slidersFrame;
262
GtkWidget* slidersVbox;
263
GtkWidget* tintFrame;
264
GtkWidget* tintHscale;
266
GtkWidget* hueHscale;
268
win = gtk_dialog_new_with_buttons("Palette Options",
269
GTK_WINDOW(MainWindow),
270
(GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT),
274
gtk_window_set_icon_name(GTK_WINDOW(win), GTK_STOCK_SELECT_COLOR);
275
vbox = gtk_dialog_get_content_area(GTK_DIALOG(win));
277
paletteFrame = gtk_frame_new("Custom palette: ");
278
paletteHbox = gtk_hbox_new(FALSE, 5);
279
gtk_container_set_border_width(GTK_CONTAINER(paletteHbox), 5);
280
gtk_container_add(GTK_CONTAINER(paletteFrame), paletteHbox);
281
paletteButton = gtk_button_new_from_stock(GTK_STOCK_OPEN);
282
gtk_button_set_label(GTK_BUTTON(paletteButton), "Open palette");
283
paletteEntry = gtk_entry_new();
284
gtk_editable_set_editable(GTK_EDITABLE(paletteEntry), FALSE);
286
clearButton = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
288
gtk_box_pack_start(GTK_BOX(paletteHbox), paletteButton, FALSE, FALSE, 2);
289
gtk_box_pack_start(GTK_BOX(paletteHbox), paletteEntry, TRUE, TRUE, 5);
290
gtk_box_pack_start(GTK_BOX(paletteHbox), clearButton, FALSE, FALSE, 0);
292
g_signal_connect(paletteButton, "clicked", G_CALLBACK(loadPalette), paletteEntry);
293
g_signal_connect(clearButton, "clicked", G_CALLBACK(clearPalette), paletteEntry);
297
g_config->getOption("SDL.Palette", &fn);
298
gtk_entry_set_text(GTK_ENTRY(paletteEntry), fn.c_str());
301
ntscColorChk = gtk_check_button_new_with_label("Use NTSC palette");
303
g_signal_connect(ntscColorChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.NTSCpalette");
307
g_config->getOption("SDL.NTSCpalette", &b);
309
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ntscColorChk), 1);
311
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ntscColorChk), 0);
313
// color / tint / hue sliders
314
slidersFrame = gtk_frame_new("NTSC palette controls");
315
slidersVbox = gtk_vbox_new(FALSE, 2);
316
tintFrame = gtk_frame_new("Tint");
317
tintHscale = gtk_hscale_new_with_range(0, 128, 1);
318
gtk_container_add(GTK_CONTAINER(tintFrame), tintHscale);
319
hueFrame = gtk_frame_new("Hue");
320
hueHscale = gtk_hscale_new_with_range(0, 128, 1);
321
gtk_container_add(GTK_CONTAINER(hueFrame), hueHscale);
323
g_signal_connect(tintHscale, "button-release-event", G_CALLBACK(setTint), NULL);
324
g_signal_connect(hueHscale, "button-release-event", G_CALLBACK(setHue), NULL);
328
g_config->getOption("SDL.Hue", &h);
329
g_config->getOption("SDL.Tint", &t);
331
gtk_range_set_value(GTK_RANGE(hueHscale), h);
332
gtk_range_set_value(GTK_RANGE(tintHscale), t);
334
gtk_container_add(GTK_CONTAINER(slidersFrame), slidersVbox);
335
gtk_box_pack_start(GTK_BOX(slidersVbox), ntscColorChk, FALSE, FALSE, 5);
336
gtk_box_pack_start(GTK_BOX(slidersVbox), tintFrame, FALSE, TRUE, 5);
337
gtk_box_pack_start(GTK_BOX(slidersVbox), hueFrame, FALSE, TRUE, 5);
339
gtk_box_pack_start(GTK_BOX(vbox), paletteFrame, FALSE, TRUE, 5);
340
gtk_box_pack_start(GTK_BOX(vbox), slidersFrame, FALSE, TRUE, 5);
342
g_signal_connect(win, "delete-event", G_CALLBACK(closeDialog), NULL);
343
g_signal_connect(win, "response", G_CALLBACK(closeDialog), NULL);
345
gtk_widget_show_all(win);
355
void launchNet(GtkWidget* w, gpointer p)
357
char* ip = (char*)gtk_entry_get_text(GTK_ENTRY(ipEntry));
358
char* pw = (char*)gtk_entry_get_text(GTK_ENTRY(pwEntry));
359
int port = (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(portSpin));
361
g_config->setOption("SDL.NetworkIP", ip);
362
g_config->setOption("SDL.NetworkPassword", pw);
363
g_config->setOption("SDL.NetworkPort", port);
365
gtk_widget_destroy(GTK_WIDGET(w));
370
void setUsername(GtkWidget* w, gpointer p)
372
char* s = (char*)gtk_entry_get_text(GTK_ENTRY(w));
373
g_config->setOption("SDL.NetworkUsername", s);
376
void netResponse(GtkWidget* w, gint response_id, gpointer p)
378
if(response_id == GTK_RESPONSE_OK)
381
gtk_widget_destroy(w);
384
void openNetworkConfig()
389
GtkWidget* userEntry;
399
//GtkWidget* localPlayersCbo;
403
win = gtk_dialog_new_with_buttons("Network Options",GTK_WINDOW(MainWindow), (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT),GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, GTK_STOCK_CONNECT, GTK_RESPONSE_OK, NULL);
404
gtk_window_set_icon_name(GTK_WINDOW(win), GTK_STOCK_NETWORK);
405
box = gtk_dialog_get_content_area(GTK_DIALOG(win));
407
userBox = gtk_hbox_new(FALSE, 3);
408
userLbl = gtk_label_new("Username:");
409
userEntry = gtk_entry_new();
411
g_config->getOption("SDL.NetworkUsername", &s);
412
gtk_entry_set_text(GTK_ENTRY(userEntry), s.c_str());
414
g_signal_connect(userEntry, "changed", G_CALLBACK(setUsername), NULL);
416
frame = gtk_frame_new("Network options");
417
vbox = gtk_vbox_new(FALSE, 5);
418
ipBox = gtk_hbox_new(FALSE, 5);
419
ipLbl = gtk_label_new("Server IP:");
420
ipEntry = gtk_entry_new();
421
portBox = gtk_hbox_new(FALSE, 5);
422
portLbl = gtk_label_new("Server port:");
423
portSpin = gtk_spin_button_new_with_range(0, 999999, 1);
424
//localPlayersCbo = gtk_combo_box_new_text();
425
pwBox = gtk_hbox_new(FALSE, 3);
426
pwLbl = gtk_label_new("Server password:");
427
pwEntry = gtk_entry_new();
429
gtk_spin_button_set_value(GTK_SPIN_BUTTON(portSpin), 4046);
431
gtk_box_pack_start(GTK_BOX(userBox), userLbl, FALSE, FALSE, 3);
432
gtk_box_pack_start(GTK_BOX(userBox), userEntry, TRUE , TRUE, 3);
434
gtk_box_pack_start(GTK_BOX(portBox), portLbl, FALSE, FALSE, 3);
435
gtk_box_pack_start(GTK_BOX(portBox), portSpin, FALSE , FALSE, 3);
437
gtk_box_pack_start(GTK_BOX(ipBox), ipLbl, FALSE, FALSE, 3);
438
gtk_box_pack_start(GTK_BOX(ipBox), ipEntry, TRUE , TRUE, 3);
440
gtk_box_pack_start(GTK_BOX(pwBox), pwLbl, FALSE, FALSE, 3);
441
gtk_box_pack_start(GTK_BOX(pwBox), pwEntry, TRUE , TRUE, 3);
443
gtk_box_pack_start(GTK_BOX(vbox), ipBox, FALSE, FALSE, 3);
444
gtk_box_pack_start(GTK_BOX(vbox), portBox, FALSE, FALSE, 3);
445
//gtk_box_pack_start_defaults(GTK_BOX(vbox), localPlayersCbo);
446
gtk_box_pack_start(GTK_BOX(vbox), pwBox, FALSE, FALSE, 3);
448
gtk_container_add(GTK_CONTAINER(frame), vbox);
450
gtk_box_pack_start(GTK_BOX(box), userBox, TRUE, TRUE, 0);
451
gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 0);
453
gtk_widget_show_all(win);
455
g_signal_connect(win, "delete-event", G_CALLBACK(closeDialog), NULL);
456
g_signal_connect(win, "response", G_CALLBACK(netResponse), NULL);
460
static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data);
462
void flushGtkEvents()
464
while (gtk_events_pending ())
465
gtk_main_iteration_do (FALSE);
470
GtkWidget* HotkeyWin;
472
// creates and opens hotkey config window
473
void openHotkeyConfig()
481
GtkWidget* win = gtk_dialog_new_with_buttons("Hotkey Configuration",
482
GTK_WINDOW(MainWindow), (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT),
486
gtk_window_set_default_size(GTK_WINDOW(win), 400, 800);
494
vbox = gtk_dialog_get_content_area(GTK_DIALOG(win));
496
GtkTreeStore *hotkey_store = gtk_tree_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
498
std::string prefix = "SDL.Hotkeys.";
499
GtkTreeIter iter; // parent
500
GtkTreeIter iter2; // child
502
gtk_tree_store_append(hotkey_store, &iter, NULL); // aquire iter
505
for(int i=0; i<HK_MAX; i++)
507
const char* optionName = (prefix + HotkeyStrings[i]).c_str();
508
g_config->getOption(optionName, &keycode);
509
gtk_tree_store_set(hotkey_store, &iter,
510
COMMAND_COLUMN, optionName,
511
KEY_COLUMN, SDL_GetKeyName((SDLKey)keycode),
513
gtk_tree_store_append(hotkey_store, &iter, NULL); // acquire child iterator
516
tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(hotkey_store));
517
GtkCellRenderer *renderer;
518
GtkTreeViewColumn* column;
521
renderer = gtk_cell_renderer_text_new();
522
column = gtk_tree_view_column_new_with_attributes("Command", renderer, "text", COMMAND_COLUMN, NULL);
523
gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
524
column = gtk_tree_view_column_new_with_attributes("Key", renderer, "text", KEY_COLUMN, NULL);
525
gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
526
scroll = gtk_scrolled_window_new(NULL, NULL);
527
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_NEVER,
528
GTK_POLICY_AUTOMATIC);
529
gtk_container_add(GTK_CONTAINER(scroll), tree);
530
gtk_box_pack_start(GTK_BOX(vbox), scroll, TRUE, TRUE, 5);
531
gtk_widget_show_all(win);
533
g_signal_connect(win, "delete-event", G_CALLBACK(closeDialog), NULL);
534
g_signal_connect(win, "response", G_CALLBACK(closeDialog), NULL);
536
GtkTreeSelection *select;
538
select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
539
gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
540
g_signal_connect ( G_OBJECT (select), "changed", G_CALLBACK (tree_selection_changed_cb),
542
gtk_tree_selection_unselect_all (select);
545
static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data)
551
if (gtk_tree_selection_get_selected (selection, &model, &iter))
553
gtk_tree_model_get (model, &iter, 0, &hotkey, -1);
555
gtk_widget_hide(HotkeyWin);
559
configHotkey(hotkey);
561
g_signal_emit_by_name(HotkeyWin, "destroy-event");
570
GtkWidget* typeCombo;
573
int setInputDevice(GtkWidget* w, gpointer p)
575
std::string s = "SDL.Input.";
577
printf("%s", s.c_str());
578
g_config->setOption(s, gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(typeCombo)));
584
void updateGamepadConfig(GtkWidget* w, gpointer p)
588
int padNo = atoi(gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(padNoCombo))) - 1;
589
int configNo = atoi(gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(configNoCombo))) - 1;
593
GtkWidget* mappedKey = buttonMappings[i];
594
if(GamePadConfig[padNo][i].ButtType[configNo] == BUTTC_KEYBOARD)
596
snprintf(strBuf, sizeof(strBuf), "<tt>%s</tt>",
597
SDL_GetKeyName((SDLKey)GamePadConfig[padNo][i].ButtonNum[configNo]));
599
else // FIXME: display joystick button/hat/axis names properly
600
strncpy(strBuf, "<tt>Joystick</tt>", sizeof(strBuf));
602
gtk_label_set_text(GTK_LABEL(mappedKey), strBuf);
603
gtk_label_set_use_markup(GTK_LABEL(mappedKey), TRUE);
607
// creates and opens the gamepad config window (requires GTK 2.24)
608
void openGamepadConfig()
610
// GTK 2.24 required for this dialog
611
if (checkGTKVersion(2, 24) == false)
613
// TODO: present this in a GTK MessageBox?
614
printf(" Warning: GTK >= 2.24 required for this dialog.\nTo configure the gamepads, use \"--inputcfg\" from the command line (ie: \"fceux --inputcfg gamepad1\").\n");
620
GtkWidget* hboxPadNo;
621
GtkWidget* padNoLabel;
622
GtkWidget* configNoLabel;
623
GtkWidget* fourScoreChk;
624
GtkWidget* oppositeDirChk;
625
GtkWidget* buttonFrame;
626
GtkWidget* buttonTable;
628
win = gtk_dialog_new_with_buttons("Controller Configuration",
629
GTK_WINDOW(MainWindow),
630
(GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT),
634
gtk_window_set_title(GTK_WINDOW(win), "Controller Configuration");
635
gtk_window_set_icon_name(GTK_WINDOW(win), "input-gaming");
636
gtk_widget_set_size_request(win, 350, 500);
638
vbox = gtk_dialog_get_content_area(GTK_DIALOG(win));
639
gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
641
hboxPadNo = gtk_hbox_new(FALSE, 0);
642
padNoLabel = gtk_label_new("Port:");
643
configNoLabel = gtk_label_new("Config Number:");
644
fourScoreChk = gtk_check_button_new_with_label("Enable Four Score");
645
oppositeDirChk = gtk_check_button_new_with_label("Allow Up+Down / Left+Right");
647
typeCombo = gtk_combo_box_text_new();
648
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(typeCombo), "gamepad");
649
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(typeCombo), "zapper");
650
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(typeCombo), "powerpad.0");
651
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(typeCombo), "powerpad.1");
652
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(typeCombo), "arkanoid");
654
gtk_combo_box_set_active(GTK_COMBO_BOX(typeCombo), 0);
657
padNoCombo = gtk_combo_box_text_new();
658
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(padNoCombo), "1");
659
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(padNoCombo), "2");
660
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(padNoCombo), "3");
661
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(padNoCombo), "4");
662
gtk_combo_box_set_active(GTK_COMBO_BOX(padNoCombo), 0);
663
g_signal_connect(padNoCombo, "changed", G_CALLBACK(updateGamepadConfig), NULL);
665
configNoCombo = gtk_combo_box_text_new();
666
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(configNoCombo), "1");
667
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(configNoCombo), "2");
668
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(configNoCombo), "3");
669
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(configNoCombo), "4");
670
gtk_combo_box_set_active(GTK_COMBO_BOX(configNoCombo), 0);
671
g_signal_connect(padNoCombo, "changed", G_CALLBACK(updateGamepadConfig), NULL);
674
g_signal_connect(typeCombo, "changed", G_CALLBACK(setInputDevice),
675
gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(typeCombo)));
679
g_config->getOption("SDL.FourScore", &buf);
681
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fourScoreChk), 1);
683
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fourScoreChk), 0);
684
g_config->getOption("SDL.Input.EnableOppositeDirectionals", &buf);
686
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(oppositeDirChk), 1);
688
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(oppositeDirChk), 0);
690
g_signal_connect(fourScoreChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.FourScore");
691
g_signal_connect(oppositeDirChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.Input.EnableOppositeDirectionals");
693
gtk_box_pack_start(GTK_BOX(hboxPadNo), padNoLabel, TRUE, TRUE, 5);
694
gtk_box_pack_start(GTK_BOX(hboxPadNo), padNoCombo, TRUE, TRUE, 5);
695
//gtk_box_pack_start(GTK_BOX(hboxPadNo), configNoLabel, TRUE, TRUE, 5);
696
//gtk_box_pack_start(GTK_BOX(hboxPadNo), configNoCombo, TRUE, TRUE, 5);
697
gtk_box_pack_start(GTK_BOX(vbox), hboxPadNo, FALSE, TRUE, 5);
698
//gtk_box_pack_start_defaults(GTK_BOX(vbox), typeCombo);
700
gtk_box_pack_start(GTK_BOX(vbox), fourScoreChk, FALSE, TRUE, 5);
701
gtk_box_pack_start(GTK_BOX(vbox), oppositeDirChk, FALSE, TRUE, 5);
704
// create gamepad buttons
705
buttonFrame = gtk_frame_new("<b><i>Buttons</i></b>");
706
gtk_label_set_use_markup(GTK_LABEL(gtk_frame_get_label_widget(GTK_FRAME(buttonFrame))), TRUE);
707
buttonTable = gtk_table_new(10, 3, FALSE);
708
gtk_table_set_col_spacings(GTK_TABLE(buttonTable), 5);
709
gtk_container_add(GTK_CONTAINER(buttonFrame), buttonTable);
710
for(int i=0; i<10; i++)
712
GtkWidget* buttonName = gtk_label_new(GamePadNames[i]);
713
GtkWidget* mappedKey = gtk_label_new(NULL);
714
GtkWidget* changeButton = gtk_toggle_button_new();
717
sprintf(strBuf, "%s:", GamePadNames[i]);
718
gtk_label_set_text(GTK_LABEL(buttonName), strBuf);
719
gtk_misc_set_alignment(GTK_MISC(buttonName), 1.0, 0.5);
721
gtk_misc_set_alignment(GTK_MISC(mappedKey), 0.0, 0.5);
723
gtk_button_set_label(GTK_BUTTON(changeButton), "Change");
724
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(changeButton), FALSE);
726
gtk_table_attach(GTK_TABLE(buttonTable), buttonName, 0, 1, i, i+1, GTK_FILL, GTK_FILL, 0, 0);
727
gtk_table_attach(GTK_TABLE(buttonTable), mappedKey, 1, 2, i, i+1,
728
(GtkAttachOptions)(GTK_EXPAND|GTK_FILL), (GtkAttachOptions)(GTK_EXPAND|GTK_FILL), 0, 0);
729
gtk_table_attach(GTK_TABLE(buttonTable), changeButton, 2, 3, i, i+1,
730
(GtkAttachOptions)0, (GtkAttachOptions)0, 0, 0);
732
g_signal_connect(changeButton, "clicked", G_CALLBACK(configGamepadButton), GINT_TO_POINTER(i));
733
buttonMappings[i] = mappedKey;
736
// display the button mappings for the currently selected configuration
737
updateGamepadConfig(NULL, NULL);
739
gtk_box_pack_start(GTK_BOX(vbox), buttonFrame, TRUE, TRUE, 5);
741
g_signal_connect(win, "delete-event", G_CALLBACK(closeDialog), NULL);
742
g_signal_connect(win, "response", G_CALLBACK(closeDialog), NULL);
744
gtk_widget_show_all(win);
749
int setBufSize(GtkWidget* w, gpointer p)
751
int x = gtk_range_get_value(GTK_RANGE(w));
752
g_config->setOption("SDL.Sound.BufSize", x);
753
// reset sound subsystem for changes to take effect
759
void setRate(GtkWidget* w, gpointer p)
761
char* str = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(w));
762
g_config->setOption("SDL.Sound.Rate", atoi(str));
763
// reset sound subsystem for changes to take effect
770
void setQuality(GtkWidget* w, gpointer p)
772
char* str = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(w));
773
if(!strcmp(str, "Very High"))
774
g_config->setOption("SDL.Sound.Quality", 2);
775
if(!strcmp(str, "High"))
776
g_config->setOption("SDL.Sound.Quality", 1);
777
if(!strcmp(str, "Low"))
778
g_config->setOption("SDL.Sound.Quality", 0);
779
// reset sound subsystem for changes to take effect
786
void resizeGtkWindow()
790
double xscale, yscale;
791
g_config->getOption("SDL.XScale", &xscale);
792
g_config->getOption("SDL.YScale", &yscale);
793
gtk_widget_set_size_request(evbox, 256*xscale, 224*yscale);
795
gtk_widget_size_request(GTK_WIDGET(MainWindow), &req);
796
gtk_window_resize(GTK_WINDOW(MainWindow), req.width, req.height);
801
void setScaler(GtkWidget* w, gpointer p)
803
int x = gtk_combo_box_get_active(GTK_COMBO_BOX(w));
804
g_config->setOption("SDL.SpecialFilter", x);
806
// 1 - hq2x 2 - Scale2x 3 - NTSC2x 4 - hq3x 5 - Scale3x
807
if (x >= 1 && x <= 3)
809
g_config->setOption("SDL.XScale", 2.0);
810
g_config->setOption("SDL.YScale", 2.0);
815
g_config->setOption("SDL.XScale", 3.0);
816
g_config->setOption("SDL.YScale", 3.0);
824
int setXscale(GtkWidget* w, gpointer p)
826
double v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
827
g_config->setOption("SDL.XScale", v);
833
int setYscale(GtkWidget* w, gpointer p)
835
double v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
836
g_config->setOption("SDL.YScale", v);
843
void setGl(GtkWidget* w, gpointer p)
845
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
846
g_config->setOption("SDL.OpenGL", 1);
848
g_config->setOption("SDL.OpenGL", 0);
852
void setDoubleBuffering(GtkWidget* w, gpointer p)
854
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
855
g_config->setOption("SDL.DoubleBuffering", 1);
857
g_config->setOption("SDL.DoubleBuffering", 0);
862
void openVideoConfig()
868
GtkWidget* scalerLbl;
869
GtkWidget* scalerCombo;
871
GtkWidget* linearChk;
875
GtkWidget* spriteLimitChk;
876
GtkWidget* frameskipChk;
877
GtkWidget* clipSidesChk;
878
GtkWidget* xscaleSpin;
879
GtkWidget* yscaleSpin;
880
GtkWidget* xscaleLbl;
881
GtkWidget* yscaleLbl;
882
GtkWidget* xscaleHbox;
883
GtkWidget* yscaleHbox;
884
GtkWidget* showFpsChk;
886
win = gtk_dialog_new_with_buttons("Video Preferences",
887
GTK_WINDOW(MainWindow),
888
(GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT),
889
GTK_STOCK_CLOSE, GTK_RESPONSE_OK, NULL);
890
gtk_window_set_icon_name(GTK_WINDOW(win), "video-display");
891
//gtk_widget_set_size_request(win, 250, 250);
893
vbox = gtk_dialog_get_content_area(GTK_DIALOG(win));
895
lbl = gtk_label_new("Video options will not take\neffect until the emulator is restarted.");
898
hbox1 = gtk_hbox_new(FALSE, 3);
899
scalerLbl = gtk_label_new("Special Scaler: ");
900
scalerCombo = gtk_combo_box_text_new();
902
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scalerCombo), "none");
903
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scalerCombo), "hq2x");
904
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scalerCombo), "scale2x");
905
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scalerCombo), "NTSC 2x");
906
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scalerCombo), "hq3x");
907
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scalerCombo), "scale3x");
911
g_config->getOption("SDL.SpecialFilter", &buf);
912
gtk_combo_box_set_active(GTK_COMBO_BOX(scalerCombo), buf);
914
g_signal_connect(scalerCombo, "changed", G_CALLBACK(setScaler), NULL);
915
gtk_box_pack_start(GTK_BOX(hbox1), scalerLbl, FALSE, FALSE, 5);
916
gtk_box_pack_start(GTK_BOX(hbox1), scalerCombo, FALSE, FALSE, 5);
919
glChk = gtk_check_button_new_with_label("Enable OpenGL");
920
g_signal_connect(glChk, "clicked", G_CALLBACK(setGl), NULL);
924
g_config->getOption("SDL.OpenGL", &buf);
926
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glChk), 1);
928
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glChk), 0);
930
// openGL linear filter check
931
linearChk = gtk_check_button_new_with_label("Enable OpenGL linear filter");
932
g_signal_connect(linearChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.OpenGLip");
936
g_config->getOption("SDL.OpenGLip", &buf);
938
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linearChk), 1);
940
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linearChk), 0);
942
// DoubleBuffering check
943
dbChk = gtk_check_button_new_with_label("Enable double buffering");
944
g_signal_connect(dbChk, "clicked", G_CALLBACK(setDoubleBuffering), NULL);
948
g_config->getOption("SDL.DoubleBuffering", &buf);
950
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dbChk), 1);
952
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dbChk), 0);
957
palChk = gtk_check_button_new_with_label("Enable PAL mode");
958
g_signal_connect(palChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.PAL");
962
g_config->getOption("SDL.PAL", &buf);
964
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(palChk), 1);
966
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(palChk), 0);
969
ppuChk = gtk_check_button_new_with_label("Enable new PPU");
970
g_signal_connect(ppuChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.NewPPU");
974
g_config->getOption("SDL.NewPPU", &buf);
976
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ppuChk), 1);
978
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ppuChk), 0);
980
// "disable 8 sprite limit" check
981
spriteLimitChk = gtk_check_button_new_with_label("Disable sprite limit");
982
g_signal_connect(spriteLimitChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.DisableSpriteLimit");
986
g_config->getOption("SDL.DisableSpriteLimit", &buf);
988
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(spriteLimitChk), 1);
990
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(spriteLimitChk), 0);
993
frameskipChk = gtk_check_button_new_with_label("Enable frameskip");
994
g_signal_connect(frameskipChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.Frameskip");
998
g_config->getOption("SDL.Frameskip", &buf);
1000
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frameskipChk), 1);
1002
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frameskipChk), 0);
1006
clipSidesChk = gtk_check_button_new_with_label("Clip sides");
1007
g_signal_connect(clipSidesChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.ClipSides");
1011
g_config->getOption("SDL.ClipSides", &buf);
1013
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(clipSidesChk), 1);
1015
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(clipSidesChk), 0);
1018
xscaleHbox = gtk_hbox_new(FALSE, 5);
1019
xscaleLbl = gtk_label_new("X scaling factor");
1020
xscaleSpin = gtk_spin_button_new_with_range(1.0, 10.0, .1);
1021
yscaleHbox = gtk_hbox_new(FALSE, 5);
1022
yscaleLbl = gtk_label_new("Y scaling factor");
1023
yscaleSpin = gtk_spin_button_new_with_range(1.0, 10.0, .1);
1025
gtk_box_pack_start(GTK_BOX(xscaleHbox), xscaleLbl, FALSE, FALSE, 2);
1026
gtk_box_pack_start(GTK_BOX(xscaleHbox), xscaleSpin, FALSE, FALSE, 2);
1027
gtk_box_pack_start(GTK_BOX(yscaleHbox), yscaleLbl, FALSE, FALSE, 2);
1028
gtk_box_pack_start(GTK_BOX(yscaleHbox), yscaleSpin, FALSE, FALSE, 2);
1030
g_signal_connect(xscaleSpin, "value-changed", G_CALLBACK(setXscale), NULL);
1031
g_signal_connect(yscaleSpin, "value-changed", G_CALLBACK(setYscale), NULL);
1035
g_config->getOption("SDL.XScale", &f);
1036
gtk_spin_button_set_value(GTK_SPIN_BUTTON(xscaleSpin), f);
1037
g_config->getOption("SDL.YScale", &f);
1038
gtk_spin_button_set_value(GTK_SPIN_BUTTON(yscaleSpin), f);
1041
showFpsChk = gtk_check_button_new_with_label("Show FPS");
1042
g_signal_connect(showFpsChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.ShowFPS");
1046
g_config->getOption("SDL.ShowFPS", &buf);
1048
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(showFpsChk), 1);
1050
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(showFpsChk), 0);
1054
gtk_box_pack_start(GTK_BOX(vbox), lbl, FALSE, FALSE, 5);
1055
gtk_box_pack_start(GTK_BOX(vbox), hbox1, FALSE, FALSE, 5);
1057
gtk_box_pack_start(GTK_BOX(vbox), glChk, FALSE, FALSE, 5);
1058
gtk_box_pack_start(GTK_BOX(vbox), linearChk, FALSE, FALSE, 5);
1059
gtk_box_pack_start(GTK_BOX(vbox), dbChk, FALSE, FALSE, 5);
1061
gtk_box_pack_start(GTK_BOX(vbox), palChk, FALSE, FALSE,5);
1062
gtk_box_pack_start(GTK_BOX(vbox), ppuChk, FALSE, FALSE, 5);
1064
gtk_box_pack_start(GTK_BOX(vbox), frameskipChk, FALSE, FALSE, 5);
1066
gtk_box_pack_start(GTK_BOX(vbox), spriteLimitChk, FALSE, FALSE, 5);
1067
gtk_box_pack_start(GTK_BOX(vbox), clipSidesChk, FALSE, FALSE, 5);
1068
gtk_box_pack_start(GTK_BOX(vbox), xscaleHbox, FALSE, FALSE, 5);
1069
gtk_box_pack_start(GTK_BOX(vbox), yscaleHbox, FALSE, FALSE, 5);
1070
gtk_box_pack_start(GTK_BOX(vbox), showFpsChk, FALSE, FALSE, 5);
1072
g_signal_connect(win, "delete-event", G_CALLBACK(closeVideoWin), NULL);
1073
g_signal_connect(win, "response", G_CALLBACK(closeVideoWin), NULL);
1075
gtk_widget_show_all(win);
1079
const char* mixerStrings[6] = {"Volume", "Triangle", "Square1", "Square2", "Noise", "PCM"};
1081
int mixerChanged(GtkWidget* w, gpointer p)
1083
int v = gtk_range_get_value(GTK_RANGE(w));
1084
GtkWidget* parent = gtk_widget_get_parent(w);
1085
char* lbl = (char*)gtk_frame_get_label(GTK_FRAME(parent));
1086
if(strcmp(lbl, "Volume") == 0)
1088
g_config->setOption("SDL.Sound.Volume", v);
1089
FCEUI_SetSoundVolume(v);
1091
if(strcmp(lbl, "Triangle") == 0)
1093
g_config->setOption("SDL.Sound.TriangleVolume", v);
1094
FCEUI_SetTriangleVolume(v);
1096
if(strcmp(lbl, "Square1") == 0)
1098
g_config->setOption("SDL.Sound.Square1Volume", v);
1099
FCEUI_SetSquare1Volume(v);
1101
if(strcmp(lbl, "Square2") == 0)
1103
g_config->setOption("SDL.Sound.Square2Volume", v);
1104
FCEUI_SetSquare2Volume(v);
1106
if(strcmp(lbl, "Noise") == 0)
1108
g_config->setOption("SDL.Sound.NoiseVolume", v);
1109
FCEUI_SetNoiseVolume(v);
1111
if(strcmp(lbl, "PCM") == 0)
1113
g_config->setOption("SDL.Sound.PCMVolume", v);
1114
FCEUI_SetPCMVolume(v);
1120
void openSoundConfig()
1123
GtkWidget* main_hbox;
1125
GtkWidget* soundChk;
1126
GtkWidget* lowpassChk;
1128
GtkWidget* qualityCombo;
1129
GtkWidget* qualityLbl;
1131
GtkWidget* rateCombo;
1134
GtkWidget* bufferLbl;
1135
GtkWidget* bufferHscale;
1136
GtkWidget* mixerFrame;
1137
GtkWidget* mixerHbox;
1138
GtkWidget* mixers[6];
1139
GtkWidget* mixerFrames[6];
1141
win = gtk_dialog_new_with_buttons("Sound Preferences",
1142
GTK_WINDOW(MainWindow),
1143
(GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT),
1147
gtk_window_set_icon_name(GTK_WINDOW(win), "audio-x-generic");
1148
main_hbox = gtk_hbox_new(FALSE, 15);
1149
vbox = gtk_vbox_new(False, 5);
1151
// sound enable check
1152
soundChk = gtk_check_button_new_with_label("Enable sound");
1156
g_config->getOption("SDL.Sound", &cfgBuf);
1158
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(soundChk), TRUE);
1160
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(soundChk), FALSE);
1162
g_signal_connect(soundChk, "clicked", G_CALLBACK(toggleSound), NULL);
1164
// low pass filter check
1165
lowpassChk = gtk_check_button_new_with_label("Enable low pass filter");
1168
g_config->getOption("SDL.Sound.LowPass", &cfgBuf);
1170
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lowpassChk), TRUE);
1172
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lowpassChk), FALSE);
1174
g_signal_connect(lowpassChk, "clicked", G_CALLBACK(toggleLowPass), NULL);
1176
// sound quality combo box
1177
hbox1 = gtk_hbox_new(FALSE, 3);
1178
qualityCombo = gtk_combo_box_text_new();
1179
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(qualityCombo), "Low");
1180
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(qualityCombo), "High");
1181
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(qualityCombo), "Very High");
1183
// sync widget with cfg
1184
g_config->getOption("SDL.Sound.Quality", &cfgBuf);
1186
gtk_combo_box_set_active(GTK_COMBO_BOX(qualityCombo), 2);
1187
else if(cfgBuf == 1)
1188
gtk_combo_box_set_active(GTK_COMBO_BOX(qualityCombo), 1);
1190
gtk_combo_box_set_active(GTK_COMBO_BOX(qualityCombo), 0);
1192
g_signal_connect(qualityCombo, "changed", G_CALLBACK(setQuality), NULL);
1194
qualityLbl = gtk_label_new("Quality: ");
1196
gtk_box_pack_start(GTK_BOX(hbox1), qualityLbl, FALSE, FALSE, 5);
1197
gtk_box_pack_start(GTK_BOX(hbox1), qualityCombo, FALSE, FALSE, 5);
1199
// sound rate widgets
1200
hbox2 = gtk_hbox_new(FALSE, 3);
1201
rateCombo = gtk_combo_box_text_new();
1203
const int rates[5] = {11025, 22050, 44100, 48000, 96000};
1206
for(int i=0; i<5;i++)
1208
sprintf(buf, "%d", rates[i]);
1209
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rateCombo), buf);
1212
// sync widget with cfg
1213
g_config->getOption("SDL.Sound.Rate", &cfgBuf);
1214
for(int i=0; i<5; i++)
1215
if(cfgBuf == rates[i])
1216
gtk_combo_box_set_active(GTK_COMBO_BOX(rateCombo), i);
1218
g_signal_connect(rateCombo, "changed", G_CALLBACK(setRate), NULL);
1220
// sound rate widgets
1221
rateLbl = gtk_label_new("Rate (Hz): ");
1223
gtk_box_pack_start(GTK_BOX(hbox2), rateLbl, FALSE, FALSE, 5);
1224
gtk_box_pack_start(GTK_BOX(hbox2), rateCombo, FALSE, FALSE, 5);
1226
hbox3 = gtk_hbox_new(FALSE, 2);
1227
bufferHscale = gtk_hscale_new_with_range(15, 200, 2);
1228
bufferLbl = gtk_label_new("Buffer size (in ms)");
1230
// sync widget with cfg
1231
g_config->getOption("SDL.Sound.BufSize", &cfgBuf);
1232
gtk_range_set_value(GTK_RANGE(bufferHscale), cfgBuf);
1234
g_signal_connect(bufferHscale, "button-release-event", G_CALLBACK(setBufSize), NULL);
1237
mixerFrame = gtk_frame_new("Mixer:");
1238
mixerHbox = gtk_hbox_new(TRUE, 5);
1239
for(int i=0; i<6; i++)
1241
mixers[i] = gtk_vscale_new_with_range(0, 256, 1);
1242
gtk_range_set_inverted(GTK_RANGE(mixers[i]), TRUE);
1243
mixerFrames[i] = gtk_frame_new(mixerStrings[i]);
1244
gtk_container_add(GTK_CONTAINER(mixerFrames[i]), mixers[i]);
1245
gtk_box_pack_start(GTK_BOX(mixerHbox), mixerFrames[i], FALSE, TRUE, 5);
1246
g_signal_connect(mixers[i], "button-release-event", G_CALLBACK(mixerChanged), (gpointer)i);
1251
g_config->getOption("SDL.Sound.Volume", &v);
1252
gtk_range_set_value(GTK_RANGE(mixers[0]), v);
1253
g_config->getOption("SDL.Sound.TriangleVolume", &v);
1254
gtk_range_set_value(GTK_RANGE(mixers[1]), v);
1255
g_config->getOption("SDL.Sound.Square1Volume", &v);
1256
gtk_range_set_value(GTK_RANGE(mixers[2]), v);
1257
g_config->getOption("SDL.Sound.Square2Volume", &v);
1258
gtk_range_set_value(GTK_RANGE(mixers[3]), v);
1259
g_config->getOption("SDL.Sound.NoiseVolume", &v);
1260
gtk_range_set_value(GTK_RANGE(mixers[4]), v);
1261
g_config->getOption("SDL.Sound.PCMVolume", &v);
1262
gtk_range_set_value(GTK_RANGE(mixers[5]), v);
1265
// packing some boxes
1267
gtk_box_pack_start(GTK_BOX(main_hbox), vbox, FALSE, TRUE, 5);
1268
gtk_box_pack_start(GTK_BOX(vbox), soundChk, FALSE, FALSE, 5);
1269
gtk_box_pack_start(GTK_BOX(vbox), lowpassChk, FALSE, FALSE, 5);
1270
gtk_box_pack_start(GTK_BOX(vbox), hbox1, FALSE, FALSE, 5);
1271
gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 5);
1272
gtk_box_pack_start(GTK_BOX(vbox), bufferLbl, FALSE, FALSE, 5);
1273
gtk_box_pack_start(GTK_BOX(vbox), bufferHscale, FALSE, TRUE, 5);
1274
gtk_box_pack_start(GTK_BOX(main_hbox), mixerFrame, TRUE, TRUE, 5);
1275
gtk_container_add(GTK_CONTAINER(mixerFrame), mixerHbox);
1277
gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(win))), main_hbox, TRUE, TRUE, 0);
1279
g_signal_connect(win, "delete-event", G_CALLBACK(closeDialog), NULL);
1280
g_signal_connect(win, "response", G_CALLBACK(closeDialog), NULL);
1282
gtk_widget_show_all(win);
1289
// manually flush GTK event queue
1290
while(gtk_events_pending())
1291
gtk_main_iteration_do(FALSE);
1292
// this is not neccesary to be explicitly called
1293
// it raises a GTK-Critical when its called
1297
// LoadGame() checks for an IP and if it finds one begins a network session
1298
// clear the NetworkIP field so this doesn't happen unintentionally
1299
g_config->setOption("SDL.NetworkIP", "");
1304
const char* Authors[]= {
1305
"Linux/SDL Developers:",
1306
" Lukas Sabota", " Soules", " Bryan Cain", " radsaq", " Shinydoofy",
1307
"FceuX 2.0 Developers:",
1308
" SP", " zeromus", " adelikat", " caH4e3", " qfox",
1309
" Luke Gustafson", " _mz", " UncombedCoconut", " DwEdit", " AnS",
1311
" Bero", " Xodnizel", " Aaron Oneal", " Joe Nahmias",
1312
" Paul Kuliniewicz", " Quietust", " Ben Parnell", " Parasyte & bbitmaster",
1318
GdkPixbuf* logo = gdk_pixbuf_new_from_xpm_data(icon_xpm);
1320
gtk_show_about_dialog(GTK_WINDOW(MainWindow),
1321
"program-name", "fceuX",
1322
"version", FCEU_VERSION_STRING,
1323
"copyright", "© 2012 FceuX development team",
1324
"license", "GPL-2; See COPYING",
1325
//"license-type", GTK_LICENSE_GPL_2_0,
1326
"website", "http://fceux.com",
1328
"logo", logo, NULL);
1331
void toggleSound(GtkWidget* check, gpointer data)
1333
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check)))
1335
g_config->setOption("SDL.Sound", 1);
1341
g_config->setOption("SDL.Sound", 0);
1357
const char* lastFile;
1358
g_config->getOption("SDL.LastOpenFile", &lastFile);
1359
LoadGame(lastFile) == 0;
1364
void enableFullscreen ()
1370
void toggleAutoResume (GtkToggleAction *action)
1372
bool autoResume = gtk_toggle_action_get_active(action);
1374
g_config->setOption("SDL.AutoResume", (int)autoResume);
1375
AutoResumePlay = autoResume;
1382
char* movie_fname = const_cast<char*>(FCEU_MakeFName(FCEUMKF_MOVIE, 0, 0).c_str());
1383
FCEUI_printf("Recording movie to %s\n", movie_fname);
1384
FCEUI_SaveMovie(movie_fname, MOVIE_FLAG_NONE, L"");
1389
void recordMovieAs ()
1395
GtkWidget* fileChooser;
1397
GtkFileFilter* filterFm2;
1398
GtkFileFilter* filterAll;
1400
filterFm2 = gtk_file_filter_new();
1401
gtk_file_filter_add_pattern(filterFm2, "*.fm2");
1402
gtk_file_filter_set_name(filterFm2, "FM2 Movies");
1404
filterAll = gtk_file_filter_new();
1405
gtk_file_filter_add_pattern(filterAll, "*");
1406
gtk_file_filter_set_name(filterAll, "All Files");
1408
fileChooser = gtk_file_chooser_dialog_new ("Save FM2 movie for recording", GTK_WINDOW(MainWindow),
1409
GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1410
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
1411
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(fileChooser), ".fm2");
1412
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterFm2);
1413
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterAll);
1414
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fileChooser), getcwd(NULL, 0));
1416
if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1420
fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
1422
return; // no filename selected, quit the whole thing
1423
char* movie_fname = const_cast<char*>(FCEU_MakeFName(FCEUMKF_MOVIE, 0, 0).c_str());
1425
std::string s = GetUserText("Author name");
1426
std::wstring author(s.begin(), s.end());
1429
FCEUI_SaveMovie(fname.c_str(), MOVIE_FLAG_NONE, author);
1431
gtk_widget_destroy (fileChooser);
1436
GtkWidget* fileChooser;
1438
GtkFileFilter* filterMovies;
1439
GtkFileFilter* filterFm2;
1440
GtkFileFilter* filterAll;
1442
filterMovies = gtk_file_filter_new();
1443
gtk_file_filter_add_pattern(filterMovies, "*.fm2");
1444
gtk_file_filter_add_pattern(filterMovies, "*.FM2f");
1445
gtk_file_filter_add_pattern(filterMovies, "*.fm3");
1446
gtk_file_filter_set_name(filterMovies, "FM2 Movies, TAS Editor Projects");
1448
filterFm2 = gtk_file_filter_new();
1449
gtk_file_filter_add_pattern(filterFm2, "*.fm2");
1450
gtk_file_filter_add_pattern(filterFm2, "*.FM2f");
1451
gtk_file_filter_set_name(filterFm2, "FM2 Movies");
1453
filterAll = gtk_file_filter_new();
1454
gtk_file_filter_add_pattern(filterAll, "*");
1455
gtk_file_filter_set_name(filterAll, "All Files");
1457
fileChooser = gtk_file_chooser_dialog_new ("Open FM2 Movie", GTK_WINDOW(MainWindow),
1458
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1459
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
1461
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterMovies);
1462
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterFm2);
1463
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterAll);
1464
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fileChooser), getcwd(NULL, 0));
1466
if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1470
fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
1471
static int pauseframe;
1472
g_config->getOption("SDL.PauseFrame", &pauseframe);
1473
g_config->setOption("SDL.PauseFrame", 0);
1474
FCEUI_printf("Playing back movie located at %s\n", fname);
1475
if(FCEUI_LoadMovie(fname, false, pauseframe ? pauseframe : false) == FALSE)
1478
d = gtk_message_dialog_new(GTK_WINDOW(MainWindow), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1479
"Could not open the movie file.");
1480
gtk_dialog_run(GTK_DIALOG(d));
1481
gtk_widget_destroy(d);
1484
gtk_widget_destroy (fileChooser);
1490
GtkWidget* fileChooser;
1491
GtkFileFilter* filterLua;
1492
GtkFileFilter* filterAll;
1494
filterLua = gtk_file_filter_new();
1495
gtk_file_filter_add_pattern(filterLua, "*.lua");
1496
gtk_file_filter_add_pattern(filterLua, "*.LUA");
1497
gtk_file_filter_set_name(filterLua, "Lua scripts");
1499
filterAll = gtk_file_filter_new();
1500
gtk_file_filter_add_pattern(filterAll, "*");
1501
gtk_file_filter_set_name(filterAll, "All Files");
1503
fileChooser = gtk_file_chooser_dialog_new ("Open LUA Script", GTK_WINDOW(MainWindow),
1504
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1505
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
1507
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterLua);
1508
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterAll);
1509
const char* last_file;
1510
g_config->getOption("SDL.LastLoadLua", &last_file);
1511
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(fileChooser), last_file);
1513
if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1517
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
1518
g_config->setOption("SDL.LastLoadLua", filename);
1519
gtk_widget_destroy(fileChooser);
1520
if(FCEU_LoadLuaCode(filename) == 0)
1522
// This is necessary because lua scripts do not use FCEUD_PrintError to print errors.
1524
d = gtk_message_dialog_new(GTK_WINDOW(MainWindow), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1525
"Could not open the selected lua script.");
1526
gtk_dialog_run(GTK_DIALOG(d));
1527
gtk_widget_destroy(d);
1532
gtk_widget_destroy (fileChooser);
1539
GtkWidget* fileChooser;
1540
GtkFileFilter* filterDiskSys;
1541
GtkFileFilter* filterRom;
1542
GtkFileFilter* filterAll;
1545
filterDiskSys = gtk_file_filter_new();
1546
gtk_file_filter_add_pattern(filterDiskSys, "disksys.rom");
1547
gtk_file_filter_set_name(filterDiskSys, "disksys.rom");
1549
filterRom = gtk_file_filter_new();
1550
gtk_file_filter_add_pattern(filterRom, "*.rom");
1551
gtk_file_filter_set_name(filterRom, "*.rom");
1553
filterAll = gtk_file_filter_new();
1554
gtk_file_filter_add_pattern(filterAll, "*");
1555
gtk_file_filter_set_name(filterAll, "All Files");
1558
fileChooser = gtk_file_chooser_dialog_new ("Load FDS BIOS (disksys.rom)", GTK_WINDOW(MainWindow),
1559
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1560
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
1561
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterDiskSys);
1562
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterRom);
1563
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterAll);
1564
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fileChooser), getcwd(NULL, 0));
1566
if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1569
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
1570
// copy BIOS file to proper place (~/.fceux/disksys.rom)
1571
std::ifstream fdsBios (filename,std::fstream::binary);
1572
std::string output_filename = FCEU_MakeFName(FCEUMKF_FDSROM, 0, "");
1573
std::ofstream outFile (output_filename.c_str(),std::fstream::trunc|std::fstream::binary);
1574
outFile<<fdsBios.rdbuf();
1577
FCEUD_PrintError("Error copying the FDS BIOS file.");
1582
d = gtk_message_dialog_new(GTK_WINDOW(MainWindow), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
1583
"Famicom Disk System BIOS loaded. If you are you having issues, make sure your BIOS file is 8KB in size.");
1584
gtk_dialog_run(GTK_DIALOG(d));
1585
gtk_widget_destroy(d);
1588
gtk_widget_destroy (fileChooser);
1591
// TODO: is there somewhere else we can move this? works for now though
1592
void enableGameGenie(int enabled)
1594
g_config->setOption("SDL.GameGenie", enabled);
1596
FCEUI_SetGameGenie(enabled);
1599
void toggleGameGenie(GtkToggleAction *action)
1601
enableGameGenie(gtk_toggle_action_get_active(action));
1604
void togglePause(GtkAction *action)
1611
paused = FCEUI_EmulationPaused();
1613
sdlev.type = SDL_FCEU_HOTKEY_EVENT;
1614
sdlev.user.code = HK_PAUSE;
1615
if(SDL_PushEvent(&sdlev) < 0)
1617
FCEU_printf("Failed to push SDL event to %s game.\n", paused ? "resume" : "pause");
1620
gtk_action_set_label(action, paused ? "Pause" : "Resume");
1621
gtk_action_set_stock_id(action, paused ? GTK_STOCK_MEDIA_PAUSE : GTK_STOCK_MEDIA_PLAY);
1625
void loadGameGenie ()
1627
GtkWidget* fileChooser;
1628
GtkFileFilter* filterGG;
1629
GtkFileFilter* filterRom;
1630
GtkFileFilter* filterNes;
1631
GtkFileFilter* filterAll;
1634
filterGG = gtk_file_filter_new();
1635
gtk_file_filter_add_pattern(filterGG, "gg.rom");
1636
gtk_file_filter_set_name(filterGG, "gg.rom");
1638
filterRom = gtk_file_filter_new();
1639
gtk_file_filter_add_pattern(filterRom, "*.rom");
1640
gtk_file_filter_set_name(filterRom, "*.rom");
1642
filterNes = gtk_file_filter_new();
1643
gtk_file_filter_add_pattern(filterNes, "*.nes");
1644
gtk_file_filter_set_name(filterNes, "*.nes");
1646
filterAll = gtk_file_filter_new();
1647
gtk_file_filter_add_pattern(filterAll, "*");
1648
gtk_file_filter_set_name(filterAll, "All Files");
1651
fileChooser = gtk_file_chooser_dialog_new ("Load Game Genie ROM", GTK_WINDOW(MainWindow),
1652
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1653
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
1654
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterGG);
1655
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterRom);
1656
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterNes);
1657
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterAll);
1658
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fileChooser), getcwd(NULL, 0));
1660
if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1663
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
1664
// copy file to proper place (~/.fceux/gg.rom)
1665
std::ifstream f1 (filename,std::fstream::binary);
1666
std::string fn_out = FCEU_MakeFName(FCEUMKF_GGROM, 0, "");
1667
std::ofstream f2 (fn_out.c_str(),std::fstream::trunc|std::fstream::binary);
1668
gtk_widget_destroy (fileChooser);
1670
enableGameGenie(TRUE);
1671
d = gtk_message_dialog_new(GTK_WINDOW(MainWindow), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
1672
"Game Genie ROM copied to: '%s'.", fn_out.c_str());
1673
gtk_dialog_run(GTK_DIALOG(d));
1674
gtk_widget_destroy(d);
1680
gtk_widget_destroy (fileChooser);
1686
GtkWidget* fileChooser;
1687
GtkFileFilter* filterNSF;
1688
GtkFileFilter* filterZip;
1689
GtkFileFilter* filterAll;
1691
filterNSF = gtk_file_filter_new();
1692
filterZip = gtk_file_filter_new();
1693
gtk_file_filter_add_pattern(filterNSF, "*.nsf");
1694
gtk_file_filter_add_pattern(filterNSF, "*.NSF");
1695
gtk_file_filter_add_pattern(filterZip, "*.zip");
1696
gtk_file_filter_add_pattern(filterZip, "*.ZIP");
1697
gtk_file_filter_set_name(filterNSF, "NSF sound files");
1698
gtk_file_filter_set_name(filterZip, "Zip archives");
1700
filterAll = gtk_file_filter_new();
1701
gtk_file_filter_add_pattern(filterAll, "*");
1702
gtk_file_filter_set_name(filterAll, "All Files");
1704
fileChooser = gtk_file_chooser_dialog_new ("Open NSF File", GTK_WINDOW(MainWindow),
1705
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1706
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
1708
const char* last_dir;
1709
g_config->getOption("SDL.LastOpenNSF", &last_dir);
1710
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(fileChooser), last_dir);
1712
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterNSF);
1713
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterZip);
1714
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterAll);
1716
if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1720
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
1721
gtk_widget_destroy (fileChooser);
1723
// no longer required with GTK FCEUD_PrintError implementation
1724
/*if(LoadGame(filename) == 0)
1728
d = gtk_message_dialog_new(GTK_WINDOW(MainWindow), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1729
"Could not open the selected NSF file.");
1730
gtk_dialog_run(GTK_DIALOG(d));
1731
gtk_widget_destroy(d);
1733
g_config->setOption("SDL.LastOpenNSF", filename);
1737
gtk_widget_destroy (fileChooser);
1742
GdkColor bg = {0, 0, 0, 0};
1743
gtk_widget_modify_bg(evbox, GTK_STATE_NORMAL, &bg);
1749
GtkWidget* fileChooser;
1750
GtkFileFilter* filterFCEU;
1751
GtkFileFilter* filterNes;
1752
GtkFileFilter* filterFds;
1753
GtkFileFilter* filterNSF;
1754
GtkFileFilter* filterZip;
1755
GtkFileFilter* filterAll;
1757
filterFCEU = gtk_file_filter_new();
1758
filterNes = gtk_file_filter_new();
1759
filterFds = gtk_file_filter_new();
1760
filterNSF = gtk_file_filter_new();
1761
filterZip = gtk_file_filter_new();
1762
gtk_file_filter_add_pattern(filterFCEU, "*.nes");
1763
gtk_file_filter_add_pattern(filterFCEU, "*.NES");
1764
gtk_file_filter_add_pattern(filterFCEU, "*.fds");
1765
gtk_file_filter_add_pattern(filterFCEU, "*.FDS");
1766
gtk_file_filter_add_pattern(filterFCEU, "*.zip");
1767
gtk_file_filter_add_pattern(filterFCEU, "*.ZIP");
1768
gtk_file_filter_add_pattern(filterFCEU, "*.Nes");
1769
gtk_file_filter_add_pattern(filterFCEU, "*.Fds");
1770
gtk_file_filter_add_pattern(filterFCEU, "*.Zip");
1771
gtk_file_filter_add_pattern(filterFCEU, "*.nsf");
1772
gtk_file_filter_add_pattern(filterFCEU, "*.NSF");
1773
gtk_file_filter_add_pattern(filterNes, "*.nes");
1774
gtk_file_filter_add_pattern(filterNes, "*.NES");
1775
gtk_file_filter_add_pattern(filterFds, "*.fds");
1776
gtk_file_filter_add_pattern(filterFds, "*.FDS");
1777
gtk_file_filter_add_pattern(filterNSF, "*.nsf");
1778
gtk_file_filter_add_pattern(filterNSF, "*.NSF");
1779
gtk_file_filter_add_pattern(filterZip, "*.zip");
1780
gtk_file_filter_add_pattern(filterZip, "*.zip");
1781
gtk_file_filter_set_name(filterFCEU, "*.nes;*.fds;*.nsf;*.zip");
1782
gtk_file_filter_set_name(filterNes, "NES ROM files");
1783
gtk_file_filter_set_name(filterFds, "FDS ROM files");
1784
gtk_file_filter_set_name(filterNSF, "NSF sound files");
1785
gtk_file_filter_set_name(filterZip, "Zip archives");
1787
filterAll = gtk_file_filter_new();
1788
gtk_file_filter_add_pattern(filterAll, "*");
1789
gtk_file_filter_set_name(filterAll, "All Files");
1793
fileChooser = gtk_file_chooser_dialog_new ("Open ROM", GTK_WINDOW(MainWindow),
1794
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1795
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
1796
const char* last_dir;
1797
g_config->getOption("SDL.LastOpenFile", &last_dir);
1798
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(fileChooser), last_dir);
1800
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterFCEU);
1801
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterNes);
1802
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterFds);
1803
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterNSF);
1804
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterZip);
1805
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterAll);
1807
if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1811
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
1812
gtk_widget_destroy (fileChooser);
1813
g_config->setOption("SDL.LastOpenFile", filename);
1816
// Error dialog no longer required with GTK implementation of FCEUD_PrintError()
1817
/*if(LoadGame(filename) == 0)
1821
d = gtk_message_dialog_new(GTK_WINDOW(MainWindow), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1822
"Could not open the selected ROM file.");
1823
gtk_dialog_run(GTK_DIALOG(d));
1824
gtk_widget_destroy(d);
1830
gtk_widget_destroy (fileChooser);
1835
GtkWidget* fileChooser;
1836
GtkFileFilter* filterSav;
1837
GtkFileFilter* filterAll;
1839
filterSav = gtk_file_filter_new();
1840
gtk_file_filter_add_pattern(filterSav, "*.sav");
1841
gtk_file_filter_add_pattern(filterSav, "*.SAV");
1842
gtk_file_filter_set_name(filterSav, "SAV files");
1844
filterAll = gtk_file_filter_new();
1845
gtk_file_filter_add_pattern(filterAll, "*");
1846
gtk_file_filter_set_name(filterAll, "All Files");
1848
const char* last_dir;
1849
g_config->getOption("SDL.LastSaveStateAs", &last_dir);
1851
fileChooser = gtk_file_chooser_dialog_new ("Save State As", GTK_WINDOW(MainWindow),
1852
GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1853
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
1855
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fileChooser), last_dir);
1857
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(fileChooser), ".sav");
1858
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterSav);
1859
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterAll);
1861
if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1865
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
1866
FCEUI_SaveState(filename);
1867
g_config->setOption("SDL.LastSaveStateAs", filename);
1870
gtk_widget_destroy (fileChooser);
1875
void loadStateFrom()
1877
GtkWidget* fileChooser;
1878
GtkFileFilter* filterFcs;
1879
GtkFileFilter* filterSav;
1880
GtkFileFilter* filterAll;
1882
filterSav = gtk_file_filter_new();
1883
gtk_file_filter_add_pattern(filterSav, "*.sav");
1884
gtk_file_filter_add_pattern(filterSav, "*.SAV");
1885
gtk_file_filter_set_name(filterSav, "SAV files");
1887
filterFcs = gtk_file_filter_new();
1888
gtk_file_filter_add_pattern(filterFcs, "*.fc?");
1889
gtk_file_filter_add_pattern(filterFcs, "*.FC?");
1890
gtk_file_filter_set_name(filterFcs, "FCS files");
1892
filterAll = gtk_file_filter_new();
1893
gtk_file_filter_add_pattern(filterAll, "*");
1894
gtk_file_filter_set_name(filterAll, "All Files");
1896
fileChooser = gtk_file_chooser_dialog_new ("Load State From", GTK_WINDOW(MainWindow),
1897
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1898
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
1900
const char* last_dir;
1901
g_config->getOption("SDL.LastLoadStateFrom", &last_dir);
1902
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(fileChooser), last_dir);
1904
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterFcs);
1905
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterSav);
1906
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterAll);
1908
if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1912
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
1913
FCEUI_LoadState(filename);
1914
g_config->setOption("SDL.LastLoadStateFrom", filename);
1917
gtk_widget_destroy (fileChooser);
1922
FCEUI_LoadState(NULL);
1927
FCEUI_SaveState(NULL);
1930
void changeState(GtkAction *action, GtkRadioAction *current, gpointer data)
1932
FCEUI_SelectState(gtk_radio_action_get_current_value(current), 0);
1936
// Adapted from Gens/GS. Converts a GDK key value into an SDL key value.
1937
unsigned short GDKToSDLKeyval(int gdk_key)
1939
if (!(gdk_key & 0xFF00))
1942
// SDL and GDK use the same values for these keys.
1944
// Make sure the key value is lowercase.
1945
gdk_key = tolower(gdk_key);
1947
// Return the key value.
1951
if (gdk_key & 0xFFFF0000)
1953
// Extended X11 key. Not supported by SDL.
1954
#ifdef GDK_WINDOWING_X11
1955
fprintf(stderr, "Unhandled extended X11 key: 0x%08X (%s)", gdk_key, XKeysymToString(gdk_key));
1957
fprintf(stderr, "Unhandled extended key: 0x%08X\n", gdk_key);
1962
// Non-ASCII symbol.
1963
static const uint16_t gdk_to_sdl_table[0x100] =
1966
0x0000, 0x0000, 0x0000, 0x0000,
1967
0x0000, 0x0000, 0x0000, 0x0000,
1968
SDLK_BACKSPACE, SDLK_TAB, SDLK_RETURN, SDLK_CLEAR,
1969
0x0000, SDLK_RETURN, 0x0000, 0x0000,
1972
0x0000, 0x0000, 0x0000, SDLK_PAUSE,
1973
SDLK_SCROLLOCK, SDLK_SYSREQ, 0x0000, 0x0000,
1974
0x0000, 0x0000, 0x0000, SDLK_ESCAPE,
1975
0x0000, 0x0000, 0x0000, 0x0000,
1978
SDLK_COMPOSE, 0x0000, 0x0000, 0x0000,
1979
0x0000, 0x0000, 0x0000, 0x0000,
1980
0x0000, 0x0000, 0x0000, 0x0000,
1981
0x0000, 0x0000, 0x0000, 0x0000,
1983
// 0x30 - 0x3F [Japanese keys]
1984
0x0000, 0x0000, 0x0000, 0x0000,
1985
0x0000, 0x0000, 0x0000, 0x0000,
1986
0x0000, 0x0000, 0x0000, 0x0000,
1987
0x0000, 0x0000, 0x0000, 0x0000,
1989
// 0x40 - 0x4F [unused]
1990
0x0000, 0x0000, 0x0000, 0x0000,
1991
0x0000, 0x0000, 0x0000, 0x0000,
1992
0x0000, 0x0000, 0x0000, 0x0000,
1993
0x0000, 0x0000, 0x0000, 0x0000,
1996
SDLK_HOME, SDLK_LEFT, SDLK_UP, SDLK_RIGHT,
1997
SDLK_DOWN, SDLK_PAGEUP, SDLK_PAGEDOWN, SDLK_END,
1998
0x0000, 0x0000, 0x0000, 0x0000,
1999
0x0000, 0x0000, 0x0000, 0x0000,
2002
0x0000, SDLK_PRINT, 0x0000, SDLK_INSERT,
2003
SDLK_UNDO, 0x0000, 0x0000, SDLK_MENU,
2004
0x0000, SDLK_HELP, SDLK_BREAK, 0x0000,
2005
0x0000, 0x0000, 0x0000, 0x0000,
2007
// 0x70 - 0x7F [mostly unused, except for Alt Gr and Num Lock]
2008
0x0000, 0x0000, 0x0000, 0x0000,
2009
0x0000, 0x0000, 0x0000, 0x0000,
2010
0x0000, 0x0000, 0x0000, 0x0000,
2011
0x0000, 0x0000, SDLK_MODE, SDLK_NUMLOCK,
2013
// 0x80 - 0x8F [mostly unused, except for some numeric keypad keys]
2014
SDLK_KP5, 0x0000, 0x0000, 0x0000,
2015
0x0000, 0x0000, 0x0000, 0x0000,
2016
0x0000, 0x0000, 0x0000, 0x0000,
2017
0x0000, SDLK_KP_ENTER, 0x0000, 0x0000,
2020
0x0000, 0x0000, 0x0000, 0x0000,
2021
0x0000, SDLK_KP7, SDLK_KP4, SDLK_KP8,
2022
SDLK_KP6, SDLK_KP2, SDLK_KP9, SDLK_KP3,
2023
SDLK_KP1, SDLK_KP5, SDLK_KP0, SDLK_KP_PERIOD,
2026
0x0000, 0x0000, 0x0000, 0x0000,
2027
0x0000, 0x0000, 0x0000, 0x0000,
2028
0x0000, 0x0000, SDLK_KP_MULTIPLY, SDLK_KP_PLUS,
2029
0x0000, SDLK_KP_MINUS, SDLK_KP_PERIOD, SDLK_KP_DIVIDE,
2032
SDLK_KP0, SDLK_KP1, SDLK_KP2, SDLK_KP3,
2033
SDLK_KP4, SDLK_KP5, SDLK_KP6, SDLK_KP7,
2034
SDLK_KP8, SDLK_KP9, 0x0000, 0x0000,
2035
0x0000, SDLK_KP_EQUALS, SDLK_F1, SDLK_F2,
2038
SDLK_F3, SDLK_F4, SDLK_F5, SDLK_F6,
2039
SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10,
2040
SDLK_F11, SDLK_F12, SDLK_F13, SDLK_F14,
2041
SDLK_F15, 0x0000, 0x0000, 0x0000,
2043
// 0xD0 - 0xDF [L* and R* function keys]
2044
0x0000, 0x0000, 0x0000, 0x0000,
2045
0x0000, 0x0000, 0x0000, 0x0000,
2046
0x0000, 0x0000, 0x0000, 0x0000,
2047
0x0000, 0x0000, 0x0000, 0x0000,
2050
0x0000, SDLK_LSHIFT, SDLK_RSHIFT, SDLK_LCTRL,
2051
SDLK_RCTRL, SDLK_CAPSLOCK, 0x0000, SDLK_LMETA,
2052
SDLK_RMETA, SDLK_LALT, SDLK_RALT, SDLK_LSUPER,
2053
SDLK_RSUPER, 0x0000, 0x0000, 0x0000,
2055
// 0xF0 - 0xFF [mostly unused, except for Delete]
2056
0x0000, 0x0000, 0x0000, 0x0000,
2057
0x0000, 0x0000, 0x0000, 0x0000,
2058
0x0000, 0x0000, 0x0000, 0x0000,
2059
0x0000, 0x0000, 0x0000, SDLK_DELETE,
2062
unsigned short sdl_key = gdk_to_sdl_table[gdk_key & 0xFF];
2065
// Unhandled GDK key.
2066
fprintf(stderr, "Unhandled GDK key: 0x%04X (%s)", gdk_key, gdk_keyval_name(gdk_key));
2070
// ignore pause and screenshot hotkeys since they is handled by GTK+ as accelerators
2071
if (sdl_key == Hotkeys[HK_PAUSE] || sdl_key == Hotkeys[HK_SCREENSHOT] ||
2072
sdl_key == Hotkeys[HK_SAVE_STATE] || sdl_key == Hotkeys[HK_LOAD_STATE])
2079
// Function adapted from Gens/GS (source/gens/input/input_sdl.c)
2080
gint convertKeypress(GtkWidget *grab, GdkEventKey *event, gpointer user_data)
2086
switch (event->type)
2089
sdlev.type = SDL_KEYDOWN;
2090
sdlev.key.state = SDL_PRESSED;
2094
case GDK_KEY_RELEASE:
2095
sdlev.type = SDL_KEYUP;
2096
sdlev.key.state = SDL_RELEASED;
2101
fprintf(stderr, "Unhandled GDK event type: %d", event->type);
2105
// Convert this keypress from GDK to SDL.
2106
sdlkey = (SDLKey)GDKToSDLKeyval(event->keyval);
2108
// Create an SDL event from the keypress.
2109
sdlev.key.keysym.sym = sdlkey;
2112
SDL_PushEvent(&sdlev);
2114
// Only let the emulator handle the key event if this window has the input focus.
2115
if(keystate == 0 || gtk_window_is_active(GTK_WINDOW(MainWindow)))
2117
#if SDL_VERSION_ATLEAST(1, 3, 0)
2118
SDL_GetKeyboardState(NULL)[SDL_GetScancodeFromKey(sdlkey)] = keystate;
2120
SDL_GetKeyState(NULL)[sdlkey] = keystate;
2125
// Allow GTK+ to process this key.
2129
// Our menu, in the XML markup format used by GtkUIManager
2130
static char* menuXml =
2132
" <menubar name='Menubar'>"
2133
" <menu action='FileMenuAction'>"
2134
" <menuitem action='OpenRomAction' />"
2135
" <menuitem action='CloseRomAction' />"
2137
" <menuitem action='PlayNsfAction' />"
2139
" <menuitem action='LoadStateFromAction' />"
2140
" <menuitem action='SaveStateAsAction' />"
2141
" <menuitem action='QuickLoadAction' />"
2142
" <menuitem action='QuickSaveAction' />"
2143
" <menu action='ChangeStateMenuAction'>"
2144
" <menuitem action='State0Action' />"
2145
" <menuitem action='State1Action' />"
2146
" <menuitem action='State2Action' />"
2147
" <menuitem action='State3Action' />"
2148
" <menuitem action='State4Action' />"
2149
" <menuitem action='State5Action' />"
2150
" <menuitem action='State6Action' />"
2151
" <menuitem action='State7Action' />"
2152
" <menuitem action='State8Action' />"
2153
" <menuitem action='State9Action' />"
2157
" <menuitem action='LoadLuaScriptAction' />"
2160
" <menuitem action='ScreenshotAction' />"
2162
" <menuitem action='QuitAction' />"
2164
" <menu action='OptionsMenuAction'>"
2165
" <menuitem action='GamepadConfigAction' />"
2166
" <menuitem action='HotkeyConfigAction' />"
2167
" <menuitem action='SoundConfigAction' />"
2168
" <menuitem action='VideoConfigAction' />"
2169
" <menuitem action='PaletteConfigAction' />"
2170
" <menuitem action='NetworkConfigAction' />"
2171
" <menuitem action='AutoResumeAction' />"
2173
" <menuitem action='FullscreenAction' />"
2175
" <menu action='EmulationMenuAction'>"
2176
" <menuitem action='PowerAction' />"
2177
" <menuitem action='ResetAction' />"
2178
" <menuitem action='SoftResetAction' />"
2179
" <menuitem action='PauseToggleAction' />"
2181
" <menuitem action='GameGenieToggleAction' />"
2182
" <menuitem action='LoadGameGenieAction' />"
2184
" <menuitem action='InsertCoinAction' />"
2186
" <menu action='FdsMenuAction'>"
2187
" <menuitem action='SwitchDiskAction' />"
2188
" <menuitem action='EjectDiskAction' />"
2189
" <menuitem action='LoadBiosAction' />"
2192
" <menu action='MovieMenuAction'>"
2193
" <menuitem action='OpenMovieAction' />"
2194
" <menuitem action='StopMovieAction' />"
2196
" <menuitem action='RecordMovieAction' />"
2197
" <menuitem action='RecordMovieAsAction' />"
2199
" <menu action='HelpMenuAction'>"
2200
" <menuitem action='AboutAction' />"
2205
// Menu items, as an array of GtkActionEntry structures that define each item
2206
static GtkActionEntry normal_entries[] = {
2207
{"FileMenuAction", NULL, "_File"},
2208
{"OpenRomAction", GTK_STOCK_OPEN, "_Open ROM", "<control>O", NULL, G_CALLBACK(loadGame)},
2209
{"CloseRomAction", GTK_STOCK_CLOSE, "_Close ROM", "<control>C", NULL, G_CALLBACK(closeGame)},
2210
{"PlayNsfAction", GTK_STOCK_OPEN, "_Play NSF", "<control>N", NULL, G_CALLBACK(loadNSF)},
2211
{"LoadStateFromAction", GTK_STOCK_OPEN, "Load State _From", "", NULL, G_CALLBACK(loadStateFrom)},
2212
{"SaveStateAsAction", GTK_STOCK_SAVE_AS, "Save State _As", NULL, NULL, G_CALLBACK(saveStateAs)},
2213
{"QuickLoadAction", "go-jump", "Quick _Load", "F7", NULL, G_CALLBACK(quickLoad)},
2214
{"QuickSaveAction", GTK_STOCK_SAVE, "Qu_ick Save", "F5", NULL, G_CALLBACK(quickSave)},
2215
{"ChangeStateMenuAction", NULL, "C_hange State"},
2217
{"LoadLuaScriptAction", GTK_STOCK_OPEN, "Load L_ua Script", "", NULL, G_CALLBACK(loadLua)},
2219
{"ScreenshotAction", NULL, "_Screenshot", "F12", NULL, G_CALLBACK(FCEUI_SaveSnapshot)},
2220
{"QuitAction", GTK_STOCK_QUIT, "_Quit", "<control>Q", NULL, G_CALLBACK(quit)},
2222
{"OptionsMenuAction", NULL, "_Options"},
2223
#if GTK_MAJOR_VERSION == 3 || (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 24)
2224
{"GamepadConfigAction", "input-gaming", "_Gamepad Config", NULL, NULL, G_CALLBACK(openGamepadConfig)},
2226
{"HotkeyConfigAction", "input", "_Hotkey Config", NULL, NULL, G_CALLBACK(openHotkeyConfig)},
2227
{"SoundConfigAction", "audio-x-generic", "_Sound Config", NULL, NULL, G_CALLBACK(openSoundConfig)},
2228
{"VideoConfigAction", "video-display", "_Video Config", NULL, NULL, G_CALLBACK(openVideoConfig)},
2229
{"PaletteConfigAction", GTK_STOCK_SELECT_COLOR, "_Palette Config", NULL, NULL, G_CALLBACK(openPaletteConfig)},
2230
{"NetworkConfigAction", GTK_STOCK_NETWORK, "_Network Config", NULL, NULL, G_CALLBACK(openNetworkConfig)},
2231
{"FullscreenAction", GTK_STOCK_FULLSCREEN, "_Fullscreen", "<alt>Return", NULL, G_CALLBACK(enableFullscreen)},
2232
{"EmulationMenuAction", NULL, "_Emulation"},
2233
{"PowerAction", NULL, "P_ower", NULL, NULL, G_CALLBACK(FCEUI_PowerNES)},
2234
{"SoftResetAction", GTK_STOCK_REFRESH, "_Soft Reset", NULL, NULL, G_CALLBACK(emuReset)},
2235
{"ResetAction", GTK_STOCK_REFRESH, "_Reset", NULL, NULL, G_CALLBACK(hardReset)},
2236
{"PauseToggleAction", GTK_STOCK_MEDIA_PAUSE, "_Pause", "Pause", NULL, G_CALLBACK(togglePause)},
2237
{"FdsMenuAction", GTK_STOCK_FLOPPY, "_FDS"},
2238
{"SwitchDiskAction", "go-jump", "_Switch Disk", NULL, NULL, G_CALLBACK(FCEU_FDSSelect)},
2239
{"EjectDiskAction", "media-eject", "_Eject Disk", NULL, NULL, G_CALLBACK(FCEU_FDSInsert)},
2240
{"LoadBiosAction", GTK_STOCK_OPEN, "Load _BIOS File", "", NULL, G_CALLBACK(loadFdsBios)},
2241
{"LoadGameGenieAction", GTK_STOCK_OPEN, "_Load Game Genie ROM", "", NULL, G_CALLBACK(loadGameGenie)},
2242
{"InsertCoinAction", NULL, "_Insert Coin", NULL, NULL, G_CALLBACK(FCEUI_VSUniCoin)},
2244
{"MovieMenuAction", NULL, "_Movie"},
2245
{"OpenMovieAction", GTK_STOCK_OPEN, "_Open", "<shift>F7", NULL, G_CALLBACK(loadMovie)},
2246
{"StopMovieAction", GTK_STOCK_MEDIA_STOP, "S_top", NULL, NULL, G_CALLBACK(FCEUI_StopMovie)},
2247
{"RecordMovieAction", GTK_STOCK_MEDIA_RECORD, "_Record", "<shift>F5", NULL, G_CALLBACK(recordMovie)},
2248
{"RecordMovieAsAction", NULL, "Record _As", NULL, NULL, G_CALLBACK(recordMovieAs)},
2250
{"HelpMenuAction", NULL, "_Help"},
2251
{"AboutAction", GTK_STOCK_ABOUT, "_About", NULL, NULL, G_CALLBACK(openAbout)},
2254
// Menu items with a check box that can be toggled on or off
2255
static GtkToggleActionEntry toggle_entries[] = {
2256
{"GameGenieToggleAction", NULL, "Enable Game _Genie", NULL, NULL, G_CALLBACK(toggleGameGenie), FALSE},
2257
{"AutoResumeAction", NULL, "Auto-Resume Play", NULL, NULL, G_CALLBACK(toggleAutoResume), FALSE},
2260
// Menu items for selecting a save state slot using radio buttons
2261
static GtkRadioActionEntry radio_entries[] = {
2262
{"State0Action", NULL, "0", NULL, NULL, 0},
2263
{"State1Action", NULL, "1", NULL, NULL, 1},
2264
{"State2Action", NULL, "2", NULL, NULL, 2},
2265
{"State3Action", NULL, "3", NULL, NULL, 3},
2266
{"State4Action", NULL, "4", NULL, NULL, 4},
2267
{"State5Action", NULL, "5", NULL, NULL, 5},
2268
{"State6Action", NULL, "6", NULL, NULL, 6},
2269
{"State7Action", NULL, "7", NULL, NULL, 7},
2270
{"State8Action", NULL, "8", NULL, NULL, 8},
2271
{"State9Action", NULL, "9", NULL, NULL, 9},
2274
static GtkWidget* CreateMenubar( GtkWidget* window)
2276
GtkUIManager *ui_manager;
2277
GtkActionGroup *action_group;
2278
GtkAccelGroup* accel_group;
2279
GError *error = NULL;
2282
/* Make an UIManager (which makes a menubar). */
2283
ui_manager = gtk_ui_manager_new ();
2285
/* Add the menu items to the UIManager as a GtkActionGroup. */
2286
action_group = gtk_action_group_new ("MenubarActions");
2287
gtk_action_group_add_actions (action_group, normal_entries, G_N_ELEMENTS (normal_entries), NULL);
2288
gtk_action_group_add_toggle_actions (action_group, toggle_entries, G_N_ELEMENTS (toggle_entries), NULL);
2289
gtk_action_group_add_radio_actions (action_group, radio_entries, G_N_ELEMENTS (radio_entries), 0, G_CALLBACK(changeState), NULL);
2290
gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
2292
/* Read the menu layout from the XML markup. */
2293
gtk_ui_manager_add_ui_from_string (ui_manager, menuXml, -1, &error);
2296
fprintf (stderr, "Unable to create menu bar: %s\n", error->message);
2297
g_error_free (error);
2300
/* Attach the new accelerator group to the window. */
2301
accel_group = gtk_ui_manager_get_accel_group (ui_manager);
2302
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
2304
/* Get an action that can be used to change the active state slot selection. */
2305
state = gtk_action_group_get_action (action_group, "State0Action");
2306
if (state && GTK_IS_RADIO_ACTION (state))
2307
stateSlot = GTK_RADIO_ACTION (state);
2309
/* Set the autoResume checkbox */
2310
GtkCheckMenuItem* auto_resume_chk = (GtkCheckMenuItem*) gtk_ui_manager_get_widget ( ui_manager, "/Menubar/OptionsMenuAction/AutoResumeAction");
2311
gtk_check_menu_item_set_active (auto_resume_chk, (bool)AutoResumePlay);
2313
/* Finally, return the actual menu bar created by the UIManager. */
2314
return gtk_ui_manager_get_widget (ui_manager, "/Menubar");
2318
void pushOutputToGTK(const char* str)
2320
// we don't really do anything with the output right now
2324
void showGui(bool b)
2327
gtk_widget_show_all(MainWindow);
2329
gtk_widget_hide(MainWindow);
2332
int GtkMouseData[3] = {0,0,0};
2334
gint handleMouseClick(GtkWidget* widget, GdkEvent *event, gpointer callback_data)
2336
GtkMouseData[0] = ((GdkEventButton*)event)->x;
2337
GtkMouseData[1] = ((GdkEventButton*)event)->y;
2338
int button = ((GdkEventButton*)event)->button;
2339
if(!(((GdkEventButton*)event)->type == GDK_BUTTON_PRESS))
2340
GtkMouseData[2] = 0;
2344
GtkMouseData[2] |= 0x1;
2346
GtkMouseData[2] |= 0x3;
2349
// this doesn't work because we poll the mouse position rather
2353
sdlev.type = SDL_MOUSEBUTTONDOWN;
2354
if(((GdkEventButton*)event)->type == GDK_BUTTON_PRESS)
2355
sdlev.button.type = SDL_MOUSEBUTTONDOWN;
2357
sdlev.button.type = SDL_MOUSEBUTTONUP;
2358
sdlev.button.button = ((GdkEventButton*)event)->button;
2359
sdlev.button.state = ((GdkEventButton*)event)->state;
2360
sdlev.button.x = ((GdkEventButton*)event)->x;
2361
sdlev.button.y = ((GdkEventButton*)event)->y;
2363
SDL_PushEvent(&sdlev);
2368
// NES resolution = 256x240
2369
const int NES_WIDTH=256;
2370
const int NES_HEIGHT=240;
2372
void handle_resize(GtkWindow* win, GdkEvent* event, gpointer data)
2374
// TODO this is a stub atm
2375
// this should handle resizing so the emulation takes up as much
2376
// of the GTK window as possible
2379
// get new window width/height
2381
width = event->configure.width;
2382
height = event->configure.height;
2383
printf("DEBUG: new window size: %dx%d\n", width, height);
2385
// get width/height multipliers
2386
double xscale = width / (double)NES_WIDTH;
2387
double yscale = height / (double)NES_HEIGHT;
2389
// TODO check KeepRatio (where is this)
2390
// do this to keep aspect ratio
2396
//TODO if openGL make these integers
2397
g_config->setOption("SDL.XScale", xscale);
2398
g_config->setOption("SDL.YScale", yscale);
2399
//gtk_widget_realize(evbox);
2404
InitVideo(GameInfo);
2406
gtk_widget_set_size_request(evbox, (int)(NES_WIDTH*xscale), (int)(NES_HEIGHT*yscale));
2411
// gtk_widget_modify_bg(GTK_WIDGET(win), GTK_STATE_NORMAL, &black);
2413
printf("DEBUG: new xscale: %f yscale: %f\n", xscale, yscale);
2418
int InitGTKSubsystem(int argc, char** argv)
2423
MainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
2424
// gtk_window_set_policy (GTK_WINDOW (MainWindow), FALSE, FALSE, TRUE);
2425
gtk_window_set_resizable(GTK_WINDOW(MainWindow), TRUE);
2426
gtk_window_set_title(GTK_WINDOW(MainWindow), FCEU_NAME_AND_VERSION);
2427
gtk_window_set_default_size(GTK_WINDOW(MainWindow), NES_WIDTH, NES_HEIGHT);
2429
GdkPixbuf* icon = gdk_pixbuf_new_from_xpm_data(icon_xpm);
2430
gtk_window_set_default_icon(icon);
2431
gtk_window_set_icon(GTK_WINDOW(MainWindow), icon);
2433
vbox = gtk_vbox_new(FALSE, 0);
2434
gtk_container_add(GTK_CONTAINER(MainWindow), vbox);
2436
Menubar = CreateMenubar(MainWindow);
2437
// turn of game genie by default, since its off by default in the menu
2440
gtk_box_pack_start (GTK_BOX(vbox), Menubar, FALSE, TRUE, 0);
2442
// PRG: this code here is the the windowID "hack" to render SDL
2443
// in a GTK window. however, I can't get it to work right now
2444
// so i'm commenting it out and haivng a seperate GTK2 window with
2448
// uncommented and fixed by Bryan Cain
2451
// prg - Bryan Cain, you are the man!
2453
evbox = gtk_event_box_new();
2454
gtk_box_pack_start (GTK_BOX(vbox), evbox, TRUE, TRUE, 0);
2456
double xscale, yscale;
2457
g_config->getOption("SDL.XScale", &xscale);
2458
g_config->getOption("SDL.YScale", &yscale);
2460
gtk_widget_set_size_request(evbox, NES_WIDTH*xscale, NES_HEIGHT*yscale);
2461
gtk_widget_realize(evbox);
2462
gtk_widget_show(evbox);
2463
gtk_widget_show_all(vbox);
2465
GdkColor bg = {0, 0, 0, 0};
2466
gtk_widget_modify_bg(evbox, GTK_STATE_NORMAL, &bg);
2468
// set up keypress "snooper" to convert GDK keypress events into SDL keypresses
2469
gtk_key_snooper_install(convertKeypress, NULL);
2471
// pass along mouse data from GTK to SDL
2472
g_signal_connect(G_OBJECT(evbox), "button-press-event", G_CALLBACK(handleMouseClick), NULL);
2473
g_signal_connect(G_OBJECT(evbox), "button-release-event", G_CALLBACK(handleMouseClick), NULL);
2477
g_signal_connect(MainWindow, "delete-event", quit, NULL);
2478
g_signal_connect(MainWindow, "destroy-event", quit, NULL);
2480
// g_signal_connect(MainWindow, "configure-event", G_CALLBACK(handle_resize), NULL);
2482
gtk_widget_show_all(MainWindow);
2485
gtk_widget_size_request(GTK_WIDGET(MainWindow), &req);
2486
gtk_window_resize(GTK_WINDOW(MainWindow), req.width, req.height);
2487
gtkIsStarted = true;