~ubuntu-branches/ubuntu/utopic/fceux/utopic

« back to all changes in this revision

Viewing changes to .pc/set-script-and-palette-gtkfilechooser-default-directory.patch/src/drivers/sdl/gui.cpp

  • Committer: Package Import Robot
  • Author(s): Joe Nahmias
  • Date: 2014-03-02 19:22:04 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20140302192204-9f0aehi5stfnhn7d
Tags: 2.2.2+dfsg0-1
* Imported Upstream version 2.2.2
  + remove patches merged upstream; refresh remaining
  + remove windows compiled help files and non-free Visual C files
* Use C++11 standard static assertion functionality
* fix upstream installation of support files
* New patch 0004-ignore-missing-windows-help-CHM-file.patch
* update d/copyright for new, renamed, deleted files
* d/control: bump std-ver to 3.9.5, no changes needed

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <gtk/gtk.h>
2
 
#include <gdk/gdkkeysyms.h>
3
 
#include <gdk/gdkx.h>
4
 
 
5
 
#ifdef _GTK3
6
 
#include <gdk/gdkkeysyms-compat.h>
7
 
#endif
8
 
 
9
 
#include <fstream>
10
 
#include <iostream>
11
 
#include <cstdlib>
12
 
 
13
 
#include <SDL/SDL.h>
14
 
 
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"
23
 
 
24
 
#include "sdl.h"
25
 
#include "gui.h"
26
 
#include "dface.h"
27
 
#include "input.h"
28
 
#include "config.h"
29
 
#include "icon.xpm"
30
 
 
31
 
#ifdef _S9XLUA_H
32
 
#include "../../fceulua.h"
33
 
#endif
34
 
 
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
41
 
#endif
42
 
 
43
 
void toggleSound(GtkWidget* check, gpointer data);
44
 
void loadGame ();
45
 
void closeGame();
46
 
extern Config *g_config;
47
 
 
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;
55
 
 
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)
59
 
{
60
 
        int major = GTK_MAJOR_VERSION;
61
 
        int minor = GTK_MINOR_VERSION;
62
 
 
63
 
        if(major > major_required)
64
 
        {
65
 
                return true;
66
 
        } else if (major == major_required)
67
 
        {
68
 
                if(minor >= minor_required)
69
 
                {
70
 
                        return true;
71
 
                }
72
 
                else
73
 
                {
74
 
                        return false;
75
 
                }
76
 
        } else
77
 
        {
78
 
                return false;
79
 
        }
80
 
}
81
 
 
82
 
// This function configures a single hotkey
83
 
int configHotkey(char* hotkeyString)
84
 
{
85
 
        SDL_Surface *screen;
86
 
        SDL_Event event;
87
 
        KillVideo();
88
 
        screen = SDL_SetVideoMode(420, 200, 8, 0);
89
 
        //SDL_WM_SetCaption("Press a key to bind...", 0);
90
 
 
91
 
        int newkey = 0;
92
 
        while(1)
93
 
        {
94
 
                SDL_WaitEvent(&event);
95
 
        
96
 
                switch (event.type)
97
 
                {
98
 
                        case SDL_KEYDOWN:
99
 
                                newkey = event.key.keysym.sym;
100
 
                                g_config->setOption(hotkeyString, newkey);
101
 
                                extern FCEUGI *GameInfo;
102
 
                                InitVideo(GameInfo);
103
 
                                return 0;
104
 
                }
105
 
        }       
106
 
        
107
 
        return 0;
108
 
}
109
 
// This function configures a single button on a gamepad
110
 
int configGamepadButton(GtkButton* button, gpointer p)
111
 
{
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;
116
 
                
117
 
        char buf[256];
118
 
        std::string prefix;
119
 
    
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)))
122
 
                return 0;
123
 
    
124
 
        ButtonConfigBegin();
125
 
    
126
 
        snprintf(buf, sizeof(buf), "SDL.Input.GamePad.%d", padNo);
127
 
        prefix = buf;
128
 
        DWaitButton(NULL, &GamePadConfig[padNo][x], configNo);
129
 
 
130
 
        g_config->setOption(prefix + GamePadNames[x], GamePadConfig[padNo][x].ButtonNum[configNo]);
131
 
 
132
 
        if(GamePadConfig[padNo][x].ButtType[0] == BUTTC_KEYBOARD)
133
 
        {
134
 
                g_config->setOption(prefix + "DeviceType", "Keyboard");
135
 
        } else if(GamePadConfig[padNo][x].ButtType[0] == BUTTC_JOYSTICK) {
136
 
                g_config->setOption(prefix + "DeviceType", "Joystick");
137
 
        } else {
138
 
                g_config->setOption(prefix + "DeviceType", "Unknown");
139
 
        }
140
 
        g_config->setOption(prefix + "DeviceNum", GamePadConfig[padNo][x].DeviceNum[configNo]);
141
 
    
142
 
        snprintf(buf, sizeof(buf), "<tt>%s</tt>", ButtonName(&GamePadConfig[padNo][x], configNo));
143
 
        gtk_label_set_markup(GTK_LABEL(buttonMappings[x]), buf);
144
 
 
145
 
        ButtonConfigEnd();
146
 
    
147
 
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
148
 
    
149
 
        return 0;
150
 
}
151
 
 
152
 
void resetVideo()
153
 
{
154
 
        KillVideo();
155
 
        InitVideo(GameInfo);
156
 
}
157
 
 
158
 
void closeVideoWin(GtkWidget* w, GdkEvent* e, gpointer p)
159
 
{
160
 
        resetVideo();
161
 
        gtk_widget_destroy(w);
162
 
}
163
 
 
164
 
void closeDialog(GtkWidget* w, GdkEvent* e, gpointer p)
165
 
{
166
 
        gtk_widget_destroy(w);
167
 
}
168
 
void toggleLowPass(GtkWidget* w, gpointer p)
169
 
{
170
 
        if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
171
 
        {
172
 
                g_config->setOption("SDL.Sound.LowPass", 1);
173
 
                FCEUI_SetLowPass(1);
174
 
        }
175
 
        else
176
 
        {
177
 
                g_config->setOption("SDL.Sound.LowPass", 0);
178
 
                FCEUI_SetLowPass(0);
179
 
        }
180
 
        g_config->save();
181
 
}
182
 
 
183
 
// Wrapper for pushing GTK options into the config file
184
 
// p : pointer to the string that names the config option
185
 
// w : toggle widget
186
 
void toggleOption(GtkWidget* w, gpointer p)
187
 
{
188
 
        if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
189
 
                g_config->setOption((char*)p, 1);
190
 
        else
191
 
                g_config->setOption((char*)p, 0);
192
 
        
193
 
        g_config->save();
194
 
        UpdateEMUCore(g_config);
195
 
}
196
 
 
197
 
int setTint(GtkWidget* w, gpointer p)
198
 
{
199
 
        int v = gtk_range_get_value(GTK_RANGE(w));
200
 
        g_config->setOption("SDL.Tint", v);
201
 
        g_config->save();
202
 
        int c, h;
203
 
        g_config->getOption("SDL.NTSCpalette", &c);
204
 
        g_config->getOption("SDL.Hue", &h);
205
 
        FCEUI_SetNTSCTH(c, v, h);
206
 
        
207
 
        return 0;
208
 
}
209
 
int setHue(GtkWidget* w, gpointer p)
210
 
{
211
 
        int v = gtk_range_get_value(GTK_RANGE(w));
212
 
        g_config->setOption("SDL.Hue", v);
213
 
        g_config->save();
214
 
        int c, t;
215
 
        g_config->getOption("SDL.Tint", &t);
216
 
        g_config->getOption("SDL.SDL.NTSCpalette", &c);
217
 
        FCEUI_SetNTSCTH(c, t, v);
218
 
        
219
 
        return 0;
220
 
}
221
 
void loadPalette (GtkWidget* w, gpointer p)
222
 
{
223
 
        GtkWidget* fileChooser;
224
 
        
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));
229
 
 
230
 
        if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
231
 
        {
232
 
                char* filename;
233
 
                
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);
238
 
                
239
 
                gtk_entry_set_text(GTK_ENTRY(p), filename);
240
 
                
241
 
        }
242
 
        gtk_widget_destroy (fileChooser);
243
 
}
244
 
 
245
 
void clearPalette(GtkWidget* w, gpointer p)
246
 
{
247
 
        g_config->setOption("SDL.Palette", 0);
248
 
        gtk_entry_set_text(GTK_ENTRY(p), "");
249
 
}
250
 
 
251
 
void openPaletteConfig()
252
 
{
253
 
        GtkWidget* win;
254
 
        GtkWidget* vbox;
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;
265
 
        GtkWidget* hueFrame;
266
 
        GtkWidget* hueHscale;
267
 
        
268
 
        win = gtk_dialog_new_with_buttons("Palette Options",
269
 
                                                                          GTK_WINDOW(MainWindow),
270
 
                                                                          (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT),
271
 
                                                                          GTK_STOCK_CLOSE,
272
 
                                                                          GTK_RESPONSE_OK,
273
 
                                                                          NULL);
274
 
        gtk_window_set_icon_name(GTK_WINDOW(win), GTK_STOCK_SELECT_COLOR);
275
 
        vbox = gtk_dialog_get_content_area(GTK_DIALOG(win));
276
 
        
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);
285
 
        
286
 
        clearButton = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
