mupen64plus-oldsvn/main/gui_gtk/main_gtk.c

1640 lines
61 KiB
C

/***************************************************************************
main_gtk.c - Handles the main window and 'glues' it with other windows
----------------------------------------------------------------------------
Began : Fri Nov 8 2002
Copyright : (C) 2002 by blight
Email : blight@Ashitaka
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "../version.h"
#include "../winlnxdefs.h"
#include "main_gtk.h"
#include "../main.h"
#include "../config.h"
#include "../util.h"
#include "aboutdialog.h"
#include "cheatdialog.h"
#include "configdialog.h"
#include "rombrowser.h"
#include "romproperties.h"
#include "../translate.h"
#include "vcrcomp_dialog.h"
#include "../plugin.h"
#include "../rom.h"
#include "../../r4300/r4300.h"
#include "../../r4300/recomph.h"
#include "../../memory/memory.h"
#include "../savestates.h"
#include "../vcr.h"
#include "../vcr_compress.h"
#ifdef DBG
#include "../../debugger/debugger.h"
#include "debugger/registers.h" //temporary includes for the debugger menu
#include "debugger/breakpoints.h" //these can be removed when the main gui
#include "debugger/regTLB.h" //window no longer needs to know if each
#include "debugger/memedit.h" //debugger window is open
#include "debugger/varlist.h" //
#endif
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <SDL.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <pthread.h> // POSIX Thread library
#include <signal.h> // signals
#include <sys/stat.h>
#ifdef CONFIG_PATH
#include <dirent.h>
#endif
#include "netplay/net_gui.h"
/** function prototypes **/
static void callback_startEmulation(GtkWidget *widget, gpointer data);
static void callback_stopEmulation(GtkWidget *widget, gpointer data);
static void callback_openRom(GtkWidget *widget, gpointer data);
static int create_mainWindow(void);
/** globals **/
SMainWindow g_MainWindow;
static pthread_t g_GuiThread = 0; // main gui thread
/*********************************************************************************************************
* GUI interfaces (declared in ../guifuncs.h)
*/
/** gui_init
* Parse gui-specific arguments, remove them from argument list,
* and create gtk gui in thread-safe manner, but do not display.
*/
void gui_init(int *argc, char ***argv)
{
// init multi-threading support
g_thread_init(NULL);
gdk_threads_init();
// save main gui thread handle
g_GuiThread = pthread_self();
// call gtk to parse arguments
gtk_init(argc, argv);
create_mainWindow();
create_configDialog();
#ifdef VCR_SUPPORT
create_vcrCompDialog();
#endif
create_aboutDialog();
// Netplay dialogs
create_findgames_dialog();
create_creategame_dialog();
create_joingame_dialog();
}
/* gui_display
* Display GUI components to the screen
*/
void gui_display(void)
{
gtk_widget_show_all(g_MainWindow.window);
if(!(config_get_bool("ToolbarVisible",TRUE)))
gtk_widget_hide(g_MainWindow.toolBar);
if(!(config_get_bool("FilterVisible",TRUE)))
gtk_widget_hide(g_MainWindow.filterBar);
if(!(config_get_bool("StatusbarVisible",TRUE)))
gtk_widget_hide(g_MainWindow.statusBarHBox);
}
/* gui_destroy
* Better gui cleanup...
*/
void gui_destroy(void)
{
gtk_widget_destroy( g_MainWindow.window );
gtk_widget_destroy( g_AboutDialog.dialog );
gtk_widget_destroy( g_ConfigDialog.dialog );
gtk_widget_destroy( g_RomPropDialog.dialog );
}
/* gui_main_loop
* give control of thread to gtk
*/
void gui_main_loop(void)
{
gtk_main();
gui_destroy();
gdk_threads_leave();
}
//External pulic function to update rombrowser.
void updaterombrowser( unsigned int roms, unsigned short clear )
{
pthread_t self = pthread_self();
//if we're calling from a thread other than the main gtk thread, take gdk lock
if (!pthread_equal(self, g_GuiThread))
gdk_threads_enter();
rombrowser_refresh(roms, clear);
GUI_PROCESS_QUEUED_EVENTS();
if (!pthread_equal(self, g_GuiThread))
gdk_threads_leave();
return;
}
// prints informational message to status bar
int gui_message(unsigned char messagetype, const char *format, ...)
{
if(!gui_enabled())
return 0;
va_list ap;
char buffer[2049];
pthread_t self = pthread_self();
gint response = 0;
va_start(ap, format);
vsnprintf(buffer, 2048, format, ap);
buffer[2048] = '\0';
va_end(ap);
// If we're calling from a thread other than the main gtk thread, take gdk lock.
if(!pthread_equal(self, g_GuiThread))
gdk_threads_enter();
if(messagetype==0)
{
int counter;
for( counter = 0; counter < strlen(buffer); ++counter )
{
if(buffer[counter]=='\n')
{
buffer[counter]='\0';
break;
}
}
gtk_statusbar_pop(GTK_STATUSBAR(g_MainWindow.statusBar), gtk_statusbar_get_context_id( GTK_STATUSBAR(g_MainWindow.statusBar), "status"));
gtk_statusbar_push(GTK_STATUSBAR(g_MainWindow.statusBar), gtk_statusbar_get_context_id( GTK_STATUSBAR(g_MainWindow.statusBar), "status"), buffer);
}
else if(messagetype>0)
{
GtkWidget *dialog, *hbox, *label, *icon;
hbox = gtk_hbox_new(FALSE, 5);
GtkIconTheme *theme = gtk_icon_theme_get_default();
GdkPixbuf *pixbuf;
if(messagetype==1)
{
dialog = gtk_dialog_new_with_buttons(tr("Error"),
GTK_WINDOW(g_MainWindow.window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_OK, GTK_RESPONSE_NONE,
NULL);
if(check_icon_theme())
{
pixbuf = gtk_icon_theme_load_icon(theme, "dialog-error", 32, 0, NULL);
icon = gtk_image_new_from_pixbuf(pixbuf);
}
else
icon = gtk_image_new_from_file(get_iconpath("32x32/dialog-error.png"));
}
else if(messagetype==2)
{
dialog = gtk_dialog_new_with_buttons(tr("Confirm"),
GTK_WINDOW(g_MainWindow.window),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_YES, GTK_RESPONSE_ACCEPT,
GTK_STOCK_NO, GTK_RESPONSE_REJECT,
NULL);
if(check_icon_theme())
{
pixbuf = gtk_icon_theme_load_icon(theme, "dialog-question", 32, 0, NULL);
icon = gtk_image_new_from_pixbuf(pixbuf);
}
else
icon = gtk_image_new_from_file(get_iconpath("32x32/dialog-question.png"));
}
gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, 0);
label = gtk_label_new(buffer);
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 5);
gtk_widget_show_all(dialog);
if(messagetype==1)
{
g_signal_connect_swapped(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog);
}
else if(messagetype==2)
{
response = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
}
GUI_PROCESS_QUEUED_EVENTS();
if(!pthread_equal(self, g_GuiThread))
gdk_threads_leave();
return response == GTK_RESPONSE_ACCEPT;
}
/*********************************************************************************************************
* callbacks
*/
/** rom **/
// open rom
static void callback_openRom(GtkWidget *widget, gpointer data)
{
GtkWidget *file_chooser;
GtkFileFilter *file_filter;
//We might not need this...
if( g_EmulationThread )
{
if(!gui_message(2, tr("Emulation is running. Do you want to\nstop it and load a rom?")))
return;
callback_stopEmulation( NULL, NULL );
}
/* get rom file from user */
file_chooser = gtk_file_chooser_dialog_new(tr("Open Rom..."),
GTK_WINDOW(g_MainWindow.window),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
// add filter for rom file types
file_filter = gtk_file_filter_new();
gtk_file_filter_set_name(file_filter, "N64 ROM (*.z64, *.v64, *.n64, *.gz, *.zip. *.bz2, *.lzma *.7z)");
gtk_file_filter_add_mime_type(file_filter, "application/x-gzip");
gtk_file_filter_add_mime_type(file_filter, "application/zip");
gtk_file_filter_add_mime_type(file_filter, "application/x-bzip2");
gtk_file_filter_add_mime_type(file_filter, "application/x-7z");
gtk_file_filter_add_pattern(file_filter, "*.[zZ]64");
gtk_file_filter_add_pattern(file_filter, "*.lzma");
gtk_file_filter_add_pattern(file_filter, "*.7z");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser),
file_filter);
// add filter for "all files"
file_filter = gtk_file_filter_new();
gtk_file_filter_set_name(file_filter, "All files (*.*)");
gtk_file_filter_add_pattern(file_filter, "*");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser),
file_filter);
if(gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT)
{
gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
// hide dialog while rom is loading
gtk_widget_hide(file_chooser);
open_rom(filename, 0);
g_free(filename);
}
gtk_widget_destroy (file_chooser);
}
// close rom
static void callback_closeRom(GtkWidget *widget, gpointer data)
{
if(close_rom() == 0)
{
gtk_window_set_title( GTK_WINDOW(g_MainWindow.window), MUPEN_NAME " v" MUPEN_VERSION );
}
}
// reload windows
void reload()
{
// recreate gui
gtk_widget_destroy( g_MainWindow.window );
gtk_widget_destroy( g_AboutDialog.dialog );
gtk_widget_destroy( g_ConfigDialog.dialog );
gtk_widget_destroy( g_RomPropDialog.dialog );
create_mainWindow();
create_aboutDialog();
create_configDialog();
gtk_widget_show_all( g_MainWindow.window );
}
// language selected
static void callback_languageSelected(GtkWidget *widget, gpointer data)
{
const char *name;
widget = data; // ToDo: find out why this is needed
if( !GTK_CHECK_MENU_ITEM(widget)->active )
return;
name = gtk_object_get_data( GTK_OBJECT(widget), "lang name" );
tr_set_language( name );
config_put_string( "Language", name );
reload();
g_romcache.rcstask = RCS_RESCAN;
}
/** emulation **/
// start/continue emulation
static void callback_startEmulation(GtkWidget *widget, gpointer data)
{
if(!rom)
{
GList *list = NULL, *llist = NULL;
cache_entry *entry;
GtkTreeIter iter;
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(g_MainWindow.romDisplay));
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(g_MainWindow.romDisplay));
list = gtk_tree_selection_get_selected_rows (selection, &model);
if(!list) //Nothing selected.
{
if(gui_message(2, tr("There is no Rom loaded. Do you want to load one?")))
callback_openRom(NULL, NULL);
return;
}
else
{
llist = g_list_first(list);
gtk_tree_model_get_iter(model, &iter,(GtkTreePath *) llist->data);
gtk_tree_model_get(model, &iter, 22, &entry, -1);
g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
g_list_free(list);
if(open_rom(entry->filename, entry->archivefile)==0)
startEmulation();
else
return;
}
}
startEmulation();
}
// pause/continue emulation
static void callback_pauseContinueEmulation(GtkWidget *widget, gpointer data)
{
pauseContinueEmulation();
}
// stop emulation
static void callback_stopEmulation( GtkWidget *widget, gpointer data )
{
stopEmulation();
}
// Save State
static void callback_Save( GtkWidget *widget, gpointer data )
{
if( g_EmulationThread )
savestates_job |= SAVESTATE;
}
//Save As
//Need to add default filename here...
static void callback_SaveAs( GtkWidget *widget, gpointer data )
{
if( g_EmulationThread )
{
GtkWidget *file_chooser;
file_chooser = gtk_file_chooser_dialog_new(tr("Save as..."),
GTK_WINDOW(g_MainWindow.window),
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
if(gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT)
{
gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
savestates_select_filename( filename );
savestates_job |= SAVESTATE;
g_free(filename);
}
gtk_widget_destroy (file_chooser);
}
else
{
error_message(tr("Emulation is not running."));
}
}
// Restore
static void callback_Restore( GtkWidget *widget, gpointer data )
{
if( g_EmulationThread )
savestates_job |= LOADSTATE;
}
// Load
static void callback_Load( GtkWidget *widget, gpointer data )
{
if( g_EmulationThread )
{
GtkWidget *file_chooser;
file_chooser = gtk_file_chooser_dialog_new(tr("Load..."),
GTK_WINDOW(g_MainWindow.window),
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
if(gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT)
{
gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
savestates_select_filename( filename );
savestates_job |= LOADSTATE;
g_free(filename);
}
gtk_widget_destroy (file_chooser);
}
else
{
error_message(tr("Emulation is not running."));
}
}
// user changed savestate slot
static void cb_SaveSlotSelected(GtkMenuItem *item, int slot)
{
if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)))
{
if(slot!=savestates_get_slot()) //Only actually change slot when not a GUI update.
savestates_select_slot(slot);
}
}
// user opened save slot menu. Make sure current save slot is selected.
static void cb_UpdateSelectedSlot(GtkMenuItem *item, GSList *slots)
{
unsigned int i, slot;
GtkWidget *slotItem = GTK_WIDGET(g_slist_nth_data(slots, savestates_get_slot()));
for(i=0; i<g_slist_length(slots); i++)
{
GtkWidget *slotItem = GTK_WIDGET(g_slist_nth_data(slots, i));
slot = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(slotItem), "slot_num"));
//Make menu item represent the current selected save slot.
if(slot==savestates_get_slot())
{
if(!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(slotItem)))
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(slotItem), TRUE);
break;
}
}
}
/** Netplay **/
static void callback_netplayFindGamesShow( GtkWidget *widget, gpointer window )
{
show_findgames_dialog();
}
static void callback_netplayCreateGameShow( GtkWidget *widget, gpointer window )
{
show_creategame_dialog();
}
static void callback_netplayJoinGameShow( GtkWidget *widget, gpointer window )
{
show_joingame_dialog();
}
/** configuration **/
// configure
static void callback_configure( GtkWidget *widget, gpointer data )
{
if(g_EmulationThread)
{
if(!gui_message(2, "Cannot configure while emulator is running!\nWould you like to stop the emulator?"))
return;
stopEmulation();
}
gtk_widget_show_all( g_ConfigDialog.dialog );
}
// configure gfx
static void callback_configureVideo( GtkWidget *widget, gpointer data )
{
char *name;
name = plugin_name_by_filename( config_get_string( "Gfx Plugin", "" ) );
if( name )
{
plugin_exec_config( name );
}
else
{
if(gui_message(2, tr("No graphics plugin selected! Do you\nwant to select one?")))
{
gtk_widget_show_all( g_ConfigDialog.dialog );
gtk_notebook_set_page( GTK_NOTEBOOK(g_ConfigDialog.notebook), gtk_notebook_page_num( GTK_NOTEBOOK(g_ConfigDialog.notebook), g_ConfigDialog.configPlugins ) );
}
}
}
// configure audio
static void callback_configureAudio( GtkWidget *widget, gpointer data )
{
char *name;
name = plugin_name_by_filename( config_get_string( "Audio Plugin", "" ) );
if( name )
{
plugin_exec_config( name );
}
else
{
if(gui_message(2, tr("No audio plugin selected! Do you\nwant to select one?")))
{
gtk_widget_show_all( g_ConfigDialog.dialog );
gtk_notebook_set_page( GTK_NOTEBOOK(g_ConfigDialog.notebook), gtk_notebook_page_num( GTK_NOTEBOOK(g_ConfigDialog.notebook), g_ConfigDialog.configPlugins ) );
}
}
}
// configure input
static void callback_configureInput( GtkWidget *widget, gpointer data )
{
char *name;
name = plugin_name_by_filename( config_get_string( "Input Plugin", "" ) );
if( name )
{
plugin_exec_config( name );
}
else
{
if(gui_message(2, tr("No input plugin selected! Do you\nwant to select one?")))
{
gtk_widget_show_all( g_ConfigDialog.dialog );
gtk_notebook_set_page( GTK_NOTEBOOK(g_ConfigDialog.notebook), gtk_notebook_page_num( GTK_NOTEBOOK(g_ConfigDialog.notebook), g_ConfigDialog.configPlugins ) );
}
}
}
// configure RSP
static void callback_configureRSP( GtkWidget *widget, gpointer data )
{
char *name;
name = plugin_name_by_filename( config_get_string( "RSP Plugin", "" ) );
if( name )
{
plugin_exec_config( name );
}
else
{
if(gui_message(2, tr("No RSP plugin selected! Do you\nwant to select one?")))
{
gtk_widget_show_all( g_ConfigDialog.dialog );
gtk_notebook_set_page( GTK_NOTEBOOK(g_ConfigDialog.notebook), gtk_notebook_page_num( GTK_NOTEBOOK(g_ConfigDialog.notebook), g_ConfigDialog.configPlugins ) );
}
}
}
// full screen
static void callback_fullScreen( GtkWidget *widget, gpointer data )
{
if(g_EmulationThread)
{
changeWindow();
}
}
/** VCR **/
#ifdef VCR_SUPPORT
static void callback_vcrStartRecord( GtkWidget *widget, gpointer data )
{
if( g_EmulationThread )
{
GtkWidget *file_chooser;
// get save file from user
file_chooser = gtk_file_chooser_dialog_new(tr("Save Recording"),
GTK_WINDOW(g_MainWindow.window),
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
if(gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT)
{
gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
char full_filename[PATH_MAX];
strncpy(full_filename, filename, PATH_MAX);
// if user didn't provide suffix, append .rec
if(!strstr(filename, "."))
strncat(full_filename, ".rec", PATH_MAX - strlen(full_filename));
if (VCR_startRecord( full_filename ) < 0)
error_message(tr("Couldn't start recording."));
g_free(filename);
}
gtk_widget_destroy (file_chooser);
}
else
{
error_message(tr("Emulation is not running."));
}
}
static void callback_vcrStopRecord( GtkWidget *widget, gpointer data )
{
if( g_EmulationThread )
{
if (VCR_stopRecord() < 0)
error_message(tr("Couldn't stop recording."));
}
else
{
error_message(tr("Emulation is not running."));
}
}
static void callback_vcrStartPlayback( GtkWidget *widget, gpointer data )
{
if( g_EmulationThread )
{
GtkWidget *file_chooser;
GtkFileFilter *file_filter;
// get recording file from user to playback
file_chooser = gtk_file_chooser_dialog_new(tr("Load Recording"),
GTK_WINDOW(g_MainWindow.window),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
// add filter for recording file types
file_filter = gtk_file_filter_new();
gtk_file_filter_set_name(file_filter, "Recording file (*.rec)");
gtk_file_filter_add_pattern(file_filter, "*.[rR][eE][cC]");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser),
file_filter);
// add filter for "all files"
file_filter = gtk_file_filter_new();
gtk_file_filter_set_name(file_filter, "All files (*.*)");
gtk_file_filter_add_pattern(file_filter, "*");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser),
file_filter);
if(gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT)
{
gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
if (VCR_startPlayback( filename ) < 0)
error_message(tr("Couldn't start playback."));
g_free(filename);
}
gtk_widget_destroy (file_chooser);
}
else
{
error_message(tr("Emulation is not running."));
}
}
static void callback_vcrStopPlayback( GtkWidget *widget, gpointer data )
{
if( g_EmulationThread )
{
if (VCR_stopPlayback() < 0)
error_message(tr("Couldn't stop playback."));
}
else
{
error_message(tr("Emulation is not running."));
}
}
static void callback_vcrStartCapture( GtkWidget *widget, gpointer data )
{
if( g_EmulationThread )
{
GtkWidget *file_chooser;
GtkFileFilter *file_filter;
// load recording file to capture
file_chooser = gtk_file_chooser_dialog_new(tr("Load Recording"),
GTK_WINDOW(g_MainWindow.window),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
// add filter for recording file types
file_filter = gtk_file_filter_new();
gtk_file_filter_set_name(file_filter, "Recording file (*.rec)");
gtk_file_filter_add_pattern(file_filter, "*.[rR][eE][cC]");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser),
file_filter);
// add filter for "all files"
file_filter = gtk_file_filter_new();
gtk_file_filter_set_name(file_filter, "All files (*.*)");
gtk_file_filter_add_pattern(file_filter, "*");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser),
file_filter);
if(gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT)
{
gchar *rec_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
gtk_widget_destroy(file_chooser);
// get avi filename from user to save recording to.
file_chooser = gtk_file_chooser_dialog_new(tr("Save as..."),
GTK_WINDOW(g_MainWindow.window),
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
if(gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT)
{
gchar *avi_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
if (VCR_startCapture( rec_filename, avi_filename ) < 0)
error_message(tr("Couldn't start capturing."));
g_free(avi_filename);
}
g_free(rec_filename);
}
gtk_widget_destroy (file_chooser);
}
else
{
error_message(tr("Emulation is not running."));
}
}
static void callback_vcrStopCapture( GtkWidget *widget, gpointer data )
{
if( g_EmulationThread )
{
if (VCR_stopCapture() < 0)
error_message(tr("Couldn't stop capturing."));
}
else
{
error_message(tr("Emulation is not running."));
}
}
static void callback_vcrSetup( GtkWidget *widget, gpointer data )
{
gtk_widget_show_all( g_VcrCompDialog.dialog );
}
#endif // VCR_SUPPORT
static void callback_toggle_toolbar( GtkWidget *widget, gpointer data )
{
if(GTK_WIDGET_VISIBLE(g_MainWindow.toolBar))
gtk_widget_hide(g_MainWindow.toolBar);
else
gtk_widget_show(g_MainWindow.toolBar);
config_put_bool("ToolbarVisible",GTK_WIDGET_VISIBLE(g_MainWindow.toolBar));
}
static void callback_toggle_filter( GtkWidget *widget, gpointer data )
{
if(GTK_WIDGET_VISIBLE(g_MainWindow.filterBar))
{
gtk_entry_set_text(GTK_ENTRY(g_MainWindow.filter),"");
gtk_widget_hide(g_MainWindow.filterBar);
}
else
gtk_widget_show(g_MainWindow.filterBar);
config_put_bool("FilterVisible",GTK_WIDGET_VISIBLE(g_MainWindow.filterBar));
}
static void callback_toggle_statusbar( GtkWidget *widget, gpointer data )
{
if(GTK_WIDGET_VISIBLE(g_MainWindow.statusBarHBox))
gtk_widget_hide(g_MainWindow.statusBarHBox);
else
gtk_widget_show(g_MainWindow.statusBarHBox);
config_put_bool("StatusbarVisible",GTK_WIDGET_VISIBLE(g_MainWindow.statusBarHBox));
}
/** debugger **/
#ifdef DBG
static GtkWidget *debuggerRegistersShow;
static GtkWidget *debuggerBreakpointsShow;
static GtkWidget *debuggerTLBShow;
static GtkWidget *debuggerMemoryShow;
static GtkWidget *debuggerVariablesShow;
// show
static void callback_debuggerEnableToggled( GtkWidget *widget, gpointer data )
{
int emuRestart=0;
if( g_EmulationThread )
{
if(gui_message(2, tr("Emulation needs to be restarted in order\nto activate the debugger. Do you want\nthis to happen?")))
{
callback_stopEmulation( NULL, NULL );
emuRestart=1;
}
}
g_DebuggerEnabled = gtk_check_menu_item_get_active((GtkCheckMenuItem *) widget);
if (g_DebuggerEnabled == TRUE)
{
gtk_widget_set_sensitive( GTK_WIDGET(debuggerRegistersShow), TRUE);
gtk_widget_set_sensitive( GTK_WIDGET(debuggerBreakpointsShow), TRUE);
gtk_widget_set_sensitive( GTK_WIDGET(debuggerTLBShow), TRUE);
gtk_widget_set_sensitive( GTK_WIDGET(debuggerMemoryShow), TRUE);
gtk_widget_set_sensitive( GTK_WIDGET(debuggerVariablesShow), TRUE);
}
else
{
gtk_widget_set_sensitive( GTK_WIDGET(debuggerRegistersShow), FALSE);
gtk_widget_set_sensitive( GTK_WIDGET(debuggerBreakpointsShow), FALSE);
gtk_widget_set_sensitive( GTK_WIDGET(debuggerTLBShow), FALSE);
gtk_widget_set_sensitive( GTK_WIDGET(debuggerMemoryShow), FALSE);
gtk_widget_set_sensitive( GTK_WIDGET(debuggerVariablesShow), FALSE);
}
if (emuRestart==1)
callback_startEmulation(NULL,NULL);
}
static void callback_debuggerWindowShow( GtkWidget *widget, gpointer window )
{
switch((long)window)
{
case 1:
if(registers_opened==0)
init_registers();
break;
case 2:
if(breakpoints_opened==0)
init_breakpoints();
break;
case 3:
if(regTLB_opened==0)
init_TLBwindow();
break;
case 4:
if(memedit_opened==0)
init_memedit();
break;
case 5:
if(varlist_opened==0)
init_varlist();
break;
default:
break;
}
}
#endif // DBG
/** help **/
// about
static void callback_aboutMupen( GtkWidget *widget, gpointer data )
{
gtk_widget_show_all(g_AboutDialog.dialog);
}
/** misc **/
// hide on delete
static gint callback_mainWindowDeleteEvent(GtkWidget *widget, GdkEvent *event, gpointer data)
{
gint width, height, xposition, yposition;
gtk_window_get_size(GTK_WINDOW(g_MainWindow.window), &width, &height);
gtk_window_get_position(GTK_WINDOW(g_MainWindow.window), &xposition, &yposition);
config_put_number("MainWindowWidth",width);
config_put_number("MainWindowHeight",height);
config_put_number("MainWindowXPosition",xposition);
config_put_number("MainWindowYPosition",yposition);
gtk_main_quit();
return TRUE; // undeleteable
}
/*********************************************************************************************************
* gui creation
*/
// static widgets to change their state from emulation thread
static GtkWidget *slotItem;
// menuBar
static int create_menuBar( void )
{
GtkWidget *menuItem;
GtkWidget *fileMenu;
GtkWidget *fileMenuItem;
GtkWidget *emulationMenu;
GtkWidget *emulationMenuItem;
GtkWidget *optionsMenu;
GtkWidget *optionsMenuItem;
#ifdef VCR_SUPPORT
GtkWidget *vcrMenu;
GtkWidget *vcrMenuItem;
#endif
GtkWidget *viewMenu;
GtkWidget *viewMenuItem;
GtkWidget *viewToolbar;
GtkWidget *viewFilter;
GtkWidget *viewStatusbar;
#ifdef DBG
GtkWidget *debuggerMenu;
GtkWidget *debuggerMenuItem;
GtkWidget *debuggerEnableItem;
GtkWidget *debuggerSeparator;
#endif
GtkWidget *helpMenu;
GtkWidget *helpMenuItem;
GtkWidget *fileLoadRomItem;
GtkWidget *fileCloseRomItem;
GtkWidget *fileSeparator1;
GtkWidget *fileLanguageItem;
GtkWidget *fileLanguageMenu;
GtkWidget *fileSeparator2;
GtkWidget *fileExitItem;
GtkWidget *emulationStartItem;
GtkWidget *emulationPauseContinueItem;
GtkWidget *emulationStopItem;
GtkWidget *emulationSeparator1;
GtkWidget *emulationSaveItem;
GtkWidget *emulationSaveAsItem;
GtkWidget *emulationRestoreItem;
GtkWidget *emulationLoadItem;
GtkWidget *emulationSeparator2;
GtkWidget *emulationSlotItem;
GtkWidget *emulationSlotMenu;
GtkWidget *optionsConfigureItem;
GtkWidget *optionsSeparator1;
GtkWidget *optionsVideoItem;
GtkWidget *optionsAudioItem;
GtkWidget *optionsInputItem;
GtkWidget *optionsRSPItem;
GtkWidget *optionsSeparator2;
GtkWidget *optionsCheatsItem;
GtkWidget *optionsFullScreenItem;
#ifdef VCR_SUPPORT
GtkWidget *vcrStartRecordItem;
GtkWidget *vcrStopRecordItem;
GtkWidget *vcrSeparator1;
GtkWidget *vcrStartPlaybackItem;
GtkWidget *vcrStopPlaybackItem;
GtkWidget *vcrSeparator2;
GtkWidget *vcrStartCaptureItem;
GtkWidget *vcrStopCaptureItem;
GtkWidget *vcrSeparator3;
GtkWidget *vcrSetupItem;
#endif
GtkWidget *netplayMenu;
GtkWidget *netplayMenuItem;
GtkWidget *netplayFindGames;
GtkWidget *netplayCreateGame;
GtkWidget *netplayJoinGame;
GtkWidget *helpAboutItem;
GSList *group = NULL;
list_t langList;
list_node_t *node;
char *language;
const char *confLang = config_get_string( "Language", "English" );
int i, lang_found;
// accelerator group
g_MainWindow.accelGroup = gtk_accel_group_new();
g_MainWindow.accelUnsafe = gtk_accel_group_new();
g_MainWindow.accelUnsafeActive = TRUE;
gtk_window_add_accel_group(GTK_WINDOW(g_MainWindow.window), g_MainWindow.accelGroup);
gtk_window_add_accel_group(GTK_WINDOW(g_MainWindow.window), g_MainWindow.accelUnsafe);
// menubar
g_MainWindow.menuBar = gtk_menu_bar_new();
gtk_box_pack_start( GTK_BOX(g_MainWindow.toplevelVBox), g_MainWindow.menuBar, FALSE, FALSE, 0 );
// file menu
fileMenu = gtk_menu_new();
fileMenuItem = gtk_menu_item_new_with_mnemonic(tr("_File"));
gtk_menu_item_set_submenu( GTK_MENU_ITEM(fileMenuItem), fileMenu );
fileLoadRomItem = gtk_menu_item_new_with_mnemonic(tr("_Open Rom..."));
gtk_widget_add_accelerator(fileLoadRomItem, "activate", g_MainWindow.accelGroup,
GDK_o, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
fileCloseRomItem = gtk_menu_item_new_with_mnemonic(tr("_Close Rom"));
fileSeparator1 = gtk_menu_item_new();
gtk_widget_add_accelerator(fileCloseRomItem, "activate", g_MainWindow.accelGroup,
GDK_w, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
fileLanguageItem = gtk_menu_item_new_with_mnemonic(tr("_Language"));
fileSeparator2 = gtk_menu_item_new();
fileExitItem = gtk_menu_item_new_with_mnemonic(tr("_Quit"));
gtk_widget_add_accelerator(fileExitItem, "activate", g_MainWindow.accelGroup,
GDK_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
gtk_menu_append( GTK_MENU(fileMenu), fileLoadRomItem );
gtk_menu_append( GTK_MENU(fileMenu), fileCloseRomItem );
gtk_menu_append( GTK_MENU(fileMenu), fileSeparator1 );
gtk_menu_append( GTK_MENU(fileMenu), fileLanguageItem );
gtk_menu_append( GTK_MENU(fileMenu), fileSeparator2 );
gtk_menu_append( GTK_MENU(fileMenu), fileExitItem );
gtk_signal_connect_object( GTK_OBJECT(fileLoadRomItem), "activate", GTK_SIGNAL_FUNC(callback_openRom), (gpointer)NULL );
gtk_signal_connect_object( GTK_OBJECT(fileCloseRomItem), "activate", GTK_SIGNAL_FUNC(callback_closeRom), (gpointer)NULL );
gtk_signal_connect_object( GTK_OBJECT(fileExitItem), "activate", GTK_SIGNAL_FUNC(callback_mainWindowDeleteEvent), (gpointer)NULL );
// language menu
fileLanguageMenu = gtk_menu_new();
gtk_menu_item_set_submenu( GTK_MENU_ITEM(fileLanguageItem), fileLanguageMenu );
langList = tr_language_list();
// first check if language specified in config file is in langList
lang_found = 0;
list_foreach(langList, node)
{
language = (char *)node->data;
if(!strcasecmp(language, confLang))
lang_found = 1;
}
// if config file language is not supported, default to English
if(!lang_found)
{
printf("Warning: Language \"%s\" unsupported, or maybe the language name has changed.\n", confLang);
config_put_string("Language", "English");
confLang = config_get_string("Language", "English");
}
// create menu item for each language
list_foreach(langList, node)
{
language = (char *)node->data;
fileLanguageItem = gtk_radio_menu_item_new_with_label( group, language );
gtk_object_set_data( GTK_OBJECT(fileLanguageItem), "lang name", language );
group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM(fileLanguageItem) );
if(!strcasecmp(language, confLang))
{
gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(fileLanguageItem), 1 );
tr_set_language(language);
}
gtk_signal_connect_object(GTK_OBJECT(fileLanguageItem), "toggled",
GTK_SIGNAL_FUNC(callback_languageSelected), NULL);
gtk_menu_append(GTK_MENU(fileLanguageMenu), fileLanguageItem );
}
// free language name list
list_delete(&langList);
// emulation menu
emulationMenu = gtk_menu_new();
emulationMenuItem = gtk_menu_item_new_with_mnemonic(tr("_Emulation"));
gtk_menu_item_set_submenu( GTK_MENU_ITEM(emulationMenuItem), emulationMenu );
emulationStartItem = gtk_menu_item_new_with_mnemonic(tr("_Start"));
emulationPauseContinueItem = gtk_menu_item_new_with_mnemonic(tr("_Pause"));
gtk_widget_add_accelerator(emulationPauseContinueItem, "activate", g_MainWindow.accelGroup,
GDK_Pause, 0, GTK_ACCEL_VISIBLE);
emulationStopItem = gtk_menu_item_new_with_mnemonic(tr("S_top"));
gtk_widget_add_accelerator(emulationStopItem, "activate", g_MainWindow.accelGroup,
GDK_Escape, 0, GTK_ACCEL_VISIBLE);
emulationSeparator1 = gtk_menu_item_new();
emulationSaveItem = gtk_menu_item_new_with_mnemonic(tr("Sa_ve State"));
gtk_widget_add_accelerator(emulationSaveItem, "activate", g_MainWindow.accelGroup,
GDK_F5, 0, GTK_ACCEL_VISIBLE);
emulationSaveAsItem = gtk_menu_item_new_with_mnemonic(tr("Save State _as..."));
emulationRestoreItem = gtk_menu_item_new_with_mnemonic(tr("_Restore State"));
gtk_widget_add_accelerator(emulationRestoreItem, "activate", g_MainWindow.accelGroup,
GDK_F7, 0, GTK_ACCEL_VISIBLE);
emulationLoadItem = gtk_menu_item_new_with_mnemonic(tr("_Load State from..."));
emulationSeparator2 = gtk_menu_item_new();
emulationSlotItem = gtk_menu_item_new_with_mnemonic(tr("_Current Save State Slot"));
gtk_menu_append( GTK_MENU(emulationMenu), emulationStartItem );
gtk_menu_append( GTK_MENU(emulationMenu), emulationPauseContinueItem );
gtk_menu_append( GTK_MENU(emulationMenu), emulationStopItem );
gtk_menu_append( GTK_MENU(emulationMenu), emulationSeparator1 );
gtk_menu_append( GTK_MENU(emulationMenu), emulationSaveItem );
gtk_menu_append( GTK_MENU(emulationMenu), emulationSaveAsItem );
gtk_menu_append( GTK_MENU(emulationMenu), emulationRestoreItem );
gtk_menu_append( GTK_MENU(emulationMenu), emulationLoadItem );
gtk_menu_append( GTK_MENU(emulationMenu), emulationSeparator2 );
gtk_menu_append( GTK_MENU(emulationMenu), emulationSlotItem);
g_signal_connect(emulationStartItem, "activate", G_CALLBACK(callback_startEmulation), NULL );
g_signal_connect(emulationPauseContinueItem, "activate", G_CALLBACK(callback_pauseContinueEmulation), NULL );
g_signal_connect(emulationStopItem, "activate", G_CALLBACK(callback_stopEmulation), NULL );
g_signal_connect(emulationSaveItem, "activate", G_CALLBACK(callback_Save), NULL );
g_signal_connect(emulationSaveAsItem, "activate", G_CALLBACK(callback_SaveAs), NULL );
g_signal_connect(emulationRestoreItem, "activate", G_CALLBACK(callback_Restore), NULL );
g_signal_connect(emulationLoadItem, "activate", G_CALLBACK(callback_Load), NULL );
// slot menu
emulationSlotMenu = gtk_menu_new();
gtk_menu_item_set_submenu( GTK_MENU_ITEM(emulationSlotItem), emulationSlotMenu );
slotItem = gtk_radio_menu_item_new(NULL);
char buffer[128];
for (i = 0; i < 10; ++i)
{
snprintf(buffer, 128, tr(" Slot _%d"), i);
slotItem = gtk_radio_menu_item_new_with_mnemonic_from_widget(GTK_RADIO_MENU_ITEM(slotItem), buffer);
g_object_set_data(G_OBJECT(slotItem), "slot_num", GUINT_TO_POINTER(i));
gtk_menu_append(GTK_MENU(emulationSlotMenu), slotItem);
gtk_widget_add_accelerator(slotItem, "activate", g_MainWindow.accelUnsafe, GDK_0+i, 0, GTK_ACCEL_VISIBLE);
g_signal_connect(slotItem, "activate", G_CALLBACK(cb_SaveSlotSelected), GUINT_TO_POINTER(i));
}
// set callback so selected save state slot is updated in the menu everytime it's opened
g_signal_connect(emulationSlotItem, "activate", G_CALLBACK(cb_UpdateSelectedSlot),
gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(slotItem)));
// options menu
optionsMenu = gtk_menu_new();
optionsMenuItem = gtk_menu_item_new_with_mnemonic(tr("_Options"));
gtk_menu_item_set_submenu( GTK_MENU_ITEM(optionsMenuItem), optionsMenu );
optionsConfigureItem = gtk_menu_item_new_with_mnemonic(tr("_Configure..."));
optionsSeparator1 = gtk_menu_item_new();
optionsVideoItem = gtk_menu_item_new_with_mnemonic(tr("_Video Settings..."));
optionsAudioItem = gtk_menu_item_new_with_mnemonic(tr("_Audio Settings..."));
optionsInputItem = gtk_menu_item_new_with_mnemonic(tr("_Input Settings..."));
optionsRSPItem = gtk_menu_item_new_with_mnemonic(tr("_RSP Settings..."));
optionsSeparator2 = gtk_menu_item_new();
optionsCheatsItem = gtk_menu_item_new_with_mnemonic(tr("C_heats..."));
optionsFullScreenItem = gtk_menu_item_new_with_mnemonic(tr("_Full Screen"));
gtk_widget_add_accelerator(optionsFullScreenItem, "activate", g_MainWindow.accelGroup,
GDK_Return, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
gtk_menu_append( GTK_MENU(optionsMenu), optionsConfigureItem );
gtk_menu_append( GTK_MENU(optionsMenu), optionsSeparator1 );
gtk_menu_append( GTK_MENU(optionsMenu), optionsVideoItem );
gtk_menu_append( GTK_MENU(optionsMenu), optionsAudioItem );
gtk_menu_append( GTK_MENU(optionsMenu), optionsInputItem );
gtk_menu_append( GTK_MENU(optionsMenu), optionsRSPItem );
gtk_menu_append( GTK_MENU(optionsMenu), optionsSeparator2 );
gtk_menu_append( GTK_MENU(optionsMenu), optionsCheatsItem );
gtk_menu_append( GTK_MENU(optionsMenu), optionsFullScreenItem );
g_signal_connect(optionsConfigureItem, "activate", G_CALLBACK(callback_configure), NULL );
g_signal_connect(optionsVideoItem, "activate", G_CALLBACK(callback_configureVideo), NULL );
g_signal_connect(optionsAudioItem, "activate", G_CALLBACK(callback_configureAudio), NULL );
g_signal_connect(optionsInputItem, "activate", G_CALLBACK(callback_configureInput), NULL );
g_signal_connect(optionsRSPItem, "activate", G_CALLBACK(callback_configureRSP), NULL );
g_signal_connect(optionsCheatsItem, "activate", G_CALLBACK(cb_cheatDialog), NULL );
g_signal_connect(optionsFullScreenItem, "activate", G_CALLBACK(callback_fullScreen), NULL );
// vcr menu
#ifdef VCR_SUPPORT
vcrMenu = gtk_menu_new();
vcrMenuItem = gtk_menu_item_new_with_mnemonic(tr("_VCR"));
gtk_menu_item_set_submenu( GTK_MENU_ITEM(vcrMenuItem), vcrMenu );
vcrStartRecordItem = gtk_menu_item_new_with_mnemonic(tr("Start _Record..."));
vcrStopRecordItem = gtk_menu_item_new_with_mnemonic(tr("Stop Record"));
vcrSeparator1 = gtk_menu_item_new();
vcrStartPlaybackItem = gtk_menu_item_new_with_mnemonic(tr("Start _Playback..."));
vcrStopPlaybackItem = gtk_menu_item_new_with_mnemonic(tr("Stop Playback"));
vcrSeparator2 = gtk_menu_item_new();
vcrStartCaptureItem = gtk_menu_item_new_with_mnemonic(tr("Start _Capture..."));
vcrStopCaptureItem = gtk_menu_item_new_with_mnemonic(tr("Stop Capture"));
vcrSeparator3 = gtk_menu_item_new();
vcrSetupItem = gtk_menu_item_new_with_mnemonic(tr("Configure Codec..."));
gtk_menu_append( GTK_MENU(vcrMenu), vcrStartRecordItem );
gtk_menu_append( GTK_MENU(vcrMenu), vcrStopRecordItem );
gtk_menu_append( GTK_MENU(vcrMenu), vcrSeparator1 );
gtk_menu_append( GTK_MENU(vcrMenu), vcrStartPlaybackItem );
gtk_menu_append( GTK_MENU(vcrMenu), vcrStopPlaybackItem );
gtk_menu_append( GTK_MENU(vcrMenu), vcrSeparator2 );
gtk_menu_append( GTK_MENU(vcrMenu), vcrStartCaptureItem );
gtk_menu_append( GTK_MENU(vcrMenu), vcrStopCaptureItem );
gtk_menu_append( GTK_MENU(vcrMenu), vcrSeparator3 );
gtk_menu_append( GTK_MENU(vcrMenu), vcrSetupItem );
gtk_signal_connect_object( GTK_OBJECT(vcrStartRecordItem), "activate", GTK_SIGNAL_FUNC(callback_vcrStartRecord), (gpointer)NULL );
gtk_signal_connect_object( GTK_OBJECT(vcrStopRecordItem), "activate", GTK_SIGNAL_FUNC(callback_vcrStopRecord), (gpointer)NULL );
gtk_signal_connect_object( GTK_OBJECT(vcrStartPlaybackItem), "activate", GTK_SIGNAL_FUNC(callback_vcrStartPlayback), (gpointer)NULL );
gtk_signal_connect_object( GTK_OBJECT(vcrStopPlaybackItem), "activate", GTK_SIGNAL_FUNC(callback_vcrStopPlayback), (gpointer)NULL );
gtk_signal_connect_object( GTK_OBJECT(vcrStartCaptureItem), "activate", GTK_SIGNAL_FUNC(callback_vcrStartCapture), (gpointer)NULL );
gtk_signal_connect_object( GTK_OBJECT(vcrStopCaptureItem), "activate", GTK_SIGNAL_FUNC(callback_vcrStopCapture), (gpointer)NULL );
gtk_signal_connect_object( GTK_OBJECT(vcrSetupItem), "activate", GTK_SIGNAL_FUNC(callback_vcrSetup), (gpointer)NULL );
#endif // VCR_SUPPORT
viewMenu = gtk_menu_new();
viewMenuItem = gtk_menu_item_new_with_mnemonic(tr("_View"));
gtk_menu_item_set_submenu( GTK_MENU_ITEM(viewMenuItem), viewMenu );
viewToolbar = gtk_check_menu_item_new_with_mnemonic(tr(" _Toolbar"));
viewFilter = gtk_check_menu_item_new_with_mnemonic(tr(" _Filter"));
viewStatusbar = gtk_check_menu_item_new_with_mnemonic(tr(" _Statusbar"));
if((i=config_get_bool("ToolbarVisible",2))==2)
{
config_put_bool("ToolbarVisible",TRUE);
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(viewToolbar),TRUE);
}
else
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(viewToolbar),i);
if((i=config_get_bool("FilterVisible",2))==2)
{
config_put_bool("FilterVisible",TRUE);
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(viewFilter),TRUE);
}
else
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(viewFilter),i);
if((i=config_get_bool("StatusBarVisible",2))==2)
{
config_put_bool("StatusBarVisible",TRUE);
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(viewStatusbar),TRUE);
}
else
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(viewStatusbar),i);
gtk_signal_connect_object( GTK_OBJECT(viewToolbar), "toggled", GTK_SIGNAL_FUNC(callback_toggle_toolbar), (gpointer)NULL );
gtk_signal_connect_object( GTK_OBJECT(viewFilter), "toggled", GTK_SIGNAL_FUNC(callback_toggle_filter), (gpointer)NULL );
gtk_signal_connect_object( GTK_OBJECT(viewStatusbar), "toggled", GTK_SIGNAL_FUNC(callback_toggle_statusbar), (gpointer)NULL );
gtk_menu_append( GTK_MENU(viewMenu), viewToolbar );
gtk_menu_append( GTK_MENU(viewMenu), viewFilter );
gtk_menu_append( GTK_MENU(viewMenu), viewStatusbar );
// debugger menu
#ifdef DBG
debuggerMenu = gtk_menu_new();
debuggerMenuItem = gtk_menu_item_new_with_mnemonic(tr("_Debugger"));
gtk_menu_item_set_submenu( GTK_MENU_ITEM(debuggerMenuItem), debuggerMenu );
debuggerEnableItem = gtk_check_menu_item_new_with_mnemonic(tr(" _Enable"));
debuggerSeparator = gtk_menu_item_new();
debuggerRegistersShow = gtk_menu_item_new_with_mnemonic(tr("_Registers"));
debuggerBreakpointsShow = gtk_menu_item_new_with_mnemonic(tr("_Breakpoints"));
debuggerTLBShow = gtk_menu_item_new_with_mnemonic(tr("_TLB"));
debuggerMemoryShow = gtk_menu_item_new_with_mnemonic(tr("_Memory"));
debuggerVariablesShow = gtk_menu_item_new_with_mnemonic(tr("_Variables"));
gtk_menu_append( GTK_MENU(debuggerMenu), debuggerEnableItem );
gtk_menu_append( GTK_MENU(debuggerMenu), debuggerSeparator );
gtk_menu_append( GTK_MENU(debuggerMenu), debuggerRegistersShow );
gtk_menu_append( GTK_MENU(debuggerMenu), debuggerBreakpointsShow );
gtk_menu_append( GTK_MENU(debuggerMenu), debuggerTLBShow );
gtk_menu_append( GTK_MENU(debuggerMenu), debuggerMemoryShow );
gtk_menu_append( GTK_MENU(debuggerMenu), debuggerVariablesShow );
if(g_DebuggerEnabled)
gtk_check_menu_item_set_active( (GtkCheckMenuItem *) debuggerEnableItem, TRUE );
else
{
gtk_widget_set_sensitive( GTK_WIDGET(debuggerRegistersShow), FALSE);
gtk_widget_set_sensitive( GTK_WIDGET(debuggerBreakpointsShow), FALSE);
gtk_widget_set_sensitive( GTK_WIDGET(debuggerTLBShow), FALSE);
gtk_widget_set_sensitive( GTK_WIDGET(debuggerMemoryShow), FALSE);
gtk_widget_set_sensitive( GTK_WIDGET(debuggerVariablesShow), FALSE);
}
gtk_signal_connect( GTK_OBJECT(debuggerEnableItem), "toggled", GTK_SIGNAL_FUNC(callback_debuggerEnableToggled), (gpointer)NULL );
gtk_signal_connect( GTK_OBJECT(debuggerRegistersShow), "activate", GTK_SIGNAL_FUNC(callback_debuggerWindowShow), (gpointer)1 );
gtk_signal_connect( GTK_OBJECT(debuggerBreakpointsShow), "activate", GTK_SIGNAL_FUNC(callback_debuggerWindowShow), (gpointer)2 );
gtk_signal_connect( GTK_OBJECT(debuggerTLBShow), "activate", GTK_SIGNAL_FUNC(callback_debuggerWindowShow), (gpointer)3 );
gtk_signal_connect( GTK_OBJECT(debuggerMemoryShow), "activate", GTK_SIGNAL_FUNC(callback_debuggerWindowShow), (gpointer)4 );
gtk_signal_connect( GTK_OBJECT(debuggerVariablesShow), "activate", GTK_SIGNAL_FUNC(callback_debuggerWindowShow), (gpointer)5 );
#endif // DBG
//netplay menu
netplayMenu = gtk_menu_new();
netplayMenuItem = gtk_menu_item_new_with_mnemonic(tr("_Netplay"));
gtk_menu_item_set_submenu( GTK_MENU_ITEM(netplayMenuItem), netplayMenu );
netplayFindGames = gtk_menu_item_new_with_mnemonic(tr("_Find Games..."));
netplayCreateGame = gtk_menu_item_new_with_mnemonic(tr("_Host New Game..."));
netplayJoinGame = gtk_menu_item_new_with_mnemonic(tr("_Join Game..."));
gtk_menu_append( GTK_MENU(netplayMenu), netplayFindGames);
gtk_menu_append( GTK_MENU(netplayMenu), netplayCreateGame);
gtk_menu_append( GTK_MENU(netplayMenu), netplayJoinGame);
gtk_signal_connect( GTK_OBJECT(netplayFindGames), "activate", GTK_SIGNAL_FUNC(callback_netplayFindGamesShow), (gpointer) NULL );
gtk_signal_connect( GTK_OBJECT(netplayCreateGame), "activate", GTK_SIGNAL_FUNC(callback_netplayCreateGameShow), (gpointer) NULL );
gtk_signal_connect( GTK_OBJECT(netplayJoinGame), "activate", GTK_SIGNAL_FUNC(callback_netplayJoinGameShow), (gpointer) NULL );
// help menu
helpMenu = gtk_menu_new();
helpMenuItem = gtk_menu_item_new_with_mnemonic(tr("_Help"));
gtk_menu_item_set_submenu( GTK_MENU_ITEM(helpMenuItem), helpMenu );
helpAboutItem = gtk_menu_item_new_with_mnemonic(tr("_About..."));
gtk_menu_append( GTK_MENU(helpMenu), helpAboutItem );
gtk_signal_connect_object( GTK_OBJECT(helpAboutItem), "activate", GTK_SIGNAL_FUNC(callback_aboutMupen), (gpointer)NULL );
// add menus to menubar
gtk_menu_bar_append( GTK_MENU_BAR(g_MainWindow.menuBar), fileMenuItem );
gtk_menu_bar_append( GTK_MENU_BAR(g_MainWindow.menuBar), emulationMenuItem );
gtk_menu_bar_append( GTK_MENU_BAR(g_MainWindow.menuBar), netplayMenuItem);
gtk_menu_bar_append( GTK_MENU_BAR(g_MainWindow.menuBar), optionsMenuItem );
#ifdef VCR_SUPPORT
gtk_menu_bar_append( GTK_MENU_BAR(g_MainWindow.menuBar), vcrMenuItem );
#endif
gtk_menu_bar_append( GTK_MENU_BAR(g_MainWindow.menuBar), viewMenuItem );
#ifdef DBG
gtk_menu_bar_append( GTK_MENU_BAR(g_MainWindow.menuBar), debuggerMenuItem );
#endif
gtk_menu_bar_append( GTK_MENU_BAR(g_MainWindow.menuBar), helpMenuItem );
return 0;
}
// toolbar
static int create_toolBar( void )
{
GtkWidget *openImage = NULL;
GtkWidget *playImage = NULL;
GtkWidget *pauseImage = NULL;
GtkWidget *stopImage = NULL;
GtkWidget *fullscreenImage = NULL;
GtkWidget *configureImage = NULL;
g_MainWindow.toolBar = gtk_toolbar_new();
gtk_toolbar_set_orientation( GTK_TOOLBAR(g_MainWindow.toolBar), GTK_ORIENTATION_HORIZONTAL );
switch(config_get_number( "ToolbarStyle", 0 ))
{
case 0:
gtk_toolbar_set_style( GTK_TOOLBAR(g_MainWindow.toolBar), GTK_TOOLBAR_ICONS );
break;
case 1:
gtk_toolbar_set_style( GTK_TOOLBAR(g_MainWindow.toolBar), GTK_TOOLBAR_TEXT );
break;
case 2:
gtk_toolbar_set_style( GTK_TOOLBAR(g_MainWindow.toolBar), GTK_TOOLBAR_BOTH );
break;
default:
gtk_toolbar_set_style( GTK_TOOLBAR(g_MainWindow.toolBar), GTK_TOOLBAR_ICONS );
}
gtk_toolbar_set_tooltips( GTK_TOOLBAR(g_MainWindow.toolBar), TRUE );
// load icons from memory
GtkIconTheme *theme = gtk_icon_theme_get_default();
GdkPixbuf *pixbuf;
short size = config_get_number( "ToolbarSize", 22 );
if(check_icon_theme())
{
pixbuf = gtk_icon_theme_load_icon(theme, "document-open", size, 0, NULL);
openImage = gtk_image_new_from_pixbuf(pixbuf);
pixbuf = gtk_icon_theme_load_icon(theme, "media-playback-start", size, 0, NULL);
playImage = gtk_image_new_from_pixbuf(pixbuf);
pixbuf = gtk_icon_theme_load_icon(theme, "media-playback-pause", size, 0, NULL);
pauseImage = gtk_image_new_from_pixbuf(pixbuf);
pixbuf = gtk_icon_theme_load_icon(theme, "media-playback-stop", size, 0, NULL);
stopImage = gtk_image_new_from_pixbuf(pixbuf);
pixbuf = gtk_icon_theme_load_icon(theme, "view-fullscreen", size, 0, NULL);
fullscreenImage = gtk_image_new_from_pixbuf(pixbuf);
pixbuf = gtk_icon_theme_load_icon(theme, "preferences-system", size, 0, NULL);
configureImage = gtk_image_new_from_pixbuf(pixbuf);
}
else if(size==32)
{
openImage = gtk_image_new_from_file(get_iconpath("32x32/document-open.png"));
playImage = gtk_image_new_from_file(get_iconpath("32x32/media-playback-start.png"));
pauseImage = gtk_image_new_from_file(get_iconpath("32x32/media-playback-pause.png"));
stopImage = gtk_image_new_from_file(get_iconpath("32x32/media-playback-stop.png"));
fullscreenImage = gtk_image_new_from_file(get_iconpath("32x32/view-fullscreen.png"));
configureImage = gtk_image_new_from_file(get_iconpath("32x32/preferences-system.png"));
}
else if(size==16)
{
openImage = gtk_image_new_from_file(get_iconpath("16x16/document-open.png"));
playImage = gtk_image_new_from_file(get_iconpath("16x16/media-playback-start.png"));
pauseImage = gtk_image_new_from_file(get_iconpath("16x16/media-playback-pause.png"));
stopImage = gtk_image_new_from_file(get_iconpath("16x16/media-playback-stop.png"));
fullscreenImage = gtk_image_new_from_file(get_iconpath("16x16/view-fullscreen.png"));
configureImage = gtk_image_new_from_file(get_iconpath("16x16/preferences-system.png"));
}
else
{
openImage = gtk_image_new_from_file(get_iconpath("22x22/document-open.png"));
playImage = gtk_image_new_from_file(get_iconpath("22x22/media-playback-start.png"));
pauseImage = gtk_image_new_from_file(get_iconpath("22x22/media-playback-pause.png"));
stopImage = gtk_image_new_from_file(get_iconpath("22x22/media-playback-stop.png"));
fullscreenImage = gtk_image_new_from_file(get_iconpath("22x22/view-fullscreen.png"));
configureImage = gtk_image_new_from_file(get_iconpath("22x22/preferences-system.png"));
}
// add icons to toolbar
gtk_toolbar_append_item(GTK_TOOLBAR(g_MainWindow.toolBar),tr("Open"),tr("Open Rom"),"",openImage,GTK_SIGNAL_FUNC(callback_openRom),NULL);
gtk_toolbar_append_space( GTK_TOOLBAR(g_MainWindow.toolBar) );
gtk_toolbar_append_item( GTK_TOOLBAR(g_MainWindow.toolBar),tr("Start"),tr("Start Emulation"),"",playImage,GTK_SIGNAL_FUNC(callback_startEmulation),NULL);
gtk_toolbar_append_item( GTK_TOOLBAR(g_MainWindow.toolBar),tr("Pause"),tr("Pause/ Continue Emulation"),"",pauseImage,GTK_SIGNAL_FUNC(callback_pauseContinueEmulation),NULL );
gtk_toolbar_append_item( GTK_TOOLBAR(g_MainWindow.toolBar),tr("Stop"),tr("Stop Emulation"),"",stopImage,GTK_SIGNAL_FUNC(callback_stopEmulation),NULL );
gtk_toolbar_append_space( GTK_TOOLBAR(g_MainWindow.toolBar) );
gtk_toolbar_append_item( GTK_TOOLBAR(g_MainWindow.toolBar),tr("Configure"),tr("Configure"),"",configureImage,GTK_SIGNAL_FUNC(callback_configure),NULL );
gtk_toolbar_append_item( GTK_TOOLBAR(g_MainWindow.toolBar),tr("Fullscreen"),tr("Fullscreen"),"",fullscreenImage,GTK_SIGNAL_FUNC(callback_fullScreen),NULL );
gtk_box_pack_start( GTK_BOX(g_MainWindow.toplevelVBox), g_MainWindow.toolBar, FALSE, FALSE, 0 );
return 0;
}
// status bar
static int create_statusBar( void )
{
g_MainWindow.statusBarHBox = gtk_hbox_new( FALSE, 5 );
gtk_box_pack_end( GTK_BOX(g_MainWindow.toplevelVBox), g_MainWindow.statusBarHBox, FALSE, FALSE, 0 );
g_MainWindow.statusBar = gtk_statusbar_new();
gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(g_MainWindow.statusBar), FALSE);
gtk_box_pack_start( GTK_BOX(g_MainWindow.statusBarHBox), g_MainWindow.statusBar, TRUE , TRUE, 0 );
return 0;
}
// main window
static int create_mainWindow( void )
{
int i=config_get_number("RomSortType",16);
if(i!=GTK_SORT_ASCENDING&&i!=GTK_SORT_DESCENDING)
{
g_MainWindow.romSortType = GTK_SORT_ASCENDING;
config_put_number("RomSortType",GTK_SORT_ASCENDING);
}
else
g_MainWindow.romSortType = i;
i=config_get_number("RomSortColumn",17);
if(i<0||i>16)
{
g_MainWindow.romSortColumn = 1;
config_put_number("RomSortColumn",1);
}
else
g_MainWindow.romSortColumn = i;
gint width, height, xposition, yposition;
width = config_get_number("MainWindowWidth",600);
height = config_get_number("MainWindowHeight",400);
xposition = config_get_number("MainWindowXPosition",0);
yposition = config_get_number("MainWindowYPosition",0);
GdkDisplay *display = gdk_display_get_default();
GdkScreen *screen = gdk_display_get_default_screen(display);
gint screenwidth = gdk_screen_get_width(screen);
gint screenheight = gdk_screen_get_height(screen);
if(xposition>screenwidth)
xposition = 0;
if(yposition>screenheight)
yposition = 0;
if(width>screenwidth)
width = 600;
if(height>screenheight)
height = 400;
if((xposition+width)>screenwidth)
xposition = screenwidth - width;
if((yposition+height)>screenheight)
yposition = screenheight - height;
// window
g_MainWindow.window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_window_set_title( GTK_WINDOW(g_MainWindow.window), MUPEN_NAME " v" MUPEN_VERSION );
gtk_window_set_default_size( GTK_WINDOW(g_MainWindow.window), width, height );
gtk_window_move (GTK_WINDOW(g_MainWindow.window), xposition, yposition);
gtk_signal_connect(GTK_OBJECT(g_MainWindow.window), "delete_event", GTK_SIGNAL_FUNC(callback_mainWindowDeleteEvent), (gpointer)NULL);
// toplevel vbox
g_MainWindow.toplevelVBox = gtk_vbox_new( FALSE, 0 );
gtk_container_add( GTK_CONTAINER(g_MainWindow.window), g_MainWindow.toplevelVBox );
// menu
create_menuBar();
// toolbar
create_toolBar();
// Filter
create_filter();
// rombrowser
create_romBrowser();
// rom properties
create_romPropDialog();
// statusbar
create_statusBar();
return 0;
}
//Add a check for all Gtk icons here.
gboolean check_icon_theme()
{
GtkIconTheme *theme = gtk_icon_theme_get_default();
if(gtk_icon_theme_has_icon(theme, "document-open")&&
gtk_icon_theme_has_icon(theme, "media-playback-start")&&
gtk_icon_theme_has_icon(theme, "media-playback-pause")&&
gtk_icon_theme_has_icon(theme, "media-playback-stop")&&
gtk_icon_theme_has_icon(theme, "view-fullscreen")&&
gtk_icon_theme_has_icon(theme, "preferences-system")&&
gtk_icon_theme_has_icon(theme, "video-display")&&
gtk_icon_theme_has_icon(theme, "audio-card")&&
gtk_icon_theme_has_icon(theme, "input-gaming")&&
gtk_icon_theme_has_icon(theme, "dialog-error")&&
gtk_icon_theme_has_icon(theme, "dialog-question"))
return TRUE;
else
return FALSE;
}