nestopia/source/unix/uihelp.cpp
2013-01-19 00:11:19 -05:00

1322 lines
43 KiB
C++

/*
NEStopia / Linux
Port by R. Belmont
uihelp.cpp - UI callback functions
*/
#include <stdlib.h>
#include <SDL.h>
#include <iostream>
#include <fstream>
#include <strstream>
#include <sstream>
#include <iomanip>
#include <string.h>
#include <cassert>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <vector>
#include "core/api/NstApiEmulator.hpp"
#include "core/api/NstApiVideo.hpp"
#include "core/api/NstApiSound.hpp"
#include "core/api/NstApiInput.hpp"
#include "core/api/NstApiMachine.hpp"
#include "core/api/NstApiUser.hpp"
#include "core/api/NstApiNsf.hpp"
#include "core/api/NstApiMovie.hpp"
#include "core/api/NstApiFds.hpp"
#include "core/api/NstApiRewinder.hpp"
#include "core/api/NstApiCartridge.hpp"
#include "core/api/NstApiCheats.hpp"
#include "core/NstCrc32.hpp"
#include "core/NstChecksum.hpp"
#include "core/NstXml.hpp"
#include "oss.h"
#include "settings.h"
#include "auxio.h"
#include "input.h"
#include "controlconfig.h"
#include "cheats.h"
#include "seffect.h"
#include "main.h"
#include "GL/glu.h"
extern "C" {
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkx.h>
#include "interface.h"
#include "callbacks.h"
}
using namespace Nes::Api;
using namespace LinuxNst;
extern Emulator emulator;
static Settings *sSettings;
static CheatMgr *sCheatMgr;
static GdkPixbuf *app_icon;
GtkWidget *mainwindow;
GtkWidget *configwindow;
static GtkWidget *nsfplayer, *nsftitle, *nsfauthor, *nsfmaker, *text_volume, *scroll_volume;
static char volumestr[5], surrmulstr[5];
char windowid[24];
int playernumber = 0;
extern int xres, yres, schedule_stop;
bool wasplaying = 0;
void on_nsfspinbutton_input(GtkSpinButton *spinbutton, GtkScrollType scroll, gpointer user_data)
{
}
void on_nsfspinbutton_change_value(GtkSpinButton *spinbutton, GtkScrollType scroll, gpointer user_data)
{
}
void on_nsfspinbutton_value_changed(GtkSpinButton *spinbutton, gpointer user_data)
{
Nsf nsf( emulator );
nsf.SelectSong((int)gtk_spin_button_get_value(spinbutton));
}
void on_nsfplay_clicked(GtkButton *button, gpointer user_data)
{
NstPlayNsf();
}
void on_nsfstop_clicked(GtkButton *button, gpointer user_data)
{
NstStopNsf();
//gtk_widget_set_sensitive(button_nsfplay, TRUE);
//gtk_widget_set_sensitive(button_nsfstop, FALSE);
}
void on_videocombo_changed(GtkComboBox *combobox, gpointer user_data)
{
sSettings->SetVideoMode(gtk_combo_box_get_active(combobox));
}
void on_mainwindow_destroy(GObject *object, gpointer user_data)
{
gtk_widget_destroy(mainwindow);
NstScheduleQuit();
}
static void set_cur_path(char *inpath)
{
char cwd[1024];
int i;
strcpy(cwd, inpath);
i = strlen(inpath)-1;
while ((cwd[i] != '/') && (i > 0))
{
i--;
}
cwd[i+1] = '\0';
chdir(cwd);
}
void on_open_clicked(GtkButton *button, gpointer user_data)
{
GtkWidget *dialog;
GtkFileFilter *filter;
if (NstIsPlaying())
{
schedule_stop = 1;
}
dialog = gtk_file_chooser_dialog_new ("Select a ROM",
GTK_WINDOW(mainwindow),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
filter = gtk_file_filter_new();
gtk_file_filter_set_name(filter, "NES ROMs and archives");
gtk_file_filter_add_pattern(filter, "*.nes");
gtk_file_filter_add_pattern(filter, "*.fds");
gtk_file_filter_add_pattern(filter, "*.unf");
gtk_file_filter_add_pattern(filter, "*.unif");
gtk_file_filter_add_pattern(filter, "*.nsf");
gtk_file_filter_add_pattern(filter, "*.zip");
gtk_file_filter_add_pattern(filter, "*.7z");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
{
char *filename;
//int i;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
// make sure open starts in this location next time
set_cur_path(filename);
wasplaying = 1;
// load the cartridge
NstLoadGame(filename);
g_free (filename);
}
gtk_widget_destroy(dialog);
if (wasplaying) {
NstPlayGame();
}
}
void on_playbutton_clicked(GtkButton *button, gpointer user_data)
{
NstPlayGame();
}
void okbutton_clicked() {
gtk_widget_destroy(configwindow);
}
void configwindow_destroyed() {
if (wasplaying) {
NstPlayGame();
}
else {
get_screen_res();
}
redraw_request();
}
void
on_check_fullscreen_toggled (GtkToggleButton *togglebutton,
gpointer user_data)
{
sSettings->SetFullscreen(gtk_toggle_button_get_active(togglebutton));
}
void on_check_fsnativeres_toggled(GtkToggleButton *togglebutton, gpointer user_data) {
sSettings->SetFsNativeRes(gtk_toggle_button_get_active(togglebutton));
}
void on_check_tvaspect_toggled(GtkToggleButton *togglebutton, gpointer user_data) {
sSettings->SetTvAspect(gtk_toggle_button_get_active(togglebutton));
}
void
on_unlimitsprcheck_toggled (GtkToggleButton *togglebutton,
gpointer user_data)
{
sSettings->SetSprlimit(gtk_toggle_button_get_active(togglebutton));
}
void
on_scalecombo_changed (GtkComboBox *combobox,
gpointer user_data)
{
sSettings->SetScale(gtk_combo_box_get_active(combobox));
}
void
on_controlcheck_toggled (GtkToggleButton *togglebutton,
gpointer user_data)
{
sSettings->SetUseJoypads(gtk_toggle_button_get_active(togglebutton));
}
void
on_stereocheck_toggled (GtkToggleButton *togglebutton,
gpointer user_data)
{
Sound sound( emulator );
sSettings->SetStereo(gtk_toggle_button_get_active(togglebutton));
if (NstIsPlaying())
{
if (sSettings->GetStereo())
{
sound.SetSpeaker( Sound::SPEAKER_STEREO );
}
else
{
sound.SetSpeaker( Sound::SPEAKER_MONO );
}
}
}
void
on_surrcheck_toggled (GtkToggleButton *togglebutton,
gpointer user_data)
{
sSettings->SetUseSurround(gtk_toggle_button_get_active(togglebutton));
}
void
on_excitecheck_toggled (GtkToggleButton *togglebutton,
gpointer user_data)
{
sSettings->SetUseExciter(gtk_toggle_button_get_active(togglebutton));
}
void
on_ratecombo_changed (GtkComboBox *combobox,
gpointer user_data)
{
sSettings->SetRate(gtk_combo_box_get_active(combobox));
}
gboolean
on_ratecombo_configure_event (GtkWidget *widget,
GdkEventConfigure *event,
gpointer user_data)
{
}
void
on_rendercombo_changed (GtkComboBox *combobox,
gpointer user_data)
{
sSettings->SetRenderType(gtk_combo_box_get_active(combobox));
}
void playercombo_changed(GtkComboBox *combobox, gpointer user_data) {
playernumber = gtk_combo_box_get_active(combobox);
}
void
on_systemcombo_changed (GtkComboBox *combobox,
gpointer user_data)
{
sSettings->SetPrefSystem(gtk_combo_box_get_active(combobox));
}
void on_scaleamtcombo_changed(GtkComboBox *combobox, gpointer user_data)
{
sSettings->SetScaleAmt(gtk_combo_box_get_active(combobox));
}
void on_configcombo_changed(GtkComboBox *combobox, gpointer user_data)
{
sSettings->SetConfigItem(gtk_combo_box_get_active(combobox));
int curItem = sSettings->GetConfigItem();
//printf("%d\n", curItem);
}
void on_spatchcombo_changed(GtkComboBox *combobox, gpointer user_data)
{
sSettings->SetSoftPatch(gtk_combo_box_get_active(combobox));
}
void on_sndapicombo_changed(GtkComboBox *combobox, gpointer user_data)
{
sSettings->SetSndAPI(gtk_combo_box_get_active(combobox));
}
void
on_volumescroll_value_changed (GtkRange *range,
gpointer user_data)
{
Sound sound( emulator );
sSettings->SetVolume((int)gtk_range_get_value(range));
//sprintf(volumestr, "%d", sSettings->GetVolume());
//gtk_label_set_text(GTK_LABEL(text_volume), volumestr);
if (NstIsPlaying())
{
sound.SetVolume(Sound::ALL_CHANNELS, sSettings->GetVolume());
}
}
void on_surrscroll_value_changed(GtkRange *range, gpointer user_data)
{
sSettings->SetSurrMult((int)gtk_range_get_value(range));
//sprintf(surrmulstr, "%d", sSettings->GetSurrMult());
//gtk_label_set_text(GTK_LABEL(text_surround), surrmulstr);
}
void on_cheatbutton_pressed(GtkButton *button, gpointer user_data)
{
sCheatMgr->ShowManager();
}
void on_aboutbutton_clicked(GtkButton *button, gpointer user_data)
{
create_about();
}
gboolean
on_volumescroll_configure_event (GtkWidget *widget,
GdkEventConfigure *event,
gpointer user_data)
{
}
void on_ntsccombo_changed (GtkComboBox *combobox, gpointer user_data)
{
sSettings->SetNtscMode(gtk_combo_box_get_active(combobox));
}
void on_configbutton_clicked(GtkButton *button, gpointer user_data)
{
NstLaunchConfig();
}
void inputcfg_clicked(GtkButton *button, int data) {
if (playernumber == 0 && data < 16) { // Player 1
switch(data) {
case 0:
sSettings->SetConfigItem(0); //P1UP
break;
case 1:
sSettings->SetConfigItem(1); //P1DN
break;
case 2:
sSettings->SetConfigItem(2); //P1LT
break;
case 3:
sSettings->SetConfigItem(3); //P1RT
break;
case 4:
sSettings->SetConfigItem(4); //P1A
break;
case 5:
sSettings->SetConfigItem(5); //P1B
break;
case 6:
sSettings->SetConfigItem(6); //P1START
break;
case 7:
sSettings->SetConfigItem(7); //P1SELECT
break;
}
}
else if (playernumber == 1 && data < 16) { // Player 2
switch(data) {
case 0:
sSettings->SetConfigItem(8); //P2UP
break;
case 1:
sSettings->SetConfigItem(9); //P2DN
break;
case 2:
sSettings->SetConfigItem(10); //P2LT
break;
case 3:
sSettings->SetConfigItem(11); //P2RT
break;
case 4:
sSettings->SetConfigItem(12); //P2A
break;
case 5:
sSettings->SetConfigItem(13); //P2B
break;
case 6:
sSettings->SetConfigItem(14); //P2START
break;
case 7:
sSettings->SetConfigItem(15); //P2SELECT
break;
}
}
else {
switch(data) {
case 26:
sSettings->SetConfigItem(26); //Rewind Start
break;
case 27:
sSettings->SetConfigItem(27); //Rewind Start
break;
}
}
NstLaunchConfig();
}
void on_nsfplayer_destroy(GObject *object, gpointer user_data)
{
NstStopNsf();
//gtk_widget_destroy(nsfplayer);
}
void load_file_by_uri(char *filename) {
char *fsub;
char transname[512], convstr[3];
int i, j;
// make sure the URI header is there
if (strncmp(filename, "file://", 7))
{
return;
}
// skip the URI header
filename += 7;
// remove the path component
fsub = filename + strlen(filename)-1;
while (*fsub != '/')
{
fsub--;
}
fsub++; // skip the slash
// un-escape the URI
i = j = 0;
while (filename[i] != '\0')
{
if (filename[i] == '%')
{
char ins;
char *eptr;
i++;
convstr[0] = filename[i++];
convstr[1] = filename[i++];
convstr[2] = '\0';
ins = strtol(convstr, &eptr, 16);
transname[j++] = ins;
}
else
{
transname[j++] = filename[i++];
}
}
transname[j] = '\0';
// now load it
NstLoadGame(transname);
NstPlayGame();
}
void drag_data_received(GtkWidget *widget, GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data, guint info, guint t, gpointer data) {
if ((widget == NULL) || (dc == NULL)) {
return;
}
if (selection_data == NULL) {
return;
}
if (info == 0) {
gchar *filename = (gchar*)gtk_selection_data_get_data(selection_data);
int i, datalen;
char *root;
// for multiple files in a drag, we get a list of file:// URIs separated by LF/CRs
// we only accept one in Nestopia
datalen = strlen(filename);
root = filename;
for (i = 0; i < datalen; i++) {
if ((filename[i] == 0x0d) || (filename[i] == 0x0a)) {
filename[i] = '\0';
load_file_by_uri(root);
return;
}
}
}
}
void UIHelp_Init(int argc, char *argv[], LinuxNst::Settings *settings, LinuxNst::CheatMgr *cheatmgr, int xres, int yres)
{
sSettings = settings;
sCheatMgr = cheatmgr;
// crank up our GUI
mainwindow = create_mainwindow(xres, yres);
// set up the icon
char iconpath[1024];
sprintf(iconpath, "%s/icons/nestopia.svg", DATADIR);
// Load the icon from local source dir if make install hasn't been done
struct stat iconstat;
if (stat(iconpath, &iconstat) == -1) {
sprintf(iconpath, "source/unix/icons/nestopia.svg");
}
app_icon = gdk_pixbuf_new_from_file(iconpath, NULL);
gtk_window_set_icon(GTK_WINDOW(mainwindow), app_icon);
// show the window
gtk_widget_show(mainwindow);
}
void UIHelp_NSFLoaded(void)
{
Nsf nsf( emulator );
create_nsfplayer();
// show the NSF info
gtk_label_set_text(GTK_LABEL(nsftitle), nsf.GetName());
gtk_label_set_text(GTK_LABEL(nsfauthor), nsf.GetArtist());
gtk_label_set_text(GTK_LABEL(nsfmaker), nsf.GetCopyright());
}
// return the icon for alternate windows to use
GdkPixbuf *get_icon() {
return app_icon;
}
// These functions are dirty hacks to let the main window
// in interace.c call C++ functions. I should probably rethink this later.
void pause_clicked() {
bool playing = NstIsPlaying();
if (playing) {
wasplaying = 1;
schedule_stop = 1;
}
}
void reset_clicked() {
NstReset();
}
void fullscreen_clicked() {
ToggleFullscreen();
}
void state_load() {
auxio_do_state_load();
}
void state_save() {
auxio_do_state_save();
}
void flipdisk_clicked() {
FlipFDSDisk();
}
void movie_load() {
auxio_do_movie_load();
}
void movie_record() {
auxio_do_movie_save();
}
void movie_stop() {
auxio_do_movie_stop();
}
void redraw_request() {
redraw_drawingarea(xres, yres);
}
GtkWidget* create_config(void) {
// Pause if playing
bool playing = NstIsPlaying();
if (playing) {
schedule_stop = 1;
wasplaying = 1;
}
else { // Set it back to 0 in case the game was paused and the config is opened again
wasplaying = 0;
}
configwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(configwindow), "Configuration");
GtkWidget *bigbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
GtkWidget *smallbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
GtkWidget *notebook = gtk_notebook_new();
gtk_container_add(GTK_CONTAINER(configwindow), bigbox);
// The Video stuff
GtkWidget *videobox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
GtkWidget *renderlabel = gtk_widget_new(GTK_TYPE_LABEL, "xalign", 0.0, "margin-top", 10, "margin-bottom", 5, "margin-left", 10, NULL);
gtk_label_set_markup(GTK_LABEL(renderlabel), "<b>Renderer</b>");
GtkWidget *rendercombo = gtk_widget_new(GTK_TYPE_COMBO_BOX_TEXT, "halign", GTK_ALIGN_START, "margin-bottom", 5, "margin-left", 10, "margin-right", 10, NULL);
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rendercombo), "Software");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rendercombo), "Hardware - OpenGL");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rendercombo), "Hardware - OpenGL (bilinear)");
gtk_combo_box_set_active(GTK_COMBO_BOX(rendercombo), sSettings->GetRenderType());
GtkWidget *vidsettingslabel = gtk_widget_new(GTK_TYPE_LABEL, "xalign", 0.0, "margin-top", 10, "margin-bottom", 5, "margin-left", 10, NULL);
gtk_label_set_markup(GTK_LABEL(vidsettingslabel), "<b>Settings</b>");
GtkWidget *scalebox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget *scalelabel = gtk_widget_new(GTK_TYPE_LABEL, "label", "Scaler:", "halign", GTK_ALIGN_START, "margin-bottom", 5, "margin-left", 10, NULL);
GtkWidget *scalecombo = gtk_widget_new(GTK_TYPE_COMBO_BOX_TEXT, "halign", GTK_ALIGN_START, "margin-bottom", 5, "margin-left", 10, NULL);
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scalecombo), "None");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scalecombo), "NTSC");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scalecombo), "Scale?x");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scalecombo), "hq?x");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scalecombo), "2xSaI");
gtk_combo_box_set_active(GTK_COMBO_BOX(scalecombo), sSettings->GetScale());
gtk_box_pack_start(GTK_BOX(scalebox), scalelabel, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(scalebox), scalecombo, FALSE, FALSE, 0);
GtkWidget *scaleamtbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget *scaleamtlabel = gtk_widget_new(GTK_TYPE_LABEL, "label", "Multiplier:", "halign", GTK_ALIGN_START, "margin-bottom", 5, "margin-left", 10, NULL);
GtkWidget *scaleamtcombo = gtk_widget_new(GTK_TYPE_COMBO_BOX_TEXT, "halign", GTK_ALIGN_START, "margin-bottom", 5, "margin-left", 10, NULL);
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scaleamtcombo), "1x");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scaleamtcombo), "2x");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scaleamtcombo), "3x");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scaleamtcombo), "4x");
gtk_combo_box_set_active(GTK_COMBO_BOX(scaleamtcombo), sSettings->GetScaleAmt());
gtk_box_pack_start(GTK_BOX(scaleamtbox), scaleamtlabel, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(scaleamtbox), scaleamtcombo, FALSE, FALSE, 0);
GtkWidget *ntscbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget *ntsclabel = gtk_widget_new(GTK_TYPE_LABEL, "label", "NTSC Type:", "halign", GTK_ALIGN_START, "margin-bottom", 5, "margin-left", 10, NULL);
GtkWidget *ntsccombo = gtk_widget_new(GTK_TYPE_COMBO_BOX_TEXT, "halign", GTK_ALIGN_START, "margin-bottom", 5, "margin-left", 10, NULL);
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(ntsccombo), "Composite");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(ntsccombo), "S-Video");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(ntsccombo), "RGB");
gtk_combo_box_set_active(GTK_COMBO_BOX(ntsccombo), sSettings->GetNtscMode());
gtk_box_pack_start(GTK_BOX(ntscbox), ntsclabel, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(ntscbox), ntsccombo, FALSE, FALSE, 0);
GtkWidget *check_tvaspect = gtk_widget_new(GTK_TYPE_CHECK_BUTTON, "label", "TV Aspect Ratio", "halign", GTK_ALIGN_START, "margin-left", 10, NULL);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_tvaspect), sSettings->GetTvAspect());
GtkWidget *check_fullscreen = gtk_widget_new(GTK_TYPE_CHECK_BUTTON, "label", "Fullscreen", "halign", GTK_ALIGN_START, "margin-left", 10, NULL);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_fullscreen), sSettings->GetFullscreen());
GtkWidget *check_fsnativeres = gtk_widget_new(GTK_TYPE_CHECK_BUTTON, "label", "Stretch to Native (Fullscreen)", "halign", GTK_ALIGN_START, "margin-left", 10, NULL);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_fsnativeres), sSettings->GetFsNativeRes());
GtkWidget *unlimitsprcheck = gtk_widget_new(GTK_TYPE_CHECK_BUTTON, "label", "Unlimited Sprites", "halign", GTK_ALIGN_START, "margin-left", 10, NULL);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(unlimitsprcheck), sSettings->GetSprlimit());
gtk_box_pack_start(GTK_BOX(videobox), renderlabel, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(videobox), rendercombo, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(videobox), vidsettingslabel, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(videobox), scalebox, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(videobox), scaleamtbox, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(videobox), ntscbox, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(videobox), check_tvaspect, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(videobox), check_fullscreen, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(videobox), check_fsnativeres, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(videobox), unlimitsprcheck, FALSE, FALSE, 0);
//End of the Video stuff
// The Audio stuff
GtkWidget *audiobox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
#ifndef BSD
GtkWidget *sndapilabel = gtk_widget_new(GTK_TYPE_LABEL, "xalign", 0.0, "margin-top", 10, "margin-bottom", 5, "margin-left", 10, NULL);
gtk_label_set_markup(GTK_LABEL(sndapilabel), "<b>Sound API</b>");
GtkWidget *sndapicombo = gtk_widget_new(GTK_TYPE_COMBO_BOX_TEXT, "halign", GTK_ALIGN_START, "margin-bottom", 5, "margin-left", 10, "margin-right", 10, NULL);
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT (sndapicombo), "SDL");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT (sndapicombo), "ALSA");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT (sndapicombo), "OSS");
gtk_combo_box_set_active(GTK_COMBO_BOX(sndapicombo), sSettings->GetSndAPI());
#endif
GtkWidget *ratelabel = gtk_widget_new(GTK_TYPE_LABEL, "xalign", 0.0, "margin-top", 10, "margin-bottom", 5, "margin-left", 10, NULL);
gtk_label_set_markup(GTK_LABEL(ratelabel), "<b>Sample Rate</b>");
GtkWidget *ratecombo = gtk_widget_new(GTK_TYPE_COMBO_BOX_TEXT, "halign", GTK_ALIGN_START, "margin-bottom", 5, "margin-left", 10, "margin-right", 10, NULL);
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT (ratecombo), "11025 Hz");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT (ratecombo), "22050 Hz");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT (ratecombo), "44100 Hz");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT (ratecombo), "48000 Hz");
gtk_combo_box_set_active(GTK_COMBO_BOX(ratecombo), sSettings->GetRawRate());
GtkWidget *audsettingslabel = gtk_widget_new(GTK_TYPE_LABEL, "xalign", 0.0, "margin-top", 10, "margin-bottom", 5, "margin-left", 10, NULL);
gtk_label_set_markup(GTK_LABEL(audsettingslabel), "<b>Settings</b>");
GtkWidget *volumebox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget *volumelabel = gtk_widget_new(GTK_TYPE_LABEL, "label", "Volume", "halign", GTK_ALIGN_START, "margin-bottom", 5, "margin-left", 10, "margin-right", 10, NULL);
GtkWidget *volumescroll = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 100, 1, 5, 0)));
gtk_widget_set_size_request(volumescroll, 128, 24);
gtk_range_set_value(GTK_RANGE(volumescroll), sSettings->GetVolume());
gtk_box_pack_start(GTK_BOX(volumebox), volumelabel, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(volumebox), volumescroll, FALSE, FALSE, 0);
GtkWidget *surrbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget *surrcheck = gtk_widget_new(GTK_TYPE_CHECK_BUTTON, "label", "Lite Surround", "halign", GTK_ALIGN_START, "margin-bottom", 5, "margin-left", 10, "margin-right", 10, NULL);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(surrcheck), sSettings->GetUseSurround());
GtkWidget *surrscroll = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT(gtk_adjustment_new (0, 0, 100, 1, 5, 0)));
gtk_widget_set_size_request(surrscroll, 128, 24);
gtk_range_set_value(GTK_RANGE(surrscroll), sSettings->GetSurrMult());
gtk_box_pack_start(GTK_BOX(surrbox), surrcheck, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(surrbox), surrscroll, FALSE, FALSE, 0);
GtkWidget *stereocheck = gtk_widget_new(GTK_TYPE_CHECK_BUTTON, "label", "Stereo", "halign", GTK_ALIGN_START, "margin-left", 10, NULL);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stereocheck), sSettings->GetStereo());
GtkWidget *excitecheck = gtk_widget_new(GTK_TYPE_CHECK_BUTTON, "label", "Stereo Exciter", "halign", GTK_ALIGN_START, "margin-left", 10, NULL);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(excitecheck), sSettings->GetUseExciter());
#ifndef BSD
gtk_box_pack_start(GTK_BOX(audiobox), sndapilabel, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(audiobox), sndapicombo, FALSE, FALSE, 0);
#endif
gtk_box_pack_start(GTK_BOX(audiobox), ratelabel, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(audiobox), ratecombo, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(audiobox), audsettingslabel, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(audiobox), volumebox, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(audiobox), surrbox, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(audiobox), stereocheck, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(audiobox), excitecheck, FALSE, FALSE, 0);
// End of the Audio stuff
// The Input stuff
GtkWidget *inputbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
char svgpath[1024];
sprintf(svgpath, "%s/icons/nespad.svg", DATADIR);
// Load the NES pad svg from local source dir if make install hasn't been done
struct stat svgstat;
if (stat(svgpath, &svgstat) == -1) {
sprintf(svgpath, "source/unix/icons/nespad.svg");
}
GtkWidget *inputgamepadbox = gtk_widget_new(GTK_TYPE_BOX, "halign", GTK_ALIGN_START, "margin", 10, NULL);
GtkWidget *nespad = gtk_widget_new(GTK_TYPE_IMAGE, "halign", GTK_ALIGN_CENTER, "expand", TRUE, "file", svgpath, "margin", 10, NULL);
//gtk_widget_set_size_request(nespad, 300, 400);
GtkWidget *inputseparator1 = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
GtkWidget *playerselectcombo = gtk_widget_new(GTK_TYPE_COMBO_BOX_TEXT, "halign", GTK_ALIGN_START, "margin-top", 5, "margin-bottom", 5, "margin-left", 10, "margin-right", 10, NULL);
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT (playerselectcombo), "Player 1");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT (playerselectcombo), "Player 2");
gtk_combo_box_set_active(GTK_COMBO_BOX(playerselectcombo), 0);
GtkWidget *upbutton = gtk_widget_new(GTK_TYPE_BUTTON, "label", "U", "halign", GTK_ALIGN_START, "margin-right", 4, "margin-left", 6, NULL);
GtkWidget *downbutton = gtk_widget_new(GTK_TYPE_BUTTON, "label", "D", "halign", GTK_ALIGN_START, "margin-right", 4, NULL);
GtkWidget *leftbutton = gtk_widget_new(GTK_TYPE_BUTTON, "label", "L", "halign", GTK_ALIGN_START, "margin-right", 4, NULL);
GtkWidget *rightbutton = gtk_widget_new(GTK_TYPE_BUTTON, "label", "R", "halign", GTK_ALIGN_START, "margin-right", 16, NULL);
GtkWidget *selectbutton = gtk_widget_new(GTK_TYPE_BUTTON, "label", "SELECT", "halign", GTK_ALIGN_START, "margin-right", 4,NULL);
GtkWidget *startbutton = gtk_widget_new(GTK_TYPE_BUTTON, "label", "START", "halign", GTK_ALIGN_START, "margin-right", 16,NULL);
GtkWidget *bbutton = gtk_widget_new(GTK_TYPE_BUTTON, "label", "B", "halign", GTK_ALIGN_START, "margin-right", 4, NULL);
GtkWidget *abutton = gtk_widget_new(GTK_TYPE_BUTTON, "label", "A", "halign", GTK_ALIGN_START, NULL);
GtkWidget *inputseparator2 = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
GtkWidget *inputmetabox = gtk_widget_new(GTK_TYPE_BOX, "halign", GTK_ALIGN_START, "margin", 10, NULL);
GtkWidget *rewindstart = gtk_widget_new(GTK_TYPE_BUTTON, "label", "Rewind Start", "halign", GTK_ALIGN_START, "margin-right", 4, NULL);
GtkWidget *rewindstop = gtk_widget_new(GTK_TYPE_BUTTON, "label", "Rewind Stop", "halign", GTK_ALIGN_START, NULL);
gtk_box_pack_start(GTK_BOX(inputbox), nespad, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(inputbox), inputseparator1, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(inputbox), playerselectcombo, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(inputbox), inputgamepadbox, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(inputbox), inputseparator2, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(inputbox), inputmetabox, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(inputgamepadbox), upbutton, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(inputgamepadbox), downbutton, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(inputgamepadbox), leftbutton, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(inputgamepadbox), rightbutton, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(inputgamepadbox), selectbutton, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(inputgamepadbox), startbutton, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(inputgamepadbox), bbutton, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(inputgamepadbox), abutton, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(inputmetabox), rewindstart, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(inputmetabox), rewindstop, FALSE, FALSE, 0);
// The Misc stuff
GtkWidget *miscbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
GtkWidget *videolabel = gtk_widget_new(GTK_TYPE_LABEL, "xalign", 0.0, "margin-top", 10, "margin-bottom", 5, "margin-left", 10, NULL);
gtk_label_set_markup(GTK_LABEL(videolabel), "<b>Video Region</b>");
GtkWidget *videocombo = gtk_widget_new(GTK_TYPE_COMBO_BOX_TEXT, "halign", GTK_ALIGN_START, "margin-bottom", 5, "margin-left", 10, NULL);
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(videocombo), "Auto");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(videocombo), "NTSC");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(videocombo), "PAL");
gtk_combo_box_set_active(GTK_COMBO_BOX(videocombo), sSettings->GetVideoMode());
GtkWidget *systemlabel = gtk_widget_new(GTK_TYPE_LABEL, "xalign", 0.0, "margin-top", 10, "margin-bottom", 5, "margin-left", 10, NULL);
gtk_label_set_markup(GTK_LABEL(systemlabel), "<b>Default System</b>");
GtkWidget *systemcombo = gtk_widget_new(GTK_TYPE_COMBO_BOX_TEXT, "halign", GTK_ALIGN_START, "margin-bottom", 5, "margin-left", 10, "margin-right", 10, NULL);
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(systemcombo), "NES (NTSC)");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(systemcombo), "NES (PAL)");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(systemcombo), "Famicom");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(systemcombo), "Dendy");
gtk_combo_box_set_active(GTK_COMBO_BOX(systemcombo), sSettings->GetPrefSystem());
GtkWidget *spatchlabel = gtk_widget_new(GTK_TYPE_LABEL, "xalign", 0.0, "margin-top", 10, "margin-bottom", 5, "margin-left", 10, NULL);
gtk_label_set_markup(GTK_LABEL(spatchlabel), "<b>Soft Patching</b>");
GtkWidget *spatchcombo = gtk_widget_new(GTK_TYPE_COMBO_BOX_TEXT, "halign", GTK_ALIGN_START, "margin-bottom", 5, "margin-left", 10, "margin-right", 10, NULL);
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(spatchcombo), "Off");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(spatchcombo), "On");
gtk_combo_box_set_active(GTK_COMBO_BOX(spatchcombo), sSettings->GetSoftPatch());
gtk_box_pack_start(GTK_BOX(miscbox), videolabel, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(miscbox), videocombo, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(miscbox), systemlabel, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(miscbox), systemcombo, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(miscbox), spatchlabel, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(miscbox), spatchcombo, FALSE, FALSE, 0);
//Structuring the notebook
GtkWidget *labelvideo = gtk_label_new("Video");
GtkWidget *labelaudio = gtk_label_new("Audio");
GtkWidget *labelinput = gtk_label_new("Input");
GtkWidget *labelmisc = gtk_label_new("Misc");
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), videobox, labelvideo);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), audiobox, labelaudio);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), inputbox, labelinput);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), miscbox, labelmisc);
// The OK button stuff
GtkWidget *okbutton = gtk_widget_new(GTK_TYPE_BUTTON, "label", GTK_STOCK_OK, "halign", GTK_ALIGN_END, "margin-top", 8, "margin-bottom", 8, "margin-right", 8, NULL);
gtk_button_set_use_stock(GTK_BUTTON(okbutton), TRUE);
//Structuring the window
gtk_box_pack_start(GTK_BOX(bigbox), notebook, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(bigbox), smallbox, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(smallbox), okbutton, FALSE, FALSE, 0);
//Set the icon
GdkPixbuf *app_icon = get_icon();
gtk_window_set_icon(GTK_WINDOW(configwindow), app_icon);
//Config
g_signal_connect(G_OBJECT(okbutton), "clicked",
G_CALLBACK(okbutton_clicked), NULL);
g_signal_connect(G_OBJECT(configwindow), "destroy",
G_CALLBACK(configwindow_destroyed), NULL);
//Video
g_signal_connect(G_OBJECT(scaleamtcombo), "changed",
G_CALLBACK(on_scaleamtcombo_changed), NULL);
g_signal_connect(G_OBJECT(scalecombo), "changed",
G_CALLBACK(on_scalecombo_changed), NULL);
g_signal_connect(G_OBJECT(check_tvaspect), "toggled",
G_CALLBACK(on_check_tvaspect_toggled), NULL);
g_signal_connect(G_OBJECT(check_fullscreen), "toggled",
G_CALLBACK(on_check_fullscreen_toggled), NULL);
g_signal_connect(G_OBJECT(check_fsnativeres), "toggled",
G_CALLBACK(on_check_fsnativeres_toggled), NULL);
g_signal_connect(G_OBJECT(unlimitsprcheck), "toggled",
G_CALLBACK(on_unlimitsprcheck_toggled), NULL);
g_signal_connect(G_OBJECT(videocombo), "changed",
G_CALLBACK(on_videocombo_changed), NULL);
g_signal_connect(G_OBJECT(ntsccombo), "changed",
G_CALLBACK(on_ntsccombo_changed), NULL);
g_signal_connect(G_OBJECT(rendercombo), "changed",
G_CALLBACK(on_rendercombo_changed), NULL);
//Audio
g_signal_connect(G_OBJECT(volumescroll), "value_changed",
G_CALLBACK(on_volumescroll_value_changed), NULL);
g_signal_connect(G_OBJECT(volumescroll), "configure_event",
G_CALLBACK(on_volumescroll_configure_event), NULL);
g_signal_connect(G_OBJECT(surrscroll), "value_changed",
G_CALLBACK(on_surrscroll_value_changed), NULL);
g_signal_connect(G_OBJECT(surrcheck), "toggled",
G_CALLBACK(on_surrcheck_toggled), NULL);
g_signal_connect(G_OBJECT(excitecheck), "toggled",
G_CALLBACK(on_excitecheck_toggled), NULL);
g_signal_connect(G_OBJECT(stereocheck), "toggled",
G_CALLBACK(on_stereocheck_toggled), NULL);
g_signal_connect(G_OBJECT(ratecombo), "changed",
G_CALLBACK(on_ratecombo_changed), NULL);
g_signal_connect(G_OBJECT(ratecombo), "configure_event",
G_CALLBACK(on_ratecombo_configure_event), NULL);
#ifndef BSD
g_signal_connect(G_OBJECT(sndapicombo), "changed",
G_CALLBACK(on_sndapicombo_changed), NULL);
#endif
//Input
g_signal_connect(G_OBJECT(playerselectcombo), "changed",
G_CALLBACK(playercombo_changed), NULL);
g_signal_connect(G_OBJECT(upbutton), "clicked",
G_CALLBACK(inputcfg_clicked), gpointer(0));
g_signal_connect(G_OBJECT(downbutton), "clicked",
G_CALLBACK(inputcfg_clicked), gpointer(1));
g_signal_connect(G_OBJECT(leftbutton), "clicked",
G_CALLBACK(inputcfg_clicked), gpointer(2));
g_signal_connect(G_OBJECT(rightbutton), "clicked",
G_CALLBACK(inputcfg_clicked), gpointer(3));
g_signal_connect(G_OBJECT(selectbutton), "clicked",
G_CALLBACK(inputcfg_clicked), gpointer(7));
g_signal_connect(G_OBJECT(startbutton), "clicked",
G_CALLBACK(inputcfg_clicked), gpointer(6));
g_signal_connect(G_OBJECT(abutton), "clicked",
G_CALLBACK(inputcfg_clicked), gpointer(4));
g_signal_connect(G_OBJECT(bbutton), "clicked",
G_CALLBACK(inputcfg_clicked), gpointer(5));
g_signal_connect(G_OBJECT(rewindstart), "clicked",
G_CALLBACK(inputcfg_clicked), gpointer(26));
g_signal_connect(G_OBJECT(rewindstop), "clicked",
G_CALLBACK(inputcfg_clicked), gpointer(27));
//Misc
g_signal_connect(G_OBJECT(systemcombo), "changed",
G_CALLBACK(on_systemcombo_changed), NULL);
g_signal_connect(G_OBJECT(spatchcombo), "changed",
G_CALLBACK(on_spatchcombo_changed), NULL);
gtk_widget_show_all(configwindow);
return configwindow;
}
GtkWidget* create_nsfplayer (void) {
// Pause if playing
bool playing = NstIsPlaying();
if (playing) {
schedule_stop = 1;
wasplaying = 1;
}
else { // Set it back to 0 in case the game was paused and the config is opened again
wasplaying = 0;
}
//GtkWidget *nsfplayer;
GtkWidget *nsffixed;
GtkAdjustment *nsfspinbutton_adj;
GtkWidget *nsfspinbutton;
GtkWidget *nsfstop;
GtkWidget *nsfplay;
nsfplayer = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (nsfplayer), "NSF Player");
nsffixed = gtk_fixed_new();
gtk_container_add (GTK_CONTAINER (nsfplayer), nsffixed);
nsfmaker = gtk_label_new ("");
gtk_widget_show (nsfmaker);
gtk_fixed_put (GTK_FIXED (nsffixed), nsfmaker, 8, 64);
gtk_widget_set_size_request (nsfmaker, 320, 24);
nsfauthor = gtk_label_new ("");
gtk_widget_show (nsfauthor);
gtk_fixed_put (GTK_FIXED (nsffixed), nsfauthor, 8, 32);
gtk_widget_set_size_request (nsfauthor, 320, 24);
gtk_label_set_justify (GTK_LABEL (nsfauthor), GTK_JUSTIFY_CENTER);
nsftitle = gtk_label_new ("");
gtk_widget_show (nsftitle);
gtk_fixed_put (GTK_FIXED (nsffixed), nsftitle, 8, 0);
gtk_widget_set_size_request (nsftitle, 320, 24);
gtk_label_set_justify (GTK_LABEL (nsftitle), GTK_JUSTIFY_CENTER);
nsfstop = gtk_button_new_from_stock ("gtk-media-stop");
gtk_fixed_put (GTK_FIXED (nsffixed), nsfstop, 56, 104);
gtk_widget_set_size_request (nsfstop, 96, 32);
nsfplay = gtk_button_new_from_stock ("gtk-media-play");
gtk_fixed_put (GTK_FIXED (nsffixed), nsfplay, 160, 104);
gtk_widget_set_size_request (nsfplay, 88, 32);
nsfspinbutton_adj = gtk_adjustment_new (1, 0, 100, 1, 10, 10);
nsfspinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (nsfspinbutton_adj), 1, 0);
gtk_fixed_put (GTK_FIXED (nsffixed), nsfspinbutton, 272, 104);
gtk_widget_set_size_request (nsfspinbutton, 72, 35);
g_signal_connect (G_OBJECT(nsfspinbutton), "change_value",
G_CALLBACK (on_nsfspinbutton_change_value), NULL);
g_signal_connect (G_OBJECT(nsfspinbutton), "value_changed",
G_CALLBACK (on_nsfspinbutton_value_changed), NULL);
g_signal_connect (G_OBJECT(nsfstop), "clicked",
G_CALLBACK (on_nsfstop_clicked), NULL);
g_signal_connect (G_OBJECT(nsfplay), "clicked",
G_CALLBACK (on_nsfplay_clicked), NULL);
g_signal_connect (G_OBJECT(nsfplayer), "destroy",
G_CALLBACK (on_nsfplayer_destroy), NULL);
gtk_widget_show_all(nsfplayer);
return nsfplayer;
}
GtkWidget* create_about (void) {
char svgpath[1024];
sprintf(svgpath, "%s/icons/nestopia.svg", DATADIR);
// Load the SVG from local source dir if make install hasn't been done
struct stat svgstat;
if (stat(svgpath, &svgstat) == -1) {
sprintf(svgpath, "source/unix/icons/nestopia.svg");
}
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size(svgpath, 192, 192, NULL);
GtkWidget *aboutdialog = gtk_about_dialog_new();
GdkPixbuf *app_icon = get_icon();
gtk_window_set_icon(GTK_WINDOW(aboutdialog), app_icon);
gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(aboutdialog), pixbuf);
gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(aboutdialog), "Nestopia - Undead Edition");
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(aboutdialog), "1.44");
gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(aboutdialog), "An accurate Nintendo Entertainment System Emulator");
gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(aboutdialog), "http://0ldsk00l.ca/");
gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(aboutdialog), "(c) 2012-2013, R. Danbrook\n(c) 2007-2008, R. Belmont\n(c) 2003-2008, Martin Freij\n\nIcon based on art from Trollekop");
g_object_unref(pixbuf), pixbuf = NULL;
gtk_dialog_run(GTK_DIALOG(aboutdialog));
gtk_widget_destroy(aboutdialog);
return aboutdialog;
}
// Ripped this straight out of FCEUX and Gens/GS
unsigned short GDKToSDLKeyval(int gdk_key)
{
if (!(gdk_key & 0xFF00))
{
// ASCII symbol.
// SDL and GDK use the same values for these keys.
// Make sure the key value is lowercase.
gdk_key = tolower(gdk_key);
// Return the key value.
return gdk_key;
}
if (gdk_key & 0xFFFF0000)
{
// Extended X11 key. Not supported by SDL.
#ifdef GDK_WINDOWING_X11
fprintf(stderr, "Unhandled extended X11 key: 0x%08X (%s)", gdk_key, XKeysymToString(gdk_key));
#else
fprintf(stderr, "Unhandled extended key: 0x%08X\n", gdk_key);
#endif
return 0;
}
// Non-ASCII symbol.
static const uint16_t gdk_to_sdl_table[0x100] =
{
// 0x00 - 0x0F
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
SDLK_BACKSPACE, SDLK_TAB, SDLK_RETURN, SDLK_CLEAR,
0x0000, SDLK_RETURN, 0x0000, 0x0000,
// 0x10 - 0x1F
0x0000, 0x0000, 0x0000, SDLK_PAUSE,
SDLK_SCROLLOCK, SDLK_SYSREQ, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, SDLK_ESCAPE,
0x0000, 0x0000, 0x0000, 0x0000,
// 0x20 - 0x2F
SDLK_COMPOSE, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
// 0x30 - 0x3F [Japanese keys]
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
// 0x40 - 0x4F [unused]
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
// 0x50 - 0x5F
SDLK_HOME, SDLK_LEFT, SDLK_UP, SDLK_RIGHT,
SDLK_DOWN, SDLK_PAGEUP, SDLK_PAGEDOWN, SDLK_END,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
// 0x60 - 0x6F
0x0000, SDLK_PRINT, 0x0000, SDLK_INSERT,
SDLK_UNDO, 0x0000, 0x0000, SDLK_MENU,
0x0000, SDLK_HELP, SDLK_BREAK, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
// 0x70 - 0x7F [mostly unused, except for Alt Gr and Num Lock]
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, SDLK_MODE, SDLK_NUMLOCK,
// 0x80 - 0x8F [mostly unused, except for some numeric keypad keys]
SDLK_KP5, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, SDLK_KP_ENTER, 0x0000, 0x0000,
// 0x90 - 0x9F
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, SDLK_KP7, SDLK_KP4, SDLK_KP8,
SDLK_KP6, SDLK_KP2, SDLK_KP9, SDLK_KP3,
SDLK_KP1, SDLK_KP5, SDLK_KP0, SDLK_KP_PERIOD,
// 0xA0 - 0xAF
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, SDLK_KP_MULTIPLY, SDLK_KP_PLUS,
0x0000, SDLK_KP_MINUS, SDLK_KP_PERIOD, SDLK_KP_DIVIDE,
// 0xB0 - 0xBF
SDLK_KP0, SDLK_KP1, SDLK_KP2, SDLK_KP3,
SDLK_KP4, SDLK_KP5, SDLK_KP6, SDLK_KP7,
SDLK_KP8, SDLK_KP9, 0x0000, 0x0000,
0x0000, SDLK_KP_EQUALS, SDLK_F1, SDLK_F2,
// 0xC0 - 0xCF
SDLK_F3, SDLK_F4, SDLK_F5, SDLK_F6,
SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10,
SDLK_F11, SDLK_F12, SDLK_F13, SDLK_F14,
SDLK_F15, 0x0000, 0x0000, 0x0000,
// 0xD0 - 0xDF [L* and R* function keys]
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
// 0xE0 - 0xEF
0x0000, SDLK_LSHIFT, SDLK_RSHIFT, SDLK_LCTRL,
SDLK_RCTRL, SDLK_CAPSLOCK, 0x0000, SDLK_LMETA,
SDLK_RMETA, SDLK_LALT, SDLK_RALT, SDLK_LSUPER,
SDLK_RSUPER, 0x0000, 0x0000, 0x0000,
// 0xF0 - 0xFF [mostly unused, except for Delete]
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, SDLK_DELETE,
};
unsigned short sdl_key = gdk_to_sdl_table[gdk_key & 0xFF];
if (sdl_key == 0)
{
// Unhandled GDK key.
fprintf(stderr, "Unhandled GDK key: 0x%04X (%s)", gdk_key, gdk_keyval_name(gdk_key));
return 0;
}
// ignore pause and screenshot hotkeys since they is handled by GTK+ as accelerators
/*if (sdl_key == Hotkeys[HK_PAUSE] || sdl_key == Hotkeys[HK_SCREENSHOT] ||
sdl_key == Hotkeys[HK_SAVE_STATE] || sdl_key == Hotkeys[HK_LOAD_STATE])
return 0;*/
return sdl_key;
}
// Function adapted from Gens/GS (source/gens/input/input_sdl.c)
gint convertKeypress(GtkWidget *grab, GdkEventKey *event, gpointer user_data)
{
SDL_Event sdlev;
SDLKey sdlkey;
int keystate;
switch (event->type)
{
case GDK_KEY_PRESS:
sdlev.type = SDL_KEYDOWN;
sdlev.key.state = SDL_PRESSED;
keystate = 1;
break;
case GDK_KEY_RELEASE:
sdlev.type = SDL_KEYUP;
sdlev.key.state = SDL_RELEASED;
keystate = 0;
break;
default:
fprintf(stderr, "Unhandled GDK event type: %d", event->type);
return FALSE;
}
// Convert this keypress from GDK to SDL.
sdlkey = (SDLKey)GDKToSDLKeyval(event->keyval);
// Create an SDL event from the keypress.
sdlev.key.keysym.sym = sdlkey;
if (sdlkey != 0)
{
SDL_PushEvent(&sdlev);
// Only let the emulator handle the key event if this window has the input focus.
//if(keystate == 0 || gtk_window_is_active(GTK_WINDOW(mainwindow)))
//{
// #if SDL_VERSION_ATLEAST(1, 3, 0)
// SDL_GetKeyboardState(NULL)[SDL_GetScancodeFromKey(sdlkey)] = keystate;
// #else
SDL_GetKeyState(NULL)[sdlkey] = keystate;
// #endif
//}
}
// Allow GTK+ to process this key.
return FALSE;
}
void set_window_id(char* sdlwindowid) {
//printf("%s\n", sdlwindowid);
sprintf(windowid, "%s", sdlwindowid);
}