287
 
        
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);
291
 
        
292
 
        g_signal_connect(paletteButton, "clicked", G_CALLBACK(loadPalette), paletteEntry);
293
 
        g_signal_connect(clearButton, "clicked", G_CALLBACK(clearPalette), paletteEntry);
294
 
        
295
 
        // sync with config
296
 
        std::string fn;
297
 
        g_config->getOption("SDL.Palette", &fn);
298
 
        gtk_entry_set_text(GTK_ENTRY(paletteEntry), fn.c_str());
299
 
        
300
 
        // ntsc color check
301
 
        ntscColorChk = gtk_check_button_new_with_label("Use NTSC palette");
302
 
        
303
 
        g_signal_connect(ntscColorChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.NTSCpalette");
304
 
        
305
 
        int b;
306
 
        // sync with config
307
 
        g_config->getOption("SDL.NTSCpalette", &b);
308
 
        if(b)
309
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ntscColorChk), 1);
310
 
        else
311
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ntscColorChk), 0);
312
 
 
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);
322
 
        
323
 
        g_signal_connect(tintHscale, "button-release-event", G_CALLBACK(setTint), NULL);
324
 
        g_signal_connect(hueHscale, "button-release-event", G_CALLBACK(setHue), NULL);
325
 
        
326
 
        // sync with config
327
 
        int h, t;
328
 
        g_config->getOption("SDL.Hue", &h);
329
 
        g_config->getOption("SDL.Tint", &t);
330
 
 
331
 
        gtk_range_set_value(GTK_RANGE(hueHscale), h);
332
 
        gtk_range_set_value(GTK_RANGE(tintHscale), t);
333
 
        
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);
338
 
        
339
 
        gtk_box_pack_start(GTK_BOX(vbox), paletteFrame, FALSE, TRUE, 5);
340
 
        gtk_box_pack_start(GTK_BOX(vbox), slidersFrame, FALSE, TRUE, 5);
341
 
        
342
 
        g_signal_connect(win, "delete-event", G_CALLBACK(closeDialog), NULL);
343
 
        g_signal_connect(win, "response", G_CALLBACK(closeDialog), NULL);
344
 
        
345
 
        gtk_widget_show_all(win);
346
 
        
347
 
        return;
348
 
}
349
 
 
350
 
 
351
 
GtkWidget* ipEntry;
352
 
GtkWidget* portSpin;
353
 
GtkWidget* pwEntry;
354
 
 
355
 
void launchNet(GtkWidget* w, gpointer p)
356
 
{
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));
360
 
        
361
 
        g_config->setOption("SDL.NetworkIP", ip);
362
 
        g_config->setOption("SDL.NetworkPassword", pw);
363
 
        g_config->setOption("SDL.NetworkPort", port);
364
 
        
365
 
        gtk_widget_destroy(GTK_WIDGET(w));
366
 
        
367
 
        loadGame();
368
 
}
369
 
 
370
 
void setUsername(GtkWidget* w, gpointer p)
371
 
{
372
 
        char* s = (char*)gtk_entry_get_text(GTK_ENTRY(w));
373
 
        g_config->setOption("SDL.NetworkUsername", s);
374
 
}
375
 
 
376
 
void netResponse(GtkWidget* w, gint response_id, gpointer p)
377
 
{
378
 
        if(response_id == GTK_RESPONSE_OK)
379
 
                launchNet(w, p);
380
 
        else
381
 
                gtk_widget_destroy(w);
382
 
}
383
 
 
384
 
void openNetworkConfig()
385
 
{
386
 
        GtkWidget* win;
387
 
        GtkWidget* box;
388
 
        GtkWidget* userBox;
389
 
        GtkWidget* userEntry;
390
 
        GtkWidget* userLbl;
391
 
        GtkWidget* frame;
392
 
        GtkWidget* vbox;
393
 
        GtkWidget* ipBox;
394
 
        GtkWidget* ipLbl;
395
 
        
396
 
        GtkWidget* portBox;
397
 
        GtkWidget* portLbl;
398
 
        
399
 
        //GtkWidget* localPlayersCbo;
400
 
        GtkWidget* pwBox;
401
 
        GtkWidget* pwLbl;
402
 
        
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));
406
 
        
407
 
        userBox = gtk_hbox_new(FALSE, 3);
408
 
        userLbl = gtk_label_new("Username:");
409
 
        userEntry = gtk_entry_new();
410
 
        std::string s;
411
 
        g_config->getOption("SDL.NetworkUsername", &s);
412
 
        gtk_entry_set_text(GTK_ENTRY(userEntry), s.c_str());
413
 
        
414
 
        g_signal_connect(userEntry, "changed", G_CALLBACK(setUsername), NULL);
415
 
 
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();
428
 
        
429
 
        gtk_spin_button_set_value(GTK_SPIN_BUTTON(portSpin), 4046);
430
 
        
431
 
        gtk_box_pack_start(GTK_BOX(userBox), userLbl, FALSE, FALSE, 3);
432
 
        gtk_box_pack_start(GTK_BOX(userBox), userEntry, TRUE , TRUE, 3);
433
 
        
434
 
        gtk_box_pack_start(GTK_BOX(portBox), portLbl, FALSE, FALSE, 3);
435
 
        gtk_box_pack_start(GTK_BOX(portBox), portSpin, FALSE , FALSE, 3);
436
 
        
437
 
        gtk_box_pack_start(GTK_BOX(ipBox), ipLbl, FALSE, FALSE, 3);
438
 
        gtk_box_pack_start(GTK_BOX(ipBox), ipEntry, TRUE , TRUE, 3);
439
 
        
440
 
        gtk_box_pack_start(GTK_BOX(pwBox), pwLbl, FALSE, FALSE, 3);
441
 
        gtk_box_pack_start(GTK_BOX(pwBox), pwEntry, TRUE , TRUE, 3);
442
 
        
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);
447
 
        
448
 
        gtk_container_add(GTK_CONTAINER(frame), vbox);
449
 
        
450
 
        gtk_box_pack_start(GTK_BOX(box), userBox, TRUE, TRUE, 0);
451
 
        gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 0);
452
 
        
453
 
        gtk_widget_show_all(win);
454
 
        
455
 
        g_signal_connect(win, "delete-event", G_CALLBACK(closeDialog), NULL);
456
 
        g_signal_connect(win, "response", G_CALLBACK(netResponse), NULL);
457
 
}
458
 
 
459
 
// handler prototype
460
 
static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data);
461
 
 
462
 
void flushGtkEvents()
463
 
{
464
 
        while (gtk_events_pending ())
465
 
                gtk_main_iteration_do (FALSE);
466
 
 
467
 
        return;
468
 
}
469
 
 
470
 
GtkWidget* HotkeyWin;
471
 
 
472
 
// creates and opens hotkey config window
473
 
void openHotkeyConfig()
474
 
{
475
 
        enum
476
 
        {
477
 
                COMMAND_COLUMN,
478
 
                KEY_COLUMN,
479
 
                N_COLUMNS
480
 
        };
481
 
        GtkWidget* win = gtk_dialog_new_with_buttons("Hotkey Configuration",
482
 
                        GTK_WINDOW(MainWindow), (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT),
483
 
                        GTK_STOCK_CLOSE,
484
 
                        GTK_RESPONSE_OK,
485
 
                        NULL);
486
 
        gtk_window_set_default_size(GTK_WINDOW(win), 400, 800);
487
 
        HotkeyWin = win;
488
 
        GtkWidget *tree;
489
 
        GtkWidget *vbox;
490
 
        GtkWidget *scroll;
491
 
 
492
 
 
493
 
 
494
 
        vbox = gtk_dialog_get_content_area(GTK_DIALOG(win));
495
 
        
496
 
        GtkTreeStore *hotkey_store = gtk_tree_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
497
 
 
498
 
        std::string prefix = "SDL.Hotkeys.";
499
 
    GtkTreeIter iter; // parent
500
 
    GtkTreeIter iter2; // child
501
 
    
502
 
    gtk_tree_store_append(hotkey_store, &iter, NULL); // aquire iter
503
 
     
504
 
    int keycode;
505
 
    for(int i=0; i<HK_MAX; i++)
506
 
    {
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),
512
 
                -1);
513
 
        gtk_tree_store_append(hotkey_store, &iter, NULL); // acquire child     iterator
514
 
    }                      
515
 
 
516
 
        tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(hotkey_store));
517
 
        GtkCellRenderer *renderer;
518
 
        GtkTreeViewColumn* column;
519
 
 
520
 
        
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);
532
 
 
533
 
        g_signal_connect(win, "delete-event", G_CALLBACK(closeDialog), NULL);
534
 
    g_signal_connect(win, "response", G_CALLBACK(closeDialog), NULL);
535
 
 
536
 
        GtkTreeSelection *select;
537
 
 
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),
541
 
                        NULL);
542
 
        gtk_tree_selection_unselect_all (select);
543
 
}
544
 
 
545
 
static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data)
546
 
{
547
 
        GtkTreeIter iter;
548
 
        GtkTreeModel *model;
549
 
        char* hotkey;
550
 
 
551
 
        if (gtk_tree_selection_get_selected (selection, &model, &iter))
552
 
        {
553
 
                gtk_tree_model_get (model, &iter, 0, &hotkey, -1);
554
 
 
555
 
                gtk_widget_hide(HotkeyWin);
556
 
 
557
 
                flushGtkEvents();
558
 
 
559
 
                configHotkey(hotkey);
560
 
 
561
 
                g_signal_emit_by_name(HotkeyWin, "destroy-event");
562
 
 
563
 
                openHotkeyConfig();
564
 
 
565
 
                g_free (hotkey);
566
 
 
567
 
        }
568
 
}
569
 
 
570
 
GtkWidget*      typeCombo;
571
 
 
572
 
// TODO: finish this
573
 
int setInputDevice(GtkWidget* w, gpointer p)
574
 
{
575
 
        std::string s = "SDL.Input.";
576
 
        s = s + (char*)p;
577
 
        printf("%s", s.c_str());
578
 
        g_config->setOption(s, gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(typeCombo)));
579
 
        g_config->save();
580
 
        
581
 
        return 1;
582
 
}
583
 
 
584
 
void updateGamepadConfig(GtkWidget* w, gpointer p)
585
 
{
586
 
        int i;
587
 
        char strBuf[128];
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;
590
 
        
591
 
        for(i=0; i<10; i++)
592
 
        {
593
 
                GtkWidget* mappedKey = buttonMappings[i];
594
 
                if(GamePadConfig[padNo][i].ButtType[configNo] == BUTTC_KEYBOARD)
595
 
                {
596
 
                        snprintf(strBuf, sizeof(strBuf), "<tt>%s</tt>", 
597
 
                                        SDL_GetKeyName((SDLKey)GamePadConfig[padNo][i].ButtonNum[configNo]));
598
 
                }
599
 
                else // FIXME: display joystick button/hat/axis names properly
600
 
                        strncpy(strBuf, "<tt>Joystick</tt>", sizeof(strBuf));
601
 
        
602
 
                gtk_label_set_text(GTK_LABEL(mappedKey), strBuf);
603
 
                gtk_label_set_use_markup(GTK_LABEL(mappedKey), TRUE);
604
 
        }
605
 
}
606
 
 
607
 
// creates and opens the gamepad config window (requires GTK 2.24)
608
 
void openGamepadConfig()
609
 
{
610
 
        // GTK 2.24 required for this dialog
611
 
        if (checkGTKVersion(2, 24) == false)
612
 
        {
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");
615
 
                return;
616
 
        }
617
 
 
618
 
        GtkWidget* win;
619
 
        GtkWidget* vbox;
620
 
        GtkWidget* hboxPadNo;
621
 
        GtkWidget* padNoLabel;
622
 
        GtkWidget* configNoLabel;
623
 
        GtkWidget* fourScoreChk;
624
 
        GtkWidget* oppositeDirChk;
625
 
        GtkWidget* buttonFrame;
626
 
        GtkWidget* buttonTable;
627
 
        
628
 
        win = gtk_dialog_new_with_buttons("Controller Configuration",
629
 
                                                                          GTK_WINDOW(MainWindow),
630
 
                                                                          (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT),
631
 
                                                                          GTK_STOCK_CLOSE,
632
 
                                                                          GTK_RESPONSE_OK,
633
 
                                                                          NULL);
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);
637
 
        
638
 
        vbox = gtk_dialog_get_content_area(GTK_DIALOG(win));
639
 
        gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
640
 
        
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");
646
 
        
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");
653
 
        
654
 
        gtk_combo_box_set_active(GTK_COMBO_BOX(typeCombo), 0);
655
 
        
656
 
        
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);
664
 
        
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);
672
 
        
673
 
        
674
 
        g_signal_connect(typeCombo, "changed", G_CALLBACK(setInputDevice), 
675
 
                gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(typeCombo)));
676
 
        
677
 
        // sync with config
678
 
        int buf = 0;
679
 
        g_config->getOption("SDL.FourScore", &buf);
680
 
        if(buf)
681
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fourScoreChk), 1);
682
 
        else
683
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fourScoreChk), 0);
684
 
        g_config->getOption("SDL.Input.EnableOppositeDirectionals", &buf);
685
 
        if(buf)
686
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(oppositeDirChk), 1);
687
 
        else
688
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(oppositeDirChk), 0);
689
 
        
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");
692
 
        
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);
699
 
        
700
 
        gtk_box_pack_start(GTK_BOX(vbox), fourScoreChk, FALSE, TRUE, 5);
701
 
        gtk_box_pack_start(GTK_BOX(vbox), oppositeDirChk, FALSE, TRUE, 5);
702
 
        
703
 
        
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++)
711
 
        {
712
 
                GtkWidget* buttonName = gtk_label_new(GamePadNames[i]);
713
 
                GtkWidget* mappedKey = gtk_label_new(NULL);
714
 
                GtkWidget* changeButton = gtk_toggle_button_new();
715
 
                char strBuf[128];
716
 
                
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);
720
 
                
721
 
                gtk_misc_set_alignment(GTK_MISC(mappedKey), 0.0, 0.5);
722
 
                
723
 
                gtk_button_set_label(GTK_BUTTON(changeButton), "Change");
724
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(changeButton), FALSE);
725
 
                
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);
731
 
                
732
 
                g_signal_connect(changeButton, "clicked", G_CALLBACK(configGamepadButton), GINT_TO_POINTER(i));
733
 
                buttonMappings[i] = mappedKey;
734
 
        }
735
 
        
736
 
        // display the button mappings for the currently selected configuration
737
 
        updateGamepadConfig(NULL, NULL);
738
 
        
739
 
        gtk_box_pack_start(GTK_BOX(vbox), buttonFrame, TRUE, TRUE, 5);
740
 
        
741
 
        g_signal_connect(win, "delete-event", G_CALLBACK(closeDialog), NULL);
742
 
        g_signal_connect(win, "response", G_CALLBACK(closeDialog), NULL);
743
 
        
744
 
        gtk_widget_show_all(win);
745
 
        
746
 
        return;
747
 
}
748
 
 
749
 
int setBufSize(GtkWidget* w, gpointer p)
750
 
{
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
754
 
        KillSound();
755
 
        InitSound();
756
 
        return false;
757
 
}
758
 
 
759
 
void setRate(GtkWidget* w, gpointer p)
760
 
{
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
764
 
        KillSound();
765
 
        InitSound();
766
 
        g_config->save();       
767
 
        return;
768
 
}
769
 
 
770
 
void setQuality(GtkWidget* w, gpointer p)
771
 
{
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
780
 
        KillSound();
781
 
        InitSound();
782
 
        g_config->save();       
783
 
        return;
784
 
}
785
 
 
786
 
void resizeGtkWindow()
787
 
{
788
 
        if(GameInfo == 0)
789
 
        {
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);
794
 
                GtkRequisition req;
795
 
                gtk_widget_size_request(GTK_WIDGET(MainWindow), &req);
796
 
                gtk_window_resize(GTK_WINDOW(MainWindow), req.width, req.height);
797
 
        }
798
 
        return;
799
 
}
800
 
 
801
 
void setScaler(GtkWidget* w, gpointer p)
802
 
{
803
 
        int x = gtk_combo_box_get_active(GTK_COMBO_BOX(w));
804
 
        g_config->setOption("SDL.SpecialFilter", x);
805
 
        
806
 
        // 1 - hq2x 2 - Scale2x 3 - NTSC2x 4 - hq3x  5 - Scale3x
807
 
        if (x >= 1 && x <= 3)
808
 
        {
809
 
                g_config->setOption("SDL.XScale", 2.0);
810
 
                g_config->setOption("SDL.YScale", 2.0);
811
 
                resizeGtkWindow();
812
 
        }
813
 
        if (x >= 4 && x < 6)
814
 
        {
815
 
                g_config->setOption("SDL.XScale", 3.0);
816
 
                g_config->setOption("SDL.YScale", 3.0);
817
 
                resizeGtkWindow();
818
 
        }
819
 
        g_config->save();
820
 
        
821
 
}
822
 
 
823
 
 
824
 
int setXscale(GtkWidget* w, gpointer p)
825
 
{
826
 
        double v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
827
 
        g_config->setOption("SDL.XScale", v);
828
 
        g_config->save();
829
 
        resizeGtkWindow();
830
 
        return 0;
831
 
}
832
 
 
833
 
int setYscale(GtkWidget* w, gpointer p)
834
 
{
835
 
        double v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
836
 
        g_config->setOption("SDL.YScale", v);
837
 
        g_config->save();
838
 
        resizeGtkWindow();
839
 
        return 0;
840
 
}
841
 
 
842
 
#ifdef OPENGL
843
 
void setGl(GtkWidget* w, gpointer p)
844
 
{
845
 
        if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
846
 
                g_config->setOption("SDL.OpenGL", 1);
847
 
        else
848
 
                g_config->setOption("SDL.OpenGL", 0);
849
 
        g_config->save();
850
 
}
851
 
 
852
 
void setDoubleBuffering(GtkWidget* w, gpointer p)
853
 
{
854
 
        if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
855
 
                g_config->setOption("SDL.DoubleBuffering", 1);
856
 
        else
857
 
                g_config->setOption("SDL.DoubleBuffering", 0);
858
 
        g_config->save();
859
 
}
860
 
#endif
861
 
 
862
 
void openVideoConfig()
863
 
{
864
 
        GtkWidget* win;
865
 
        GtkWidget* vbox;
866
 
        GtkWidget* lbl;
867
 
        GtkWidget* hbox1;
868
 
        GtkWidget* scalerLbl;
869
 
        GtkWidget* scalerCombo;
870
 
        GtkWidget* glChk;
871
 
        GtkWidget* linearChk;
872
 
        GtkWidget* dbChk;
873
 
        GtkWidget* palChk;
874
 
        GtkWidget* ppuChk;
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;
885
 
                
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);
892
 
        
893
 
        vbox = gtk_dialog_get_content_area(GTK_DIALOG(win));
894
 
        
895
 
        lbl = gtk_label_new("Video options will not take\neffect until the emulator is restarted.");
896
 
        
897
 
        // scalar widgets
898
 
        hbox1 = gtk_hbox_new(FALSE, 3);
899
 
        scalerLbl = gtk_label_new("Special Scaler: ");
900
 
        scalerCombo = gtk_combo_box_text_new();
901
 
        // -Video Modes Tag-
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");
908
 
        
909
 
        // sync with cfg
910
 
        int buf;
911
 
        g_config->getOption("SDL.SpecialFilter", &buf);
912
 
        gtk_combo_box_set_active(GTK_COMBO_BOX(scalerCombo), buf);
913
 
        
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);
917
 
#ifdef OPENGL   
918
 
        // openGL check
919
 
        glChk = gtk_check_button_new_with_label("Enable OpenGL");
920
 
        g_signal_connect(glChk, "clicked", G_CALLBACK(setGl), NULL);
921
 
        
922
 
        // sync with config
923
 
        buf = 0;
924
 
        g_config->getOption("SDL.OpenGL", &buf);
925
 
        if(buf)
926
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glChk), 1);
927
 
        else
928
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glChk), 0);
929
 
        
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");
933
 
        
934
 
        // sync with config
935
 
        buf = 0;
936
 
        g_config->getOption("SDL.OpenGLip", &buf);
937
 
        if(buf)
938
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linearChk), 1);
939
 
        else
940
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linearChk), 0);
941
 
        
942
 
    // DoubleBuffering check
943
 
        dbChk = gtk_check_button_new_with_label("Enable double buffering");
944
 
        g_signal_connect(dbChk, "clicked", G_CALLBACK(setDoubleBuffering), NULL);
945
 
        
946
 
        // sync with config
947
 
        buf = 0;
948
 
        g_config->getOption("SDL.DoubleBuffering", &buf);
949
 
        if(buf)
950
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dbChk), 1);
951
 
        else
952
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dbChk), 0);
953
 
#endif
954
 
        
955
 
        
956
 
        // PAL check
957
 
        palChk = gtk_check_button_new_with_label("Enable PAL mode");
958
 
        g_signal_connect(palChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.PAL");
959
 
        
960
 
        // sync with config
961
 
        buf = 0;
962
 
        g_config->getOption("SDL.PAL", &buf);
963
 
        if(buf)
964
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(palChk), 1);
965
 
        else
966
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(palChk), 0);
967
 
                
968
 
        // New PPU check
969
 
        ppuChk = gtk_check_button_new_with_label("Enable new PPU");
970
 
        g_signal_connect(ppuChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.NewPPU");
971
 
        
972
 
        // sync with config
973
 
        buf = 0;
974
 
        g_config->getOption("SDL.NewPPU", &buf);
975
 
        if(buf)
976
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ppuChk), 1);
977
 
        else
978
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ppuChk), 0);
979
 
        
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");
983
 
        
984
 
        // sync with config
985
 
        buf = 0;
986
 
        g_config->getOption("SDL.DisableSpriteLimit", &buf);
987
 
        if(buf)
988
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(spriteLimitChk), 1);
989
 
        else
990
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(spriteLimitChk), 0);
991
 
 
992
 
        // frameskip check
993
 
        frameskipChk = gtk_check_button_new_with_label("Enable frameskip");
994
 
        g_signal_connect(frameskipChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.Frameskip");
995
 
        
996
 
        // sync with config
997
 
        buf = 0;
998
 
        g_config->getOption("SDL.Frameskip", &buf);
999
 
        if(buf)
1000
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frameskipChk), 1);
1001
 
        else
1002
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frameskipChk), 0);
1003
 
 
1004
 
 
1005
 
        // clip sides check
1006
 
        clipSidesChk = gtk_check_button_new_with_label("Clip sides");
1007
 
        g_signal_connect(clipSidesChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.ClipSides");
1008
 
        
1009
 
        // sync with config
1010
 
        buf = 0;
1011
 
        g_config->getOption("SDL.ClipSides", &buf);
1012
 
        if(buf)
1013
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(clipSidesChk), 1);
1014
 
        else
1015
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(clipSidesChk), 0);
1016
 
                
1017
 
        // xscale / yscale
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);
1024
 
        
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);
1029
 
        
1030
 
        g_signal_connect(xscaleSpin, "value-changed", G_CALLBACK(setXscale), NULL);
1031
 
        g_signal_connect(yscaleSpin, "value-changed", G_CALLBACK(setYscale), NULL);
1032
 
        
1033
 
        double f;
1034
 
        // sync with config
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);
1039
 
 
1040
 
        // show FPS check
1041
 
        showFpsChk = gtk_check_button_new_with_label("Show FPS");
1042
 
        g_signal_connect(showFpsChk, "clicked", G_CALLBACK(toggleOption), (gpointer)"SDL.ShowFPS");
1043
 
 
1044
 
        // sync with config
1045
 
        buf = 0;
1046
 
        g_config->getOption("SDL.ShowFPS", &buf);
1047
 
        if(buf)
1048
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(showFpsChk), 1);
1049
 
        else
1050
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(showFpsChk), 0);
1051
 
 
1052
 
        
1053
 
        
1054
 
        gtk_box_pack_start(GTK_BOX(vbox), lbl, FALSE, FALSE, 5);        
1055
 
        gtk_box_pack_start(GTK_BOX(vbox), hbox1, FALSE, FALSE, 5);
1056
 
#ifdef OPENGL
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);
1060
 
#endif
1061
 
        gtk_box_pack_start(GTK_BOX(vbox), palChk, FALSE, FALSE,5);
1062
 
        gtk_box_pack_start(GTK_BOX(vbox), ppuChk, FALSE, FALSE, 5);
1063
 
#ifdef FRAMESKIP
1064
 
        gtk_box_pack_start(GTK_BOX(vbox), frameskipChk, FALSE, FALSE, 5);
1065
 
#endif 
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);
1071
 
        
1072
 
        g_signal_connect(win, "delete-event", G_CALLBACK(closeVideoWin), NULL);
1073
 
        g_signal_connect(win, "response", G_CALLBACK(closeVideoWin), NULL);
1074
 
        
1075
 
        gtk_widget_show_all(win);
1076
 
        
1077
 
        return;
1078
 
}
1079
 
const char* mixerStrings[6] = {"Volume", "Triangle", "Square1", "Square2", "Noise", "PCM"};
1080
 
 
1081
 
int mixerChanged(GtkWidget* w, gpointer p)
1082
 
{
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)
1087
 
        {
1088
 
                g_config->setOption("SDL.Sound.Volume", v);
1089
 
                FCEUI_SetSoundVolume(v);
1090
 
        }
1091
 
        if(strcmp(lbl, "Triangle") == 0)
1092
 
        {
1093
 
                g_config->setOption("SDL.Sound.TriangleVolume", v);
1094
 
                FCEUI_SetTriangleVolume(v);
1095
 
        }
1096
 
        if(strcmp(lbl, "Square1") == 0)
1097
 
        {
1098
 
                g_config->setOption("SDL.Sound.Square1Volume", v);
1099
 
                FCEUI_SetSquare1Volume(v);
1100
 
        }
1101
 
        if(strcmp(lbl, "Square2") == 0)
1102
 
        {
1103
 
                g_config->setOption("SDL.Sound.Square2Volume", v);
1104
 
                FCEUI_SetSquare2Volume(v);
1105
 
        }
1106
 
        if(strcmp(lbl, "Noise") == 0)
1107
 
        {
1108
 
                g_config->setOption("SDL.Sound.NoiseVolume", v);
1109
 
                FCEUI_SetNoiseVolume(v);
1110
 
        }
1111
 
        if(strcmp(lbl, "PCM") == 0)
1112
 
        {
1113
 
                g_config->setOption("SDL.Sound.PCMVolume", v);
1114
 
                FCEUI_SetPCMVolume(v);
1115
 
        }
1116
 
        
1117
 
        return 0;
1118
 
}
1119
 
 
1120
 
void openSoundConfig()
1121
 
{
1122
 
        GtkWidget* win;
1123
 
        GtkWidget* main_hbox;
1124
 
        GtkWidget* vbox;
1125
 
        GtkWidget* soundChk;
1126
 
        GtkWidget* lowpassChk;
1127
 
        GtkWidget* hbox1;
1128
 
        GtkWidget* qualityCombo;
1129
 
        GtkWidget* qualityLbl;
1130
 
        GtkWidget* hbox2;
1131
 
        GtkWidget* rateCombo;
1132
 
        GtkWidget* rateLbl;
1133
 
        GtkWidget* hbox3;
1134
 
        GtkWidget* bufferLbl;
1135
 
        GtkWidget* bufferHscale;
1136
 
        GtkWidget* mixerFrame;
1137
 
        GtkWidget* mixerHbox;
1138
 
        GtkWidget* mixers[6];
1139
 
        GtkWidget* mixerFrames[6];
1140
 
 
1141
 
        win = gtk_dialog_new_with_buttons("Sound Preferences",
1142
 
                                                                                GTK_WINDOW(MainWindow),
1143
 
                                                                                (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT),
1144
 
                                                                                GTK_STOCK_CLOSE,
1145
 
                                                                                GTK_RESPONSE_OK,
1146
 
                                                                                NULL);
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);
1150
 
 
1151
 
        // sound enable check
1152
 
        soundChk = gtk_check_button_new_with_label("Enable sound");
1153
 
        
1154
 
        // sync with cfg
1155
 
        int cfgBuf;
1156
 
        g_config->getOption("SDL.Sound", &cfgBuf);
1157
 
        if(cfgBuf)
1158
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(soundChk), TRUE);
1159
 
        else
1160
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(soundChk), FALSE);
1161
 
        
1162
 
        g_signal_connect(soundChk, "clicked", G_CALLBACK(toggleSound), NULL);
1163
 
 
1164
 
        // low pass filter check
1165
 
        lowpassChk = gtk_check_button_new_with_label("Enable low pass filter");
1166
 
        
1167
 
        // sync with cfg
1168
 
        g_config->getOption("SDL.Sound.LowPass", &cfgBuf);
1169
 
        if(cfgBuf)
1170
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lowpassChk), TRUE);
1171
 
        else
1172
 
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lowpassChk), FALSE);
1173
 
        
1174
 
        g_signal_connect(lowpassChk, "clicked", G_CALLBACK(toggleLowPass), NULL);
1175
 
        
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");
1182
 
 
1183
 
        // sync widget with cfg 
1184
 
        g_config->getOption("SDL.Sound.Quality", &cfgBuf);
1185
 
        if(cfgBuf == 2)
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);
1189
 
        else
1190
 
                gtk_combo_box_set_active(GTK_COMBO_BOX(qualityCombo), 0);
1191
 
                
1192
 
        g_signal_connect(qualityCombo, "changed", G_CALLBACK(setQuality), NULL);
1193
 
        
1194
 
        qualityLbl = gtk_label_new("Quality: ");
1195
 
        
1196
 
        gtk_box_pack_start(GTK_BOX(hbox1), qualityLbl, FALSE, FALSE, 5);
1197
 
        gtk_box_pack_start(GTK_BOX(hbox1), qualityCombo, FALSE, FALSE, 5);
1198
 
        
1199
 
        // sound rate widgets
1200
 
        hbox2 = gtk_hbox_new(FALSE, 3);
1201
 
        rateCombo = gtk_combo_box_text_new();
1202
 
        
1203
 
        const int rates[5] = {11025, 22050, 44100, 48000, 96000};
1204
 
        
1205
 
        char buf[8];
1206
 
        for(int i=0; i<5;i++)
1207
 
        {
1208
 
                sprintf(buf, "%d", rates[i]);
1209
 
                gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rateCombo), buf);     
1210
 
        }
1211
 
        
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);
1217
 
                
1218
 
        g_signal_connect(rateCombo, "changed", G_CALLBACK(setRate), NULL);
1219
 
                
1220
 
        // sound rate widgets
1221
 
        rateLbl = gtk_label_new("Rate (Hz): ");
1222
 
        
1223
 
        gtk_box_pack_start(GTK_BOX(hbox2), rateLbl, FALSE, FALSE, 5);
1224
 
        gtk_box_pack_start(GTK_BOX(hbox2), rateCombo, FALSE, FALSE, 5);
1225
 
        
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)");
1229
 
 
1230
 
        // sync widget with cfg 
1231
 
        g_config->getOption("SDL.Sound.BufSize", &cfgBuf);
1232
 
        gtk_range_set_value(GTK_RANGE(bufferHscale), cfgBuf);
1233
 
        
1234
 
        g_signal_connect(bufferHscale, "button-release-event", G_CALLBACK(setBufSize), NULL);
1235
 
 
1236
 
        // mixer
1237
 
        mixerFrame = gtk_frame_new("Mixer:");
1238
 
        mixerHbox = gtk_hbox_new(TRUE, 5);
1239
 
        for(int i=0; i<6; i++)
1240
 
        {
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); 
1247
 
        }
1248
 
        
1249
 
        // sync with cfg
1250
 
        int v;
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);
1263
 
 
1264
 
        
1265
 
        // packing some boxes
1266
 
        
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);
1276
 
        
1277
 
        gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(win))), main_hbox, TRUE, TRUE, 0);
1278
 
        
1279
 
        g_signal_connect(win, "delete-event", G_CALLBACK(closeDialog), NULL);
1280
 
        g_signal_connect(win, "response", G_CALLBACK(closeDialog), NULL);
1281
 
        
1282
 
        gtk_widget_show_all(win);
1283
 
        
1284
 
        return;
1285
 
}
1286
 
 
1287
 
void quit ()
1288
 
{
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
1294
 
        //gtk_main_quit();
1295
 
        FCEUI_CloseGame();
1296
 
        FCEUI_Kill();
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", "");
1300
 
        g_config->save();
1301
 
        SDL_Quit();
1302
 
        exit(0);
1303
 
}
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",
1310
 
        "Pre 2.0 Guys:",
1311
 
        " Bero", " Xodnizel", " Aaron Oneal", " Joe Nahmias",
1312
 
        " Paul Kuliniewicz", " Quietust", " Ben Parnell", " Parasyte & bbitmaster",
1313
 
        " blip & nitsuja",
1314
 
        NULL};
1315
 
 
1316
 
void openAbout ()
1317
 
{
1318
 
        GdkPixbuf* logo = gdk_pixbuf_new_from_xpm_data(icon_xpm);
1319
 
        
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",
1327
 
                "authors", Authors,
1328
 
                "logo", logo, NULL);
1329
 
}
1330
 
 
1331
 
void toggleSound(GtkWidget* check, gpointer data)
1332
 
{
1333
 
        if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check)))
1334
 
        {
1335
 
                g_config->setOption("SDL.Sound", 1);
1336
 
                if(GameInfo)            
1337
 
                        InitSound();
1338
 
        }
1339
 
        else
1340
 
        {
1341
 
                g_config->setOption("SDL.Sound", 0);
1342
 
                KillSound();
1343
 
        }
1344
 
}
1345
 
 
1346
 
void emuReset ()
1347
 
{
1348
 
        if(isloaded)
1349
 
                ResetNES();
1350
 
}
1351
 
 
1352
 
void hardReset ()
1353
 
{
1354
 
        if(isloaded)
1355
 
        {
1356
 
                closeGame();
1357
 
                const char* lastFile;
1358
 
                g_config->getOption("SDL.LastOpenFile", &lastFile);
1359
 
                LoadGame(lastFile) == 0;
1360
 
                resizeGtkWindow();
1361
 
        }
1362
 
}
1363
 
 
1364
 
void enableFullscreen ()
1365
 
{
1366
 
        if(isloaded)
1367
 
                ToggleFS();
1368
 
}
1369
 
 
1370
 
void toggleAutoResume (GtkToggleAction *action)
1371
 
{
1372
 
        bool autoResume = gtk_toggle_action_get_active(action);
1373
 
 
1374
 
        g_config->setOption("SDL.AutoResume", (int)autoResume);
1375
 
        AutoResumePlay = autoResume;
1376
 
}
1377
 
 
1378
 
void recordMovie()
1379
 
{
1380
 
        if(isloaded)
1381
 
        {
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"");
1385
 
        }
1386
 
    
1387
 
        return;
1388
 
}
1389
 
void recordMovieAs ()
1390
 
{
1391
 
        if(!isloaded)
1392
 
        {
1393
 
                return;
1394
 
        }
1395
 
        GtkWidget* fileChooser;
1396
 
        
1397
 
        GtkFileFilter* filterFm2;
1398
 
        GtkFileFilter* filterAll;
1399
 
        
1400
 
        filterFm2 = gtk_file_filter_new();
1401
 
        gtk_file_filter_add_pattern(filterFm2, "*.fm2");
1402
 
        gtk_file_filter_set_name(filterFm2, "FM2 Movies");
1403
 
        
1404
 
        filterAll = gtk_file_filter_new();
1405
 
        gtk_file_filter_add_pattern(filterAll, "*");
1406
 
        gtk_file_filter_set_name(filterAll, "All Files");
1407
 
        
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));
1415
 
        
1416
 
        if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1417
 
        {
1418
 
                std::string fname;
1419
 
                
1420
 
                fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
1421
 
                if (!fname.size())
1422
 
                        return; // no filename selected, quit the whole thing
1423
 
          char* movie_fname = const_cast<char*>(FCEU_MakeFName(FCEUMKF_MOVIE, 0, 0).c_str());
1424
 
                
1425
 
                std::string s = GetUserText("Author name");
1426
 
                std::wstring author(s.begin(), s.end());
1427
 
 
1428
 
                
1429
 
                FCEUI_SaveMovie(fname.c_str(), MOVIE_FLAG_NONE, author);
1430
 
        }
1431
 
        gtk_widget_destroy (fileChooser);
1432
 
}
1433
 
 
1434
 
void loadMovie ()
1435
 
{
1436
 
        GtkWidget* fileChooser;
1437
 
        
1438
 
        GtkFileFilter* filterMovies;
1439
 
        GtkFileFilter* filterFm2;
1440
 
        GtkFileFilter* filterAll;
1441
 
 
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");
1447
 
 
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");
1452
 
        
1453
 
        filterAll = gtk_file_filter_new();
1454
 
        gtk_file_filter_add_pattern(filterAll, "*");
1455
 
        gtk_file_filter_set_name(filterAll, "All Files");
1456
 
        
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);
1460
 
                        
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));
1465
 
        
1466
 
        if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1467
 
        {
1468
 
                char* fname;
1469
 
                
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)
1476
 
                {
1477
 
                        GtkWidget* d;
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);
1482
 
                }
1483
 
        }
1484
 
        gtk_widget_destroy (fileChooser);
1485
 
}
1486
 
 
1487
 
#ifdef _S9XLUA_H
1488
 
void loadLua ()
1489
 
{
1490
 
        GtkWidget* fileChooser;
1491
 
        GtkFileFilter* filterLua;
1492
 
        GtkFileFilter* filterAll;
1493
 
        
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");
1498
 
        
1499
 
        filterAll = gtk_file_filter_new();
1500
 
        gtk_file_filter_add_pattern(filterAll, "*");
1501
 
        gtk_file_filter_set_name(filterAll, "All Files");
1502
 
        
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);
1506
 
        
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);
1512
 
        
1513
 
        if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1514
 
        {
1515
 
                char* filename;
1516
 
                
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)
1521
 
                {
1522
 
                        // This is necessary because lua scripts do not use FCEUD_PrintError to print errors.
1523
 
                        GtkWidget* d;
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);
1528
 
                }
1529
 
                g_free(filename);
1530
 
        }
1531
 
        else
1532
 
                gtk_widget_destroy (fileChooser);
1533
 
}
1534
 
#endif
1535
 
 
1536
 
 
1537
 
void loadFdsBios ()
1538
 
{
1539
 
        GtkWidget* fileChooser;
1540
 
        GtkFileFilter* filterDiskSys;
1541
 
        GtkFileFilter* filterRom;
1542
 
        GtkFileFilter* filterAll;
1543
 
        
1544
 
        
1545
 
        filterDiskSys = gtk_file_filter_new();
1546
 
        gtk_file_filter_add_pattern(filterDiskSys, "disksys.rom");
1547
 
        gtk_file_filter_set_name(filterDiskSys, "disksys.rom");
1548
 
        
1549
 
        filterRom = gtk_file_filter_new();
1550
 
        gtk_file_filter_add_pattern(filterRom, "*.rom");
1551
 
        gtk_file_filter_set_name(filterRom, "*.rom");
1552
 
        
1553
 
        filterAll = gtk_file_filter_new();
1554
 
        gtk_file_filter_add_pattern(filterAll, "*");
1555
 
        gtk_file_filter_set_name(filterAll, "All Files");
1556
 
        
1557
 
        
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));
1565
 
        
1566
 
        if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1567
 
        {
1568
 
                char* filename;
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();
1575
 
                if(outFile.fail())
1576
 
                {
1577
 
                        FCEUD_PrintError("Error copying the FDS BIOS file.");
1578
 
                }
1579
 
                else
1580
 
                {       
1581
 
                        GtkWidget* d;
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);
1586
 
                }
1587
 
        }
1588
 
        gtk_widget_destroy (fileChooser);
1589
 
}
1590
 
 
1591
 
// TODO: is there somewhere else we can move this?  works for now though
1592
 
void enableGameGenie(int enabled)
1593
 
{
1594
 
        g_config->setOption("SDL.GameGenie", enabled);
1595
 
        g_config->save();
1596
 
        FCEUI_SetGameGenie(enabled);
1597
 
}
1598
 
 
1599
 
void toggleGameGenie(GtkToggleAction *action)
1600
 
{
1601
 
        enableGameGenie(gtk_toggle_action_get_active(action));
1602
 
}
1603
 
 
1604
 
void togglePause(GtkAction *action)
1605
 
{
1606
 
        SDL_Event sdlev;
1607
 
        int paused;
1608
 
        
1609
 
        if(isloaded)
1610
 
        {
1611
 
                paused = FCEUI_EmulationPaused();
1612
 
        
1613
 
                sdlev.type = SDL_FCEU_HOTKEY_EVENT;
1614
 
                sdlev.user.code = HK_PAUSE;
1615
 
                if(SDL_PushEvent(&sdlev) < 0)
1616
 
                {
1617
 
                        FCEU_printf("Failed to push SDL event to %s game.\n", paused ? "resume" : "pause");
1618
 
                        return;
1619
 
                }
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);
1622
 
        }
1623
 
}
1624
 
 
1625
 
void loadGameGenie ()
1626
 
{
1627
 
        GtkWidget* fileChooser;
1628
 
        GtkFileFilter* filterGG;
1629
 
        GtkFileFilter* filterRom;
1630
 
        GtkFileFilter* filterNes;
1631
 
        GtkFileFilter* filterAll;
1632
 
        
1633
 
        
1634
 
        filterGG = gtk_file_filter_new();
1635
 
        gtk_file_filter_add_pattern(filterGG, "gg.rom");
1636
 
        gtk_file_filter_set_name(filterGG, "gg.rom");
1637
 
        
1638
 
        filterRom = gtk_file_filter_new();
1639
 
        gtk_file_filter_add_pattern(filterRom, "*.rom");
1640
 
        gtk_file_filter_set_name(filterRom, "*.rom");
1641
 
        
1642
 
        filterNes = gtk_file_filter_new();
1643
 
        gtk_file_filter_add_pattern(filterNes, "*.nes");
1644
 
        gtk_file_filter_set_name(filterNes, "*.nes");
1645
 
        
1646
 
        filterAll = gtk_file_filter_new();
1647
 
        gtk_file_filter_add_pattern(filterAll, "*");
1648
 
        gtk_file_filter_set_name(filterAll, "All Files");
1649
 
        
1650
 
        
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));
1659
 
        
1660
 
        if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1661
 
        {
1662
 
                char* filename;
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);
1669
 
                GtkWidget* d;
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);
1675
 
 
1676
 
                f2<<f1.rdbuf();
1677
 
                g_free(filename);
1678
 
        }
1679
 
        else
1680
 
                gtk_widget_destroy (fileChooser);
1681
 
 
1682
 
}
1683
 
 
1684
 
void loadNSF ()
1685
 
{
1686
 
        GtkWidget* fileChooser;
1687
 
        GtkFileFilter* filterNSF;
1688
 
        GtkFileFilter* filterZip;
1689
 
        GtkFileFilter* filterAll;
1690
 
        
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");
1699
 
        
1700
 
        filterAll = gtk_file_filter_new();
1701
 
        gtk_file_filter_add_pattern(filterAll, "*");
1702
 
        gtk_file_filter_set_name(filterAll, "All Files");
1703
 
        
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);
1707
 
        
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);
1711
 
        
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);
1715
 
        
1716
 
        if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1717
 
        {
1718
 
                char* filename;
1719
 
                
1720
 
                filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
1721
 
                gtk_widget_destroy (fileChooser);
1722
 
                LoadGame(filename);
1723
 
                // no longer required with GTK FCEUD_PrintError implementation
1724
 
                /*if(LoadGame(filename) == 0)
1725
 
                {
1726
 
                        
1727
 
                        GtkWidget* d;
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);
1732
 
                }*/
1733
 
                g_config->setOption("SDL.LastOpenNSF", filename);
1734
 
                g_free(filename);
1735
 
        }
1736
 
        else
1737
 
                gtk_widget_destroy (fileChooser);
1738
 
}
1739
 
 
1740
 
void closeGame()
1741
 
{
1742
 
        GdkColor bg = {0, 0, 0, 0};
1743
 
        gtk_widget_modify_bg(evbox, GTK_STATE_NORMAL, &bg);
1744
 
        CloseGame(); 
1745
 
}
1746
 
 
1747
 
void loadGame ()
1748
 
{
1749
 
        GtkWidget* fileChooser;
1750
 
        GtkFileFilter* filterFCEU;
1751
 
        GtkFileFilter* filterNes;
1752
 
        GtkFileFilter* filterFds;
1753
 
        GtkFileFilter* filterNSF;
1754
 
        GtkFileFilter* filterZip;
1755
 
        GtkFileFilter* filterAll;
1756
 
        
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");
1786
 
        
1787
 
        filterAll = gtk_file_filter_new();
1788
 
        gtk_file_filter_add_pattern(filterAll, "*");
1789
 
        gtk_file_filter_set_name(filterAll, "All Files");
1790
 
        
1791
 
        
1792
 
        
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);
1799
 
        
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);
1806
 
        
1807
 
        if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1808
 
        {
1809
 
                char* filename;
1810
 
                
1811
 
                filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
1812
 
                gtk_widget_destroy (fileChooser);
1813
 
                g_config->setOption("SDL.LastOpenFile", filename);
1814
 
                closeGame();
1815
 
                LoadGame(filename);
1816
 
                // Error dialog no longer required with GTK implementation of FCEUD_PrintError()
1817
 
                /*if(LoadGame(filename) == 0)
1818
 
                {
1819
 
                        
1820
 
                        GtkWidget* d;
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);
1825
 
                }*/
1826
 
                resizeGtkWindow();
1827
 
                g_free(filename);
1828
 
        }
1829
 
        else
1830
 
                gtk_widget_destroy (fileChooser);
1831
 
}
1832
 
 
1833
 
void saveStateAs()
1834
 
{
1835
 
        GtkWidget* fileChooser;
1836
 
        GtkFileFilter* filterSav;
1837
 
        GtkFileFilter* filterAll;
1838
 
        
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");
1843
 
        
1844
 
        filterAll = gtk_file_filter_new();
1845
 
        gtk_file_filter_add_pattern(filterAll, "*");
1846
 
        gtk_file_filter_set_name(filterAll, "All Files");
1847
 
        
1848
 
        const char* last_dir;
1849
 
        g_config->getOption("SDL.LastSaveStateAs", &last_dir);
1850
 
        
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);
1854
 
                        
1855
 
        gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fileChooser), last_dir);
1856
 
        
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);
1860
 
        
1861
 
        if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1862
 
        {
1863
 
                char* filename;
1864
 
                
1865
 
                filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
1866
 
                FCEUI_SaveState(filename);
1867
 
                g_config->setOption("SDL.LastSaveStateAs", filename);
1868
 
                g_free(filename);
1869
 
        }
1870
 
        gtk_widget_destroy (fileChooser);
1871
 
        
1872
 
        
1873
 
}
1874
 
 
1875
 
void loadStateFrom()
1876
 
{
1877
 
        GtkWidget* fileChooser;
1878
 
        GtkFileFilter* filterFcs;
1879
 
        GtkFileFilter* filterSav;
1880
 
        GtkFileFilter* filterAll;
1881
 
        
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");
1886
 
        
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");
1891
 
        
1892
 
        filterAll = gtk_file_filter_new();
1893
 
        gtk_file_filter_add_pattern(filterAll, "*");
1894
 
        gtk_file_filter_set_name(filterAll, "All Files");
1895
 
        
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);
1899
 
                        
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);
1903
 
 
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);
1907
 
        
1908
 
        if (gtk_dialog_run (GTK_DIALOG (fileChooser)) ==GTK_RESPONSE_ACCEPT)
1909
 
        {
1910
 
                char* filename;
1911
 
                
1912
 
                filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
1913
 
                FCEUI_LoadState(filename);
1914
 
                g_config->setOption("SDL.LastLoadStateFrom", filename);
1915
 
                g_free(filename);
1916
 
        }
1917
 
        gtk_widget_destroy (fileChooser);
1918
 
}
1919
 
 
1920
 
void quickLoad()
1921
 
{
1922
 
        FCEUI_LoadState(NULL);
1923
 
}
1924
 
 
1925
 
void quickSave()
1926
 
{
1927
 
        FCEUI_SaveState(NULL);
1928
 
}
1929
 
 
1930
 
void changeState(GtkAction *action, GtkRadioAction *current, gpointer data)
1931
 
{
1932
 
        FCEUI_SelectState(gtk_radio_action_get_current_value(current), 0);
1933
 
}
1934
 
 
1935
 
 
1936
 
// Adapted from Gens/GS.  Converts a GDK key value into an SDL key value.
1937
 
unsigned short GDKToSDLKeyval(int gdk_key)
1938
 
{
1939
 
        if (!(gdk_key & 0xFF00))
1940
 
        {
1941
 
                // ASCII symbol.
1942
 
                // SDL and GDK use the same values for these keys.
1943
 
                
1944
 
                // Make sure the key value is lowercase.
1945
 
                gdk_key = tolower(gdk_key);
1946
 
                
1947
 
                // Return the key value.
1948
 
                return gdk_key;
1949
 
        }
1950
 
        
1951
 
        if (gdk_key & 0xFFFF0000)
1952
 
        {
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));
1956
 
#else
1957
 
                fprintf(stderr, "Unhandled extended key: 0x%08X\n", gdk_key);
1958
 
#endif
1959
 
                return 0;
1960
 
        }
1961
 
        
1962
 
        // Non-ASCII symbol.
1963
 
        static const uint16_t gdk_to_sdl_table[0x100] =
1964
 
        {
1965
 
                // 0x00 - 0x0F
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,
1970
 
                
1971
 
                // 0x10 - 0x1F
1972
 
                0x0000, 0x0000, 0x0000, SDLK_PAUSE,
1973
 
                SDLK_SCROLLOCK, SDLK_SYSREQ, 0x0000, 0x0000,
1974
 
                0x0000, 0x0000, 0x0000, SDLK_ESCAPE,
1975
 
                0x0000, 0x0000, 0x0000, 0x0000,
1976
 
                
1977
 
                // 0x20 - 0x2F
1978
 
                SDLK_COMPOSE, 0x0000, 0x0000, 0x0000,
1979
 
                0x0000, 0x0000, 0x0000, 0x0000,
1980
 
                0x0000, 0x0000, 0x0000, 0x0000,
1981
 
                0x0000, 0x0000, 0x0000, 0x0000,
1982
 
                
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,
1988
 
                
1989
 
                // 0x40 - 0x4F [unused]
1990
 
                0x0000, 0x0000, 0x0000, 0x0000,
1991
 
                0x0000, 0x0000, 0x0000, 0x0000,
1992
 
                0x0000, 0x0000, 0x0000, 0x0000,
1993
 
                0x0000, 0x0000, 0x0000, 0x0000,
1994
 
                
1995
 
                // 0x50 - 0x5F
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,
2000
 
                
2001
 
                // 0x60 - 0x6F
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,
2006
 
                
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,
2012
 
                
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,
2018
 
                
2019
 
                // 0x90 - 0x9F
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,
2024
 
                
2025
 
                // 0xA0 - 0xAF
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,
2030
 
                
2031
 
                // 0xB0 - 0xBF
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,
2036
 
                
2037
 
                // 0xC0 - 0xCF
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,
2042
 
                
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,
2048
 
                
2049
 
                // 0xE0 - 0xEF
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,
2054
 
                
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,            
2060
 
        };
2061
 
        
2062
 
        unsigned short sdl_key = gdk_to_sdl_table[gdk_key & 0xFF];
2063
 
        if (sdl_key == 0)
2064
 
        {
2065
 
                // Unhandled GDK key.
2066
 
                fprintf(stderr, "Unhandled GDK key: 0x%04X (%s)", gdk_key, gdk_keyval_name(gdk_key));
2067
 
                return 0;
2068
 
        }
2069
 
        
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])
2073
 
                return 0;
2074
 
        
2075
 
        return sdl_key;
2076
 
}
2077
 
 
2078
 
 
2079
 
// Function adapted from Gens/GS (source/gens/input/input_sdl.c)
2080
 
gint convertKeypress(GtkWidget *grab, GdkEventKey *event, gpointer user_data)
2081
 
{
2082
 
        SDL_Event sdlev;
2083
 
        SDLKey sdlkey;
2084
 
        int keystate;
2085
 
        
2086
 
        switch (event->type)
2087
 
        {
2088
 
                case GDK_KEY_PRESS:
2089
 
                        sdlev.type = SDL_KEYDOWN;
2090
 
                        sdlev.key.state = SDL_PRESSED;
2091
 
                        keystate = 1;
2092
 
                        break;
2093
 
                
2094
 
                case GDK_KEY_RELEASE:
2095
 
                        sdlev.type = SDL_KEYUP;
2096
 
                        sdlev.key.state = SDL_RELEASED;
2097
 
                        keystate = 0;
2098
 
                        break;
2099
 
                
2100
 
                default:
2101
 
                        fprintf(stderr, "Unhandled GDK event type: %d", event->type);
2102
 
                        return FALSE;
2103
 
        }
2104
 
        
2105
 
        // Convert this keypress from GDK to SDL.
2106
 
        sdlkey = (SDLKey)GDKToSDLKeyval(event->keyval);
2107
 
        
2108
 
        // Create an SDL event from the keypress.
2109
 
        sdlev.key.keysym.sym = sdlkey;
2110
 
        if (sdlkey != 0)
2111
 
        {
2112
 
                SDL_PushEvent(&sdlev);
2113
 
                
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)))
2116
 
                {
2117
 
                        #if SDL_VERSION_ATLEAST(1, 3, 0)
2118
 
                        SDL_GetKeyboardState(NULL)[SDL_GetScancodeFromKey(sdlkey)] = keystate;
2119
 
                        #else
2120
 
                        SDL_GetKeyState(NULL)[sdlkey] = keystate;
2121
 
                        #endif
2122
 
                }
2123
 
        }
2124
 
        
2125
 
        // Allow GTK+ to process this key.
2126
 
        return FALSE;
2127
 
}
2128
 
 
2129
 
// Our menu, in the XML markup format used by GtkUIManager
2130
 
static char* menuXml = 
2131
 
        "<ui>"
2132
 
        "  <menubar name='Menubar'>"
2133
 
        "    <menu action='FileMenuAction'>"
2134
 
        "      <menuitem action='OpenRomAction' />"
2135
 
        "      <menuitem action='CloseRomAction' />"
2136
 
        "      <separator />"
2137
 
        "      <menuitem action='PlayNsfAction' />"
2138
 
        "      <separator />"
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' />"
2154
 
        "      </menu>"
2155
 
        "      <separator />"
2156
 
#ifdef _S9XLUA_H
2157
 
        "      <menuitem action='LoadLuaScriptAction' />"
2158
 
#endif
2159
 
        "      <separator />"
2160
 
        "      <menuitem action='ScreenshotAction' />"
2161
 
        "      <separator />"
2162
 
        "      <menuitem action='QuitAction' />"
2163
 
        "    </menu>"
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' />"
2172
 
        "      <separator />"
2173
 
        "      <menuitem action='FullscreenAction' />"
2174
 
        "    </menu>"
2175
 
        "    <menu action='EmulationMenuAction'>"
2176
 
        "      <menuitem action='PowerAction' />"
2177
 
        "      <menuitem action='ResetAction' />"
2178
 
        "      <menuitem action='SoftResetAction' />"
2179
 
        "      <menuitem action='PauseToggleAction' />"
2180
 
        "      <separator />"
2181
 
        "      <menuitem action='GameGenieToggleAction' />"
2182
 
        "      <menuitem action='LoadGameGenieAction' />"
2183
 
        "      <separator />"
2184
 
        "      <menuitem action='InsertCoinAction' />"
2185
 
        "      <separator />"
2186
 
        "      <menu action='FdsMenuAction'>"
2187
 
        "        <menuitem action='SwitchDiskAction' />"
2188
 
        "        <menuitem action='EjectDiskAction' />"
2189
 
        "        <menuitem action='LoadBiosAction' />"
2190
 
        "      </menu>"
2191
 
        "    </menu>"
2192
 
        "    <menu action='MovieMenuAction'>"
2193
 
        "      <menuitem action='OpenMovieAction' />"
2194
 
        "      <menuitem action='StopMovieAction' />"
2195
 
        "      <separator />"
2196
 
        "      <menuitem action='RecordMovieAction' />"
2197
 
        "      <menuitem action='RecordMovieAsAction' />"
2198
 
        "    </menu>"
2199
 
        "    <menu action='HelpMenuAction'>"
2200
 
        "      <menuitem action='AboutAction' />"
2201
 
        "    </menu>"
2202
 
        "  </menubar>"
2203
 
        "</ui>";
2204
 
 
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"},
2216
 
#ifdef _S9XLUA_H
2217
 
        {"LoadLuaScriptAction", GTK_STOCK_OPEN, "Load L_ua Script", "", NULL, G_CALLBACK(loadLua)},
2218
 
#endif
2219
 
        {"ScreenshotAction", NULL, "_Screenshot", "F12", NULL, G_CALLBACK(FCEUI_SaveSnapshot)},
2220
 
        {"QuitAction", GTK_STOCK_QUIT, "_Quit", "<control>Q", NULL, G_CALLBACK(quit)},
2221
 
        
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)},
2225
 
#endif
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)},
2243
 
        
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)},
2249
 
        
2250
 
        {"HelpMenuAction", NULL, "_Help"},
2251
 
        {"AboutAction", GTK_STOCK_ABOUT, "_About", NULL, NULL, G_CALLBACK(openAbout)},
2252
 
};
2253
 
 
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},
2258
 
};
2259
 
 
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},
2272
 
};
2273
 
 
2274
 
static GtkWidget* CreateMenubar( GtkWidget* window)
2275
 
{
2276
 
        GtkUIManager *ui_manager;
2277
 
        GtkActionGroup *action_group;
2278
 
        GtkAccelGroup* accel_group;
2279
 
        GError *error = NULL;
2280
 
        GtkAction* state;
2281
 
 
2282
 
        /* Make an UIManager (which makes a menubar). */
2283
 
        ui_manager = gtk_ui_manager_new ();
2284
 
        
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);
2291
 
    
2292
 
        /* Read the menu layout from the XML markup. */
2293
 
        gtk_ui_manager_add_ui_from_string (ui_manager, menuXml, -1, &error);
2294
 
        if (error)
2295
 
        {
2296
 
                fprintf (stderr, "Unable to create menu bar: %s\n", error->message);
2297
 
                g_error_free (error);
2298
 
        }
2299
 
    
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);
2303
 
    
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);
2308
 
 
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);
2312
 
    
2313
 
        /* Finally, return the actual menu bar created by the UIManager. */
2314
 
        return gtk_ui_manager_get_widget (ui_manager, "/Menubar");
2315
 
}
2316
 
 
2317
 
 
2318
 
void pushOutputToGTK(const char* str)
2319
 
{
2320
 
        // we don't really do anything with the output right now
2321
 
        return;
2322
 
}
2323
 
 
2324
 
void showGui(bool b)
2325
 
{
2326
 
        if(b)
2327
 
                gtk_widget_show_all(MainWindow);
2328
 
        else
2329
 
                gtk_widget_hide(MainWindow);
2330
 
}
2331
 
 
2332
 
int GtkMouseData[3] = {0,0,0};
2333
 
 
2334
 
gint handleMouseClick(GtkWidget* widget, GdkEvent *event, gpointer callback_data)
2335
 
{
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;
2341
 
        else
2342
 
        {
2343
 
                if(button == 1)
2344
 
                        GtkMouseData[2] |= 0x1;
2345
 
                if(button == 3)
2346
 
                        GtkMouseData[2] |= 0x3;
2347
 
        }
2348
 
 
2349
 
        // this doesn't work because we poll the mouse position rather
2350
 
        // than use events
2351
 
        /*
2352
 
        SDL_Event sdlev;
2353
 
        sdlev.type = SDL_MOUSEBUTTONDOWN;
2354
 
        if(((GdkEventButton*)event)->type == GDK_BUTTON_PRESS)
2355
 
                 sdlev.button.type = SDL_MOUSEBUTTONDOWN;
2356
 
        else
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;
2362
 
 
2363
 
        SDL_PushEvent(&sdlev);
2364
 
        */
2365
 
  
2366
 
        return 0;
2367
 
}
2368
 
// NES resolution = 256x240
2369
 
const int NES_WIDTH=256;
2370
 
const int NES_HEIGHT=240;
2371
 
 
2372
 
void handle_resize(GtkWindow* win, GdkEvent* event, gpointer data)
2373
 
{
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
2377
 
 
2378
 
 
2379
 
        // get new window width/height
2380
 
        int width, height;
2381
 
        width = event->configure.width;
2382
 
        height = event->configure.height;
2383
 
        printf("DEBUG: new window size: %dx%d\n", width, height);
2384
 
 
2385
 
        // get width/height multipliers
2386
 
        double xscale = width / (double)NES_WIDTH;
2387
 
        double yscale = height / (double)NES_HEIGHT;
2388
 
 
2389
 
        // TODO check KeepRatio (where is this)
2390
 
        // do this to keep aspect ratio
2391
 
        if(xscale > yscale)
2392
 
                xscale = yscale;
2393
 
        if(yscale > xscale)
2394
 
                yscale = xscale;
2395
 
 
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);
2400
 
        flushGtkEvents();
2401
 
        if(GameInfo != 0)
2402
 
        {
2403
 
                KillVideo();
2404
 
                InitVideo(GameInfo);
2405
 
        }
2406
 
        gtk_widget_set_size_request(evbox, (int)(NES_WIDTH*xscale), (int)(NES_HEIGHT*yscale));
2407
 
        GdkColor black;
2408
 
        black.red = 0;
2409
 
        black.green = 0;
2410
 
        black.blue = 0;
2411
 
//      gtk_widget_modify_bg(GTK_WIDGET(win), GTK_STATE_NORMAL, &black);
2412
 
 
2413
 
        printf("DEBUG: new xscale: %f yscale: %f\n", xscale, yscale);
2414
 
 
2415
 
        return;
2416
 
}
2417
 
 
2418
 
int InitGTKSubsystem(int argc, char** argv)
2419
 
{
2420
 
        GtkWidget* Menubar;
2421
 
        GtkWidget* vbox;
2422
 
        
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);
2428
 
        
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);
2432
 
        
2433
 
        vbox = gtk_vbox_new(FALSE, 0);
2434
 
        gtk_container_add(GTK_CONTAINER(MainWindow), vbox);
2435
 
        
2436
 
        Menubar = CreateMenubar(MainWindow);
2437
 
        // turn of game genie by default, since its off by default in the menu
2438
 
        enableGameGenie(0); 
2439
 
 
2440
 
        gtk_box_pack_start (GTK_BOX(vbox), Menubar, FALSE, TRUE, 0);
2441
 
                
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 
2445
 
        // controls
2446
 
        // 12/21/09
2447
 
        // ---
2448
 
        // uncommented and fixed by Bryan Cain
2449
 
        // 1/24/11
2450
 
        //
2451
 
        // prg - Bryan Cain, you are the man!
2452
 
        
2453
 
        evbox = gtk_event_box_new();
2454
 
        gtk_box_pack_start (GTK_BOX(vbox), evbox, TRUE, TRUE, 0);
2455
 
        
2456
 
        double xscale, yscale;
2457
 
        g_config->getOption("SDL.XScale", &xscale);
2458
 
        g_config->getOption("SDL.YScale", &yscale);
2459
 
 
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);
2464
 
        
2465
 
        GdkColor bg = {0, 0, 0, 0};
2466
 
        gtk_widget_modify_bg(evbox, GTK_STATE_NORMAL, &bg);
2467
 
        
2468
 
        // set up keypress "snooper" to convert GDK keypress events into SDL keypresses
2469
 
        gtk_key_snooper_install(convertKeypress, NULL);
2470
 
 
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);
2474
 
 
2475
 
        
2476
 
        // signal handlers
2477
 
        g_signal_connect(MainWindow, "delete-event", quit, NULL);
2478
 
        g_signal_connect(MainWindow, "destroy-event", quit, NULL);
2479
 
        // resize handler
2480
 
//      g_signal_connect(MainWindow, "configure-event", G_CALLBACK(handle_resize), NULL);
2481
 
        
2482
 
        gtk_widget_show_all(MainWindow);
2483
 
        
2484
 
        GtkRequisition req;
2485
 
        gtk_widget_size_request(GTK_WIDGET(MainWindow), &req);
2486
 
        gtk_window_resize(GTK_WINDOW(MainWindow), req.width, req.height);
2487
 
        gtkIsStarted = true;
2488
 
         
2489
 
        return 0;
2490
 
}
2491