mirror of
https://github.com/mupen64plus/mupen64plus-oldsvn.git
synced 2025-04-02 10:52:35 -04:00
1267 lines
53 KiB
C
1267 lines
53 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* Mupen64plus - main_gtk.c *
|
|
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
|
|
* Copyright (C) 2008 Tillin9 *
|
|
* Copyright (C) 2002 Blight *
|
|
* *
|
|
* 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. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
/* main_gtk.c - Handles the main window and 'glues' it with other windows */
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <SDL_thread.h>
|
|
|
|
#include <gtk/gtk.h>
|
|
#include <gdk/gdkkeysyms.h>
|
|
|
|
#include "main_gtk.h"
|
|
#include "aboutdialog.h"
|
|
#include "cheatdialog.h"
|
|
#include "configdialog.h"
|
|
#include "rombrowser.h"
|
|
#include "romproperties.h"
|
|
#include "icontheme.h"
|
|
|
|
#include "../version.h"
|
|
#include "../main.h"
|
|
#include "../config.h"
|
|
#include "../util.h"
|
|
#include "../translate.h"
|
|
#include "../savestates.h"
|
|
#include "../plugin.h"
|
|
#include "../rom.h"
|
|
//TODO#include "../../r4300/r4300.h"
|
|
//TODO#include "../../r4300/recomph.h"
|
|
//TODO#include "../../memory/memory.h"
|
|
//TODO#include "../vcr_old.h"
|
|
//TODO#include "../vcr_compress_old.h"
|
|
|
|
#ifdef DBG
|
|
#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"
|
|
|
|
#include "../../debugger/debugger.h"
|
|
#endif
|
|
|
|
/* Necessary function prototypes. */
|
|
static void callback_start_emulation(GtkWidget* widget, gpointer data);
|
|
static void callback_pause_emulation(GtkWidget* widget, gpointer data);
|
|
static void callback_stop_emulation(GtkWidget* widget, gpointer data);
|
|
static void callback_open_rom(GtkWidget* widget, gpointer data);
|
|
static void callback_theme_changed(GtkWidget* widget, gpointer data);
|
|
static void create_mainWindow(void);
|
|
|
|
/* Globals. */
|
|
SMainWindow g_MainWindow;
|
|
static Uint32 g_GuiThreadID = 0; /* Main gui thread. */
|
|
|
|
/*********************************************************************************************************
|
|
* GUI interfaces.
|
|
*/
|
|
|
|
/* 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)
|
|
{
|
|
/* Initialize multi-threading support. */
|
|
g_thread_init(NULL);
|
|
gdk_threads_init();
|
|
|
|
/* Save main gui thread handle. */
|
|
g_GuiThreadID = SDL_ThreadID();
|
|
|
|
/* Call gtk to parse arguments. */
|
|
gtk_init(argc, argv);
|
|
|
|
/* Set application name. */
|
|
g_set_application_name(MUPEN_NAME);
|
|
|
|
/* Setup gtk theme. */
|
|
GtkIconTheme* icontheme = gtk_icon_theme_get_default();
|
|
g_signal_connect(icontheme, "changed", G_CALLBACK(callback_theme_changed), NULL);
|
|
g_MainWindow.dialogErrorImage = g_MainWindow.dialogQuestionImage = NULL;
|
|
|
|
create_mainWindow();
|
|
create_configDialog();
|
|
create_rom_properties();
|
|
callback_theme_changed(NULL, NULL);
|
|
gui_set_state(GUI_STATE_STOPPED);
|
|
gdk_threads_leave();
|
|
}
|
|
|
|
/* Display GUI components to the screen. */
|
|
void gui_display(void)
|
|
{
|
|
gtk_widget_show_all(g_MainWindow.toplevelVBox);
|
|
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);
|
|
gtk_widget_show(g_MainWindow.window);
|
|
}
|
|
|
|
/* Save GUI window properties and destroy widgets. */
|
|
void gui_destroy(void)
|
|
{
|
|
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_widget_destroy(g_MainWindow.window);
|
|
gtk_widget_destroy(g_ConfigDialog.dialog);
|
|
gtk_widget_destroy(g_RomPropDialog.dialog);
|
|
}
|
|
|
|
/* Give control of thread to gtk. */
|
|
void gui_main_loop(void)
|
|
{
|
|
gtk_main();
|
|
gui_destroy();
|
|
gdk_threads_leave();
|
|
}
|
|
|
|
/* gui_update_rombrowser() accesses g_romcahce.length and adds upto roms to the
|
|
* rombrowser. The clear flag tells the GUI to clear the rombrowser first.
|
|
*/
|
|
void gui_update_rombrowser(unsigned int roms, unsigned short clear)
|
|
{
|
|
Uint32 self = SDL_ThreadID();
|
|
|
|
/* If we're calling from a thread other than the main gtk thread, take gdk lock. */
|
|
if (self != g_GuiThreadID)
|
|
gdk_threads_enter();
|
|
|
|
rombrowser_refresh(roms, clear);
|
|
|
|
if (self != g_GuiThreadID)
|
|
gdk_threads_leave();
|
|
|
|
return;
|
|
}
|
|
|
|
/* Display either an informational message to the status bar, a yes / no confirmation
|
|
* dialog, or an error dialog.
|
|
*/
|
|
int gui_message(gui_message_t messagetype , const char* format, ...)
|
|
{
|
|
if(!gui_enabled()||messagetype>GUI_MESSAGE_ERROR)
|
|
return 0;
|
|
|
|
gint response = 0;
|
|
|
|
va_list ap;
|
|
char buffer[2048];
|
|
va_start(ap, format);
|
|
vsnprintf(buffer, sizeof(buffer), format, ap);
|
|
va_end(ap);
|
|
|
|
/* If we're calling from a thread other than the main gtk thread, take gdk lock. */
|
|
Uint32 self = SDL_ThreadID();
|
|
if(self!=g_GuiThreadID)
|
|
gdk_threads_enter();
|
|
|
|
if(messagetype==GUI_MESSAGE_INFO)
|
|
{
|
|
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
|
|
{
|
|
GtkWidget *dialog, *hbox, *label, *icon;
|
|
|
|
hbox = gtk_hbox_new(FALSE, 10);
|
|
gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
|
|
icon = gtk_image_new();
|
|
|
|
if(messagetype==GUI_MESSAGE_ERROR)
|
|
{
|
|
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);
|
|
|
|
icon = g_MainWindow.dialogErrorImage = gtk_image_new();
|
|
set_icon(g_MainWindow.dialogErrorImage, "dialog-error", 32, FALSE);
|
|
}
|
|
else if(messagetype==GUI_MESSAGE_CONFIRM)
|
|
{
|
|
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);
|
|
|
|
icon = g_MainWindow.dialogErrorImage = gtk_image_new();
|
|
set_icon(g_MainWindow.dialogErrorImage, "dialog-question", 32, FALSE);
|
|
}
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(icon), 0, 0);
|
|
gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, 0);
|
|
|
|
label = gtk_label_new(buffer);
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
|
|
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
|
|
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
|
|
|
|
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show_all(dialog);
|
|
|
|
if(messagetype==GUI_MESSAGE_ERROR)
|
|
g_signal_connect_swapped(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog);
|
|
else if(messagetype==GUI_MESSAGE_CONFIRM)
|
|
{
|
|
response = gtk_dialog_run(GTK_DIALOG(dialog));
|
|
gtk_widget_destroy(dialog);
|
|
}
|
|
}
|
|
|
|
if (self != g_GuiThreadID)
|
|
gdk_threads_leave();
|
|
|
|
return response == GTK_RESPONSE_ACCEPT;
|
|
}
|
|
|
|
/* Depending on emulator state, disable undefined options in menus and on the toolbar. */
|
|
void gui_set_state(gui_state_t state)
|
|
{
|
|
Uint32 self = SDL_ThreadID();
|
|
gboolean enabled, paused;
|
|
|
|
if(!gui_enabled()||state>GUI_STATE_RUNNING)
|
|
return;
|
|
|
|
/* If we're calling from a thread other than the main gtk thread, take gdk lock. */
|
|
if(self!=g_GuiThreadID)
|
|
gdk_threads_enter();
|
|
|
|
if(state==GUI_STATE_STOPPED)
|
|
enabled = paused = FALSE;
|
|
|
|
if(state==GUI_STATE_RUNNING)
|
|
{
|
|
enabled = TRUE;
|
|
paused = FALSE;
|
|
}
|
|
|
|
if(state==GUI_STATE_PAUSED)
|
|
enabled = paused = TRUE;
|
|
|
|
g_signal_handlers_block_by_func(g_MainWindow.playButtonItem, callback_start_emulation, NULL);
|
|
gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(g_MainWindow.playButtonItem), enabled&&!paused);
|
|
g_signal_handlers_unblock_by_func(g_MainWindow.playButtonItem, callback_start_emulation, NULL);
|
|
|
|
g_signal_handlers_block_by_func(g_MainWindow.pauseButtonItem, callback_pause_emulation, NULL);
|
|
gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(g_MainWindow.pauseButtonItem), paused);
|
|
g_signal_handlers_unblock_by_func(g_MainWindow.pauseButtonItem, callback_pause_emulation, NULL);
|
|
|
|
g_signal_handlers_block_by_func(g_MainWindow.stopButtonItem, callback_stop_emulation, NULL);
|
|
gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(g_MainWindow.stopButtonItem), !enabled);
|
|
g_signal_handlers_unblock_by_func(g_MainWindow.stopButtonItem, callback_stop_emulation, NULL);
|
|
|
|
gtk_widget_set_sensitive(g_MainWindow.stopMenuItem, enabled);
|
|
gtk_widget_set_sensitive(g_MainWindow.saveStateMenuItem, enabled);
|
|
gtk_widget_set_sensitive(g_MainWindow.saveStateAsMenuItem, enabled);
|
|
gtk_widget_set_sensitive(g_MainWindow.saveStateAsPJ64MenuItem, enabled);
|
|
gtk_widget_set_sensitive(g_MainWindow.loadStateMenuItem, enabled);
|
|
gtk_widget_set_sensitive(g_MainWindow.loadStateFromMenuItem, enabled);
|
|
gtk_widget_set_sensitive(g_MainWindow.fullscreenMenuItem, enabled);
|
|
gtk_widget_set_sensitive(g_MainWindow.pauseButtonItem, enabled);
|
|
gtk_widget_set_sensitive(g_MainWindow.stopButtonItem, enabled);
|
|
gtk_widget_set_sensitive(g_MainWindow.saveStateButtonItem, enabled);
|
|
gtk_widget_set_sensitive(g_MainWindow.loadStateButtonItem, enabled);
|
|
gtk_widget_set_sensitive(g_MainWindow.fullscreenButtonItem, enabled);
|
|
|
|
if(g_GfxPlugin||enabled)
|
|
gtk_widget_set_sensitive(g_ConfigDialog.graphicsCombo, FALSE);
|
|
else
|
|
gtk_widget_set_sensitive(g_ConfigDialog.graphicsCombo, TRUE);
|
|
|
|
if(g_AudioPlugin||enabled)
|
|
gtk_widget_set_sensitive(g_ConfigDialog.audioCombo, FALSE);
|
|
else
|
|
gtk_widget_set_sensitive(g_ConfigDialog.audioCombo, TRUE);
|
|
|
|
if(g_InputPlugin||enabled)
|
|
gtk_widget_set_sensitive(g_ConfigDialog.inputCombo, FALSE);
|
|
else
|
|
gtk_widget_set_sensitive(g_ConfigDialog.inputCombo, TRUE);
|
|
|
|
if(g_RspPlugin||enabled)
|
|
gtk_widget_set_sensitive(g_ConfigDialog.rspCombo, FALSE);
|
|
else
|
|
gtk_widget_set_sensitive(g_ConfigDialog.rspCombo, TRUE);
|
|
|
|
if (self != g_GuiThreadID)
|
|
gdk_threads_leave();
|
|
}
|
|
|
|
/*********************************************************************************************************
|
|
* Callbacks.
|
|
*/
|
|
|
|
static gint callback_mainWindowDeleteEvent(GtkWidget* widget, GdkEvent* event, gpointer data)
|
|
{
|
|
stopEmulation();
|
|
gtk_main_quit();
|
|
return TRUE; /* Don't delete main window here. */
|
|
}
|
|
|
|
/* If theme changes, update application with images from new theme, or fallbacks. */
|
|
static void callback_theme_changed(GtkWidget* widget, gpointer data)
|
|
{
|
|
gboolean usefallbacks = check_icon_theme();
|
|
short size = config_get_number("ToolbarSize", 22);
|
|
int counter;
|
|
|
|
set_icon(g_MainWindow.openButtonImage, "mupen64cart", size, TRUE);
|
|
set_icon(g_MainWindow.playButtonImage, "media-playback-start", size, FALSE);
|
|
set_icon(g_MainWindow.pauseButtonImage, "media-playback-pause", size, FALSE);
|
|
set_icon(g_MainWindow.stopButtonImage, "media-playback-stop", size, FALSE);
|
|
set_icon(g_MainWindow.saveStateButtonImage, "document-save", size, FALSE);
|
|
set_icon(g_MainWindow.loadStateButtonImage, "document-revert", size, FALSE);
|
|
set_icon(g_MainWindow.configureButtonImage, "preferences-system", size, FALSE);
|
|
set_icon(g_MainWindow.fullscreenButtonImage, "view-fullscreen", size, FALSE);
|
|
|
|
if(GTK_IS_IMAGE(g_MainWindow.dialogErrorImage))
|
|
set_icon(g_MainWindow.dialogErrorImage, "dialog-error", 32, FALSE);
|
|
if(GTK_IS_IMAGE(g_MainWindow.dialogQuestionImage))
|
|
set_icon(g_MainWindow.dialogQuestionImage, "dialog-question", 32, FALSE);
|
|
|
|
set_icon(g_ConfigDialog.graphicsImage, "video-display", 32, FALSE);
|
|
set_icon(g_ConfigDialog.audioImage, "audio-card", 32, FALSE);
|
|
set_icon(g_ConfigDialog.inputImage, "input-gaming", 32, FALSE);
|
|
|
|
set_icon(g_MainWindow.playMenuImage, "media-playback-start", 16, FALSE);
|
|
set_icon(g_MainWindow.pauseMenuImage, "media-playback-pause", 16, FALSE);
|
|
set_icon(g_MainWindow.stopMenuImage, "media-playback-stop", 16, FALSE);
|
|
|
|
set_icon(g_MainWindow.openRomMenuImage, "mupen64cart", 16, TRUE);
|
|
set_icon(g_MainWindow.closeRomMenuImage, "window-close", 16, FALSE);
|
|
set_icon(g_MainWindow.quitMenuImage, "application-exit", 16, FALSE);
|
|
|
|
set_icon(g_MainWindow.configureMenuImage, "preferences-system", 16, FALSE);
|
|
set_icon(g_MainWindow.graphicsMenuImage, "video-display", 16, FALSE);
|
|
set_icon(g_MainWindow.audioMenuImage, "audio-card", 16, FALSE);
|
|
set_icon(g_MainWindow.inputMenuImage, "input-gaming", 16, FALSE);
|
|
set_icon(g_MainWindow.rspMenuImage, "cpu", 16, TRUE);
|
|
set_icon(g_MainWindow.fullscreenMenuImage, "view-fullscreen", 16, FALSE);
|
|
|
|
set_icon(g_MainWindow.saveStateMenuImage, "document-save", 16, FALSE);
|
|
set_icon(g_MainWindow.saveStateAsMenuImage, "document-save-as", 16, FALSE);
|
|
set_icon(g_MainWindow.saveStateAsPJ64MenuImage, "project64", 16, TRUE);
|
|
set_icon(g_MainWindow.loadStateMenuImage, "document-revert", 16, FALSE);
|
|
set_icon(g_MainWindow.loadStateFromMenuImage, "document-open", 16, FALSE);
|
|
|
|
set_icon(g_MainWindow.aboutMenuImage, "gtk-about", 16, FALSE);
|
|
|
|
set_icon(g_MainWindow.playRombrowserImage, "media-playback-start", 16, FALSE);
|
|
set_icon(g_MainWindow.propertiesRombrowserImage, "document-properties", 16, FALSE);
|
|
set_icon(g_MainWindow.refreshRombrowserImage, "view-refresh", 16, FALSE);
|
|
|
|
if(usefallbacks)
|
|
{
|
|
GtkIconTheme* icontheme = gtk_icon_theme_get_default();
|
|
star = gtk_icon_theme_load_icon(icontheme, "gtk-about", 16, 0, NULL);
|
|
}
|
|
else
|
|
star = gdk_pixbuf_new_from_file(get_iconpath("16x16/gtk-about.png"), NULL);
|
|
|
|
staroff = gdk_pixbuf_copy(star);
|
|
gdk_pixbuf_saturate_and_pixelate(star, staroff, 0.1, FALSE);
|
|
|
|
if(g_RomPropDialog.entry)
|
|
{
|
|
for(counter = 0; counter < 5; ++counter)
|
|
{
|
|
if(g_RomPropDialog.entry->inientry->status>counter)
|
|
gtk_image_set_from_pixbuf(GTK_IMAGE(g_RomPropDialog.status[counter]), star);
|
|
else
|
|
gtk_image_set_from_pixbuf(GTK_IMAGE(g_RomPropDialog.status[counter]), staroff);
|
|
}
|
|
}
|
|
|
|
rombrowser_refresh(g_romcache.length, TRUE);
|
|
}
|
|
|
|
/* Ask user to load a rom. If emulation is running, give warning. */
|
|
static void callback_open_rom(GtkWidget* widget, gpointer data)
|
|
{
|
|
if(g_EmulatorRunning)
|
|
{
|
|
if(!gui_message(GUI_MESSAGE_CONFIRM, tr("Emulation is running. Do you want to stop it?\n\nNote: in order to play another rom, you must first stop this one. ")))
|
|
return;
|
|
callback_stop_emulation(NULL, NULL);
|
|
}
|
|
|
|
/* Get rom file from user. */
|
|
GtkWidget* 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. */
|
|
GtkFileFilter* 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));
|
|
gtk_widget_hide(file_chooser); /* Hide dialog while rom is loading. */
|
|
open_rom(filename, 0);
|
|
g_free(filename);
|
|
|
|
if(rom)
|
|
startEmulation();
|
|
}
|
|
|
|
gtk_widget_destroy(file_chooser);
|
|
}
|
|
|
|
static void callback_close_rom(GtkWidget* widget, gpointer data)
|
|
{
|
|
close_rom();
|
|
}
|
|
|
|
/* If a rom is loaded, start emulation. Else attempt to load rom, first from rombrowser
|
|
* then, if none selected, ask the user.
|
|
*/
|
|
static void callback_start_emulation(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)
|
|
{
|
|
if(gui_message(GUI_MESSAGE_CONFIRM, tr("There is no Rom loaded. Do you want to load one?")))
|
|
callback_open_rom(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;
|
|
}
|
|
}
|
|
|
|
gdk_threads_leave();
|
|
startEmulation();
|
|
}
|
|
|
|
static void callback_pause_emulation(GtkWidget* widget, gpointer data)
|
|
{
|
|
gdk_threads_leave();
|
|
pauseContinueEmulation();
|
|
}
|
|
|
|
static void callback_stop_emulation(GtkWidget* widget, gpointer data)
|
|
{
|
|
gdk_threads_leave();
|
|
stopEmulation();
|
|
}
|
|
|
|
static void callback_save_state(GtkWidget* widget, gpointer data)
|
|
{
|
|
if(g_EmulatorRunning)
|
|
savestates_job |= SAVESTATE;
|
|
else
|
|
error_message(tr("Emulation is not running."));
|
|
}
|
|
|
|
/* Save state as. Launch a file chooser so user can specify file. */
|
|
static void callback_save_state_as(GtkWidget* widget, gpointer project64format)
|
|
{
|
|
if(g_EmulatorRunning)
|
|
{
|
|
GtkWidget* file_chooser;
|
|
char* defaultfilename;
|
|
|
|
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);
|
|
|
|
/* Set default filename. */
|
|
if(GPOINTER_TO_UINT(project64format))
|
|
{ defaultfilename = savestates_get_pj64_filename(); }
|
|
else
|
|
{ defaultfilename = savestates_get_filename(); }
|
|
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(file_chooser), defaultfilename);
|
|
free(defaultfilename);
|
|
|
|
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);
|
|
if(GPOINTER_TO_UINT(project64format))
|
|
{ savestates_job |= SAVEPJ64STATE; }
|
|
savestates_job |= SAVESTATE;
|
|
|
|
g_free(filename);
|
|
}
|
|
|
|
gtk_widget_destroy (file_chooser);
|
|
}
|
|
else
|
|
error_message(tr("Emulation is not running."));
|
|
}
|
|
|
|
static void callback_load_state(GtkWidget* widget, gpointer data)
|
|
{
|
|
if(g_EmulatorRunning)
|
|
savestates_job |= LOADSTATE;
|
|
else
|
|
error_message(tr("Emulation is not running."));
|
|
}
|
|
|
|
/* Load state from. Open a file chooser so user can specify file. */
|
|
static void callback_load_state_from(GtkWidget* widget, gpointer data)
|
|
{
|
|
if(g_EmulatorRunning)
|
|
{
|
|
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 callback_change_slot(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 callback_update_slot(GtkMenuItem* item, GSList* slots)
|
|
{
|
|
unsigned int i, slot;
|
|
GtkWidget* slotItem;
|
|
|
|
for(i = 0; i < g_slist_length(slots); i++)
|
|
{
|
|
slotItem = GTK_WIDGET(g_slist_nth_data(slots, i));
|
|
slot = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(slotItem), "slot_num"));
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void callback_configure(GtkWidget* widget, gpointer data)
|
|
{
|
|
show_configure();
|
|
}
|
|
|
|
static void callback_configure_graphics(GtkWidget* widget, gpointer data)
|
|
{
|
|
char* name = plugin_name_by_filename(config_get_string("Gfx Plugin", ""));
|
|
if(name)
|
|
plugin_exec_config(name);
|
|
else
|
|
{
|
|
if(gui_message(GUI_MESSAGE_CONFIRM, tr("No graphics plugin selected! Do you\nwant to select one?")))
|
|
{
|
|
gtk_notebook_set_page(GTK_NOTEBOOK(g_ConfigDialog.notebook), gtk_notebook_page_num(GTK_NOTEBOOK(g_ConfigDialog.notebook), g_ConfigDialog.configPlugins));
|
|
gtk_widget_show_all(g_ConfigDialog.dialog);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void callback_configure_audio(GtkWidget* widget, gpointer data)
|
|
{
|
|
char* name = plugin_name_by_filename(config_get_string("Audio Plugin", ""));
|
|
if(name)
|
|
plugin_exec_config(name);
|
|
else
|
|
{
|
|
if(gui_message(GUI_MESSAGE_CONFIRM, tr("No audio plugin selected! Do you\nwant to select one?")))
|
|
{
|
|
gtk_notebook_set_page(GTK_NOTEBOOK(g_ConfigDialog.notebook), gtk_notebook_page_num(GTK_NOTEBOOK(g_ConfigDialog.notebook), g_ConfigDialog.configPlugins));
|
|
gtk_widget_show_all(g_ConfigDialog.dialog);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void callback_configure_input(GtkWidget* widget, gpointer data)
|
|
{
|
|
char* name = plugin_name_by_filename(config_get_string("Input Plugin", ""));
|
|
if(name)
|
|
plugin_exec_config(name);
|
|
else
|
|
{
|
|
if(gui_message(GUI_MESSAGE_CONFIRM, tr("No input plugin selected! Do you\nwant to select one?")))
|
|
{
|
|
gtk_notebook_set_page(GTK_NOTEBOOK(g_ConfigDialog.notebook), gtk_notebook_page_num(GTK_NOTEBOOK(g_ConfigDialog.notebook), g_ConfigDialog.configPlugins));
|
|
gtk_widget_show_all(g_ConfigDialog.dialog);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void callback_configure_rsp(GtkWidget* widget, gpointer data)
|
|
{
|
|
char* name = plugin_name_by_filename(config_get_string("RSP Plugin", ""));
|
|
if(name)
|
|
plugin_exec_config(name);
|
|
else
|
|
{
|
|
if(gui_message(GUI_MESSAGE_CONFIRM, tr("No RSP plugin selected! Do you\nwant to select one?")))
|
|
{
|
|
gtk_notebook_set_page(GTK_NOTEBOOK(g_ConfigDialog.notebook), gtk_notebook_page_num(GTK_NOTEBOOK(g_ConfigDialog.notebook), g_ConfigDialog.configPlugins));
|
|
gtk_widget_show_all(g_ConfigDialog.dialog);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Enter full screen mode. */
|
|
static void callback_fullscreen(GtkWidget* widget, gpointer data)
|
|
{
|
|
if(g_EmulatorRunning)
|
|
changeWindow();
|
|
}
|
|
|
|
static void callback_toggle_view(GtkWidget* widget, gpointer data)
|
|
{
|
|
GtkWidget* toggle_object = NULL;
|
|
switch(GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(widget), "toggle_object")))
|
|
{
|
|
case TOOLBAR:
|
|
toggle_object = g_MainWindow.toolBar;
|
|
config_put_bool("ToolbarVisible", !GTK_WIDGET_VISIBLE(g_MainWindow.toolBar));
|
|
break;
|
|
case FILTER:
|
|
toggle_object = g_MainWindow.filterBar;
|
|
gtk_entry_set_text(GTK_ENTRY(g_MainWindow.filter),"");
|
|
config_put_bool("FilterVisible", !GTK_WIDGET_VISIBLE(g_MainWindow.filterBar));
|
|
break;
|
|
case STATUSBAR:
|
|
toggle_object = g_MainWindow.statusBarHBox;
|
|
config_put_bool("StatusbarVisible", !GTK_WIDGET_VISIBLE(g_MainWindow.statusBarHBox));
|
|
break;
|
|
}
|
|
|
|
if(toggle_object==NULL)
|
|
return;
|
|
|
|
if(GTK_WIDGET_VISIBLE(toggle_object))
|
|
gtk_widget_hide(toggle_object);
|
|
else
|
|
gtk_widget_show(toggle_object);
|
|
}
|
|
|
|
static void callback_update_check_item(GtkWidget* widget, gpointer data)
|
|
{
|
|
GtkWidget* toggle_object = NULL;
|
|
switch(GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(widget), "toggle_object")))
|
|
{
|
|
case TOOLBAR:
|
|
toggle_object = g_MainWindow.toolBar;
|
|
break;
|
|
case FILTER:
|
|
toggle_object = g_MainWindow.filterBar;
|
|
break;
|
|
case STATUSBAR:
|
|
toggle_object = g_MainWindow.statusBarHBox;
|
|
break;
|
|
}
|
|
|
|
if(toggle_object==NULL)
|
|
return;
|
|
|
|
g_signal_handlers_block_by_func(widget, callback_toggle_view, NULL);
|
|
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), GTK_WIDGET_VISIBLE(toggle_object));
|
|
g_signal_handlers_unblock_by_func(widget, callback_toggle_view, NULL);
|
|
}
|
|
|
|
static void callback_update_view(GtkWidget* widget, gpointer data)
|
|
{
|
|
gtk_container_foreach(GTK_CONTAINER(widget), callback_update_check_item, NULL);
|
|
}
|
|
|
|
#ifdef DBG
|
|
static GtkWidget* debuggerRegistersShow;
|
|
static GtkWidget* debuggerBreakpointsShow;
|
|
static GtkWidget* debuggerTLBShow;
|
|
static GtkWidget* debuggerMemoryShow;
|
|
static GtkWidget* debuggerVariablesShow;
|
|
|
|
static void callback_debuggerEnableToggled(GtkWidget* widget, gpointer data)
|
|
{
|
|
int emuRestart = 0;
|
|
|
|
if(g_EmulatorRunning)
|
|
{
|
|
if(gui_message(GUI_MESSAGE_CONFIRM, tr("Emulation needs to be restarted in order\nto activate the debugger. Do you want\nthis to happen?")))
|
|
{
|
|
callback_stop_emulation(NULL, NULL);
|
|
emuRestart = 1;
|
|
}
|
|
}
|
|
|
|
g_DebuggerEnabled = gtk_check_menu_item_get_active((GtkCheckMenuItem*)widget);
|
|
|
|
gtk_widget_set_sensitive(debuggerRegistersShow, g_DebuggerEnabled);
|
|
gtk_widget_set_sensitive(debuggerBreakpointsShow, g_DebuggerEnabled);
|
|
gtk_widget_set_sensitive(debuggerTLBShow, g_DebuggerEnabled);
|
|
gtk_widget_set_sensitive(debuggerMemoryShow, g_DebuggerEnabled);
|
|
gtk_widget_set_sensitive(debuggerVariablesShow, g_DebuggerEnabled);
|
|
|
|
if(emuRestart==1)
|
|
callback_start_emulation(NULL, NULL);
|
|
}
|
|
|
|
static void callback_debuggerWindowShow(GtkWidget* widget, gpointer window)
|
|
{
|
|
switch(GPOINTER_TO_UINT(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;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/*********************************************************************************************************
|
|
* GUI creation.
|
|
*/
|
|
|
|
static void create_menubar(void)
|
|
{
|
|
GtkWidget* menu;
|
|
GtkWidget* menuitem;
|
|
GtkWidget* item;
|
|
GtkWidget* submenu;
|
|
GtkWidget* submenuitem;
|
|
int i;
|
|
|
|
/* Create toggable accelerator groups. */
|
|
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);
|
|
|
|
g_MainWindow.menuBar = gtk_menu_bar_new();
|
|
gtk_box_pack_start(GTK_BOX(g_MainWindow.toplevelVBox), g_MainWindow.menuBar, FALSE, FALSE, 0);
|
|
|
|
/* File menu. */
|
|
menu = gtk_menu_new();
|
|
menuitem = gtk_menu_item_new_with_mnemonic(tr("_File"));
|
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menu);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(g_MainWindow.menuBar), menuitem);
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(tr("_Open Rom..."));
|
|
g_MainWindow.openRomMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), g_MainWindow.openRomMenuImage);
|
|
gtk_widget_add_accelerator(item, "activate", g_MainWindow.accelGroup, GDK_o, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
|
g_signal_connect(item, "activate", G_CALLBACK(callback_open_rom), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(tr("_Close Rom"));
|
|
g_MainWindow.closeRomMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), g_MainWindow.closeRomMenuImage);
|
|
gtk_widget_add_accelerator(item, "activate", g_MainWindow.accelGroup, GDK_w, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
|
g_signal_connect(item, "activate", G_CALLBACK(callback_close_rom), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
|
|
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(tr("_Quit"));
|
|
g_MainWindow.quitMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), g_MainWindow.quitMenuImage);
|
|
gtk_widget_add_accelerator(item, "activate", g_MainWindow.accelGroup, GDK_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
|
g_signal_connect(item, "activate", G_CALLBACK(callback_mainWindowDeleteEvent), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
|
|
|
|
/* Emulation menu. */
|
|
menu = gtk_menu_new();
|
|
menuitem = gtk_menu_item_new_with_mnemonic(tr("_Emulation"));
|
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menu);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(g_MainWindow.menuBar), menuitem);
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(tr("_Start"));
|
|
g_MainWindow.playMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), g_MainWindow.playMenuImage);
|
|
g_signal_connect(item, "activate", G_CALLBACK(callback_start_emulation), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
|
|
|
|
g_MainWindow.pauseMenuItem = gtk_image_menu_item_new_with_mnemonic(tr("_Pause"));
|
|
g_MainWindow.pauseMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(g_MainWindow.pauseMenuItem), g_MainWindow.pauseMenuImage);
|
|
gtk_widget_add_accelerator(g_MainWindow.pauseMenuItem, "activate", g_MainWindow.accelGroup, GDK_Pause, 0, GTK_ACCEL_VISIBLE);
|
|
g_signal_connect(g_MainWindow.pauseMenuItem, "activate", G_CALLBACK(callback_pause_emulation), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), g_MainWindow.pauseMenuItem);
|
|
|
|
g_MainWindow.stopMenuItem = gtk_image_menu_item_new_with_mnemonic(tr("S_top"));
|
|
g_MainWindow.stopMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(g_MainWindow.stopMenuItem), g_MainWindow.stopMenuImage);
|
|
gtk_widget_add_accelerator(g_MainWindow.stopMenuItem, "activate", g_MainWindow.accelGroup, GDK_Escape, 0, GTK_ACCEL_VISIBLE);
|
|
g_signal_connect(g_MainWindow.stopMenuItem, "activate", G_CALLBACK(callback_stop_emulation), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), g_MainWindow.stopMenuItem);
|
|
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
|
|
|
|
g_MainWindow.saveStateMenuItem = gtk_image_menu_item_new_with_mnemonic(tr("Sa_ve State"));
|
|
g_MainWindow.saveStateMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(g_MainWindow.saveStateMenuItem), g_MainWindow.saveStateMenuImage);
|
|
gtk_widget_add_accelerator(g_MainWindow.saveStateMenuItem, "activate", g_MainWindow.accelGroup, GDK_F5, 0, GTK_ACCEL_VISIBLE);
|
|
g_signal_connect(g_MainWindow.saveStateMenuItem, "activate", G_CALLBACK(callback_save_state), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), g_MainWindow.saveStateMenuItem);
|
|
|
|
g_MainWindow.saveStateAsMenuItem = gtk_image_menu_item_new_with_mnemonic(tr("Save State _as..."));
|
|
g_MainWindow.saveStateAsMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(g_MainWindow.saveStateAsMenuItem), g_MainWindow.saveStateAsMenuImage);
|
|
g_signal_connect(g_MainWindow.saveStateAsMenuItem, "activate", G_CALLBACK(callback_save_state_as), GUINT_TO_POINTER(FALSE));
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), g_MainWindow.saveStateAsMenuItem);
|
|
|
|
g_MainWindow.saveStateAsPJ64MenuItem = gtk_image_menu_item_new_with_mnemonic(tr("Save P_roject64 State as..."));
|
|
g_MainWindow.saveStateAsPJ64MenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(g_MainWindow.saveStateAsPJ64MenuItem), g_MainWindow.saveStateAsPJ64MenuImage);
|
|
g_signal_connect(g_MainWindow.saveStateAsPJ64MenuItem, "activate", G_CALLBACK(callback_save_state_as), GUINT_TO_POINTER(TRUE));
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), g_MainWindow.saveStateAsPJ64MenuItem);
|
|
|
|
|
|
g_MainWindow.loadStateMenuItem = gtk_image_menu_item_new_with_mnemonic(tr("_Load State"));
|
|
g_MainWindow.loadStateMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(g_MainWindow.loadStateMenuItem), g_MainWindow.loadStateMenuImage);
|
|
gtk_widget_add_accelerator(g_MainWindow.loadStateMenuItem, "activate", g_MainWindow.accelGroup, GDK_F7, 0, GTK_ACCEL_VISIBLE);
|
|
g_signal_connect(g_MainWindow.loadStateMenuItem, "activate", G_CALLBACK(callback_load_state), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), g_MainWindow.loadStateMenuItem);
|
|
|
|
g_MainWindow.loadStateFromMenuItem = gtk_image_menu_item_new_with_mnemonic(tr("L_oad State from..."));
|
|
g_MainWindow.loadStateFromMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(g_MainWindow.loadStateFromMenuItem), g_MainWindow.loadStateFromMenuImage);
|
|
g_signal_connect(g_MainWindow.loadStateFromMenuItem, "activate", G_CALLBACK(callback_load_state_from), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), g_MainWindow.loadStateFromMenuItem);
|
|
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
|
|
|
|
/* Slot submenu. */
|
|
submenuitem = gtk_menu_item_new_with_mnemonic(tr("_Current Save State Slot"));
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), submenuitem);
|
|
submenu = gtk_menu_new();
|
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenuitem), submenu);
|
|
|
|
item = gtk_radio_menu_item_new(NULL);
|
|
char buffer[128];
|
|
for(i = 0; i < 10; ++i)
|
|
{
|
|
snprintf(buffer, 128, tr(" Slot _%d"), i); /* Mnemonic needed even with accelerator. */
|
|
|
|
item = gtk_radio_menu_item_new_with_mnemonic_from_widget(GTK_RADIO_MENU_ITEM(item), buffer);
|
|
g_object_set_data(G_OBJECT(item), "slot_num", GUINT_TO_POINTER(i));
|
|
gtk_widget_add_accelerator(item, "activate", g_MainWindow.accelUnsafe, GDK_0+i, 0, GTK_ACCEL_VISIBLE);
|
|
g_signal_connect(item, "activate", G_CALLBACK(callback_change_slot), GUINT_TO_POINTER(i));
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item);
|
|
}
|
|
|
|
/* Set callback so save state slot menu is updated everytime it's opened. */
|
|
g_signal_connect(submenuitem, "activate", G_CALLBACK(callback_update_slot), gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item)));
|
|
|
|
/* Options menu. */
|
|
menu = gtk_menu_new();
|
|
menuitem = gtk_menu_item_new_with_mnemonic(tr("_Options"));
|
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menu);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(g_MainWindow.menuBar), menuitem);
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(tr("_Configure..."));
|
|
g_MainWindow.configureMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), g_MainWindow.configureMenuImage);
|
|
g_signal_connect(item, "activate", G_CALLBACK(callback_configure), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
|
|
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(tr("_Graphics Settings..."));
|
|
g_MainWindow.graphicsMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), g_MainWindow.graphicsMenuImage);
|
|
g_signal_connect(item, "activate", G_CALLBACK(callback_configure_graphics), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(tr("_Audio Settings..."));
|
|
g_MainWindow.audioMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), g_MainWindow.audioMenuImage);
|
|
g_signal_connect(item, "activate", G_CALLBACK(callback_configure_audio), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(tr("_Input Settings..."));
|
|
g_MainWindow.inputMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), g_MainWindow.inputMenuImage);
|
|
g_signal_connect(item, "activate", G_CALLBACK(callback_configure_input), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(tr("_RSP Settings..."));
|
|
g_MainWindow.rspMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), g_MainWindow.rspMenuImage);
|
|
g_signal_connect(item, "activate", G_CALLBACK(callback_configure_rsp), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
|
|
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
|
|
|
|
item = gtk_menu_item_new_with_mnemonic(tr("C_heats..."));
|
|
g_signal_connect(item, "activate", G_CALLBACK(cb_cheatDialog), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
|
|
|
|
g_MainWindow.fullscreenMenuItem = gtk_image_menu_item_new_with_mnemonic(tr("_Full Screen"));
|
|
g_MainWindow.fullscreenMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(g_MainWindow.fullscreenMenuItem), g_MainWindow.fullscreenMenuImage);
|
|
gtk_widget_add_accelerator(g_MainWindow.fullscreenMenuItem, "activate", g_MainWindow.accelGroup, GDK_Return, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
|
|
g_signal_connect(item, "activate", G_CALLBACK(callback_fullscreen), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), g_MainWindow.fullscreenMenuItem);
|
|
|
|
/* View menu. */
|
|
menu = gtk_menu_new();
|
|
menuitem = gtk_menu_item_new_with_mnemonic(tr("_View"));
|
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menu);
|
|
g_signal_connect_object(menuitem, "activate", G_CALLBACK(callback_update_view), menu, G_CONNECT_SWAPPED);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(g_MainWindow.menuBar), menuitem);
|
|
|
|
/* Note: we must use embedded data since g_callbacks don't reference pointers
|
|
and not all widgets have been created. */
|
|
item = gtk_check_menu_item_new_with_mnemonic(tr(" _Toolbar"));
|
|
g_object_set_data(G_OBJECT(item), "toggle_object", GUINT_TO_POINTER(TOOLBAR));
|
|
g_signal_connect(item, "toggled", G_CALLBACK(callback_toggle_view), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
|
|
|
|
item = gtk_check_menu_item_new_with_mnemonic(tr(" _Filter"));
|
|
g_object_set_data(G_OBJECT(item), "toggle_object", GUINT_TO_POINTER(FILTER));
|
|
g_signal_connect(item, "toggled", G_CALLBACK(callback_toggle_view), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
|
|
|
|
item = gtk_check_menu_item_new_with_mnemonic(tr(" _Statusbar"));
|
|
g_object_set_data(G_OBJECT(item), "toggle_object", GUINT_TO_POINTER(STATUSBAR));
|
|
g_signal_connect(item, "toggled", G_CALLBACK(callback_toggle_view), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
|
|
|
|
/* Debugger submenu. */
|
|
#ifdef DBG
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
|
|
|
|
GtkWidget* debuggerMenu;
|
|
GtkWidget* debuggerMenuItem;
|
|
|
|
debuggerMenu = gtk_menu_new();
|
|
debuggerMenuItem = gtk_menu_item_new_with_mnemonic(tr("_Debugger"));
|
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(debuggerMenuItem), debuggerMenu);
|
|
|
|
item = gtk_check_menu_item_new_with_mnemonic(tr(" _Enable"));
|
|
g_signal_connect(item, "toggled", G_CALLBACK(callback_debuggerEnableToggled), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(debuggerMenu), item);
|
|
|
|
debuggerRegistersShow = gtk_menu_item_new_with_mnemonic(tr("_Registers"));
|
|
g_signal_connect(debuggerRegistersShow, "activate", G_CALLBACK(callback_debuggerWindowShow), (gpointer)1);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(debuggerMenu), debuggerRegistersShow);
|
|
|
|
debuggerBreakpointsShow = gtk_menu_item_new_with_mnemonic(tr("_Breakpoints"));
|
|
g_signal_connect(debuggerBreakpointsShow, "activate", G_CALLBACK(callback_debuggerWindowShow), (gpointer)2);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(debuggerMenu), debuggerBreakpointsShow);
|
|
|
|
debuggerTLBShow = gtk_menu_item_new_with_mnemonic(tr("_TLB"));
|
|
g_signal_connect(debuggerTLBShow, "activate", G_CALLBACK(callback_debuggerWindowShow), (gpointer)3);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(debuggerMenu), debuggerTLBShow);
|
|
|
|
debuggerMemoryShow = gtk_menu_item_new_with_mnemonic(tr("_Memory"));
|
|
g_signal_connect(debuggerMemoryShow, "activate", G_CALLBACK(callback_debuggerWindowShow), (gpointer)4);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(debuggerMenu), debuggerMemoryShow);
|
|
|
|
debuggerVariablesShow = gtk_menu_item_new_with_mnemonic(tr("_Variables"));
|
|
g_signal_connect(debuggerVariablesShow, "activate", G_CALLBACK(callback_debuggerWindowShow), (gpointer)5);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(debuggerMenu), debuggerVariablesShow);
|
|
|
|
if(g_DebuggerEnabled)
|
|
gtk_check_menu_item_set_active((GtkCheckMenuItem*)item, 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_menu_shell_append(GTK_MENU_SHELL(menu), debuggerMenuItem);
|
|
#endif
|
|
|
|
/* Help menu. */
|
|
menu = gtk_menu_new();
|
|
menuitem = gtk_menu_item_new_with_mnemonic(tr("_Help"));
|
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menu);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(g_MainWindow.menuBar), menuitem);
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(tr("_About..."));
|
|
g_MainWindow.aboutMenuImage = gtk_image_new();
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), g_MainWindow.aboutMenuImage);
|
|
g_signal_connect(item, "activate", G_CALLBACK(callback_about_mupen64plus), NULL);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
|
|
}
|
|
|
|
static void create_toolbar(void)
|
|
{
|
|
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 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);
|
|
|
|
g_MainWindow.openButtonImage = gtk_image_new();
|
|
g_MainWindow.playButtonImage = gtk_image_new();
|
|
g_MainWindow.pauseButtonImage = gtk_image_new();
|
|
g_MainWindow.stopButtonImage = gtk_image_new();
|
|
g_MainWindow.saveStateButtonImage = gtk_image_new();
|
|
g_MainWindow.loadStateButtonImage = gtk_image_new();
|
|
g_MainWindow.fullscreenButtonImage = gtk_image_new();
|
|
g_MainWindow.configureButtonImage = gtk_image_new();
|
|
|
|
GtkToolItem* item;
|
|
|
|
/* Add icons to toolbar. */
|
|
item = gtk_tool_button_new(g_MainWindow.openButtonImage, tr("Open Rom"));
|
|
gtk_widget_set_tooltip_text(GTK_WIDGET(item), tr("Open Rom"));
|
|
g_signal_connect(item, "clicked", G_CALLBACK(callback_open_rom), NULL);
|
|
gtk_toolbar_insert(GTK_TOOLBAR(g_MainWindow.toolBar), item, 0);
|
|
|
|
gtk_toolbar_insert(GTK_TOOLBAR(g_MainWindow.toolBar), gtk_separator_tool_item_new(), 1);
|
|
|
|
g_MainWindow.playButtonItem = GTK_WIDGET(gtk_toggle_tool_button_new());
|
|
gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(g_MainWindow.playButtonItem), g_MainWindow.playButtonImage);
|
|
gtk_tool_button_set_label(GTK_TOOL_BUTTON(g_MainWindow.playButtonItem), tr("Start"));
|
|
gtk_widget_set_tooltip_text(g_MainWindow.playButtonItem, tr("Start Emulation"));
|
|
g_signal_connect(g_MainWindow.playButtonItem, "toggled", G_CALLBACK(callback_start_emulation), NULL);
|
|
gtk_toolbar_insert(GTK_TOOLBAR(g_MainWindow.toolBar), GTK_TOOL_ITEM(g_MainWindow.playButtonItem), 2);
|
|
|
|
g_MainWindow.pauseButtonItem = GTK_WIDGET(gtk_toggle_tool_button_new());
|
|
gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(g_MainWindow.pauseButtonItem), g_MainWindow.pauseButtonImage);
|
|
gtk_tool_button_set_label(GTK_TOOL_BUTTON(g_MainWindow.pauseButtonItem), tr("Pause"));
|
|
gtk_widget_set_tooltip_text(g_MainWindow.pauseButtonItem, tr("Pause/ Continue Emulation"));
|
|
g_signal_connect(g_MainWindow.pauseButtonItem, "toggled", G_CALLBACK(callback_pause_emulation), NULL);
|
|
gtk_toolbar_insert(GTK_TOOLBAR(g_MainWindow.toolBar), GTK_TOOL_ITEM(g_MainWindow.pauseButtonItem), 3);
|
|
|
|
g_MainWindow.stopButtonItem = GTK_WIDGET(gtk_toggle_tool_button_new());
|
|
gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(g_MainWindow.stopButtonItem), g_MainWindow.stopButtonImage);
|
|
gtk_tool_button_set_label(GTK_TOOL_BUTTON(g_MainWindow.stopButtonItem), tr("Stop"));
|
|
gtk_widget_set_tooltip_text(g_MainWindow.stopButtonItem, tr("Stop Emulation"));
|
|
g_signal_connect(g_MainWindow.stopButtonItem, "toggled", G_CALLBACK(callback_stop_emulation), NULL);
|
|
gtk_toolbar_insert(GTK_TOOLBAR(g_MainWindow.toolBar), GTK_TOOL_ITEM(g_MainWindow.stopButtonItem), 4);
|
|
|
|
gtk_toolbar_insert(GTK_TOOLBAR(g_MainWindow.toolBar), gtk_separator_tool_item_new(), 5);
|
|
|
|
g_MainWindow.saveStateButtonItem = GTK_WIDGET(gtk_tool_button_new(g_MainWindow.saveStateButtonImage, tr("Save State")));
|
|
gtk_widget_set_tooltip_text(g_MainWindow.saveStateButtonItem, tr("Save State"));
|
|
g_signal_connect(g_MainWindow.saveStateButtonItem, "clicked", G_CALLBACK(callback_save_state), NULL);
|
|
gtk_toolbar_insert(GTK_TOOLBAR(g_MainWindow.toolBar), GTK_TOOL_ITEM(g_MainWindow.saveStateButtonItem), 6);
|
|
|
|
g_MainWindow.loadStateButtonItem = GTK_WIDGET(gtk_tool_button_new(g_MainWindow.loadStateButtonImage, tr("Load State")));
|
|
gtk_widget_set_tooltip_text(g_MainWindow.loadStateButtonItem, tr("Load State"));
|
|
g_signal_connect(g_MainWindow.loadStateButtonItem, "clicked", G_CALLBACK(callback_load_state), NULL);
|
|
gtk_toolbar_insert(GTK_TOOLBAR(g_MainWindow.toolBar), GTK_TOOL_ITEM(g_MainWindow.loadStateButtonItem), 7);
|
|
|
|
gtk_toolbar_insert(GTK_TOOLBAR(g_MainWindow.toolBar), gtk_separator_tool_item_new(), 8);
|
|
|
|
item = gtk_tool_button_new(g_MainWindow.configureButtonImage, tr("Configure"));
|
|
gtk_widget_set_tooltip_text(GTK_WIDGET(item), tr("Configure"));
|
|
g_signal_connect(item, "clicked", G_CALLBACK(callback_configure), NULL);
|
|
gtk_toolbar_insert(GTK_TOOLBAR(g_MainWindow.toolBar), item, 9);
|
|
|
|
g_MainWindow.fullscreenButtonItem = GTK_WIDGET(gtk_tool_button_new(g_MainWindow.fullscreenButtonImage, tr("Fullscreen")));
|
|
gtk_widget_set_tooltip_text(GTK_WIDGET(g_MainWindow.fullscreenButtonItem), tr("Fullscreen"));
|
|
g_signal_connect(g_MainWindow.fullscreenButtonItem, "clicked", G_CALLBACK(callback_fullscreen), NULL);
|
|
gtk_toolbar_insert(GTK_TOOLBAR(g_MainWindow.toolBar), GTK_TOOL_ITEM(g_MainWindow.fullscreenButtonItem), 10);
|
|
|
|
gtk_box_pack_start(GTK_BOX(g_MainWindow.toplevelVBox), g_MainWindow.toolBar, FALSE, FALSE, 0);
|
|
}
|
|
|
|
static void 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);
|
|
}
|
|
|
|
static void create_mainWindow(void)
|
|
{
|
|
/* Setup main window. */
|
|
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;
|
|
|
|
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);
|
|
|
|
GdkPixbuf *mupen64plus16, *mupen64plus32;
|
|
mupen64plus16 = gdk_pixbuf_new_from_file(get_iconpath("16x16/mupen64plus.png"), NULL);
|
|
mupen64plus32 = gdk_pixbuf_new_from_file(get_iconpath("32x32/mupen64plus.png"), NULL);
|
|
|
|
GList* iconlist = NULL;
|
|
iconlist = g_list_append(iconlist, mupen64plus16);
|
|
iconlist = g_list_append(iconlist, mupen64plus16);
|
|
|
|
gtk_window_set_icon_list(GTK_WINDOW(g_MainWindow.window), iconlist);
|
|
/* Edit gtk on quit. */
|
|
g_signal_connect(g_MainWindow.window, "delete_event", G_CALLBACK(callback_mainWindowDeleteEvent), NULL);
|
|
|
|
/* Toplevel vbox, parent to all GUI widgets. */
|
|
g_MainWindow.toplevelVBox = gtk_vbox_new(FALSE, 0);
|
|
gtk_container_add(GTK_CONTAINER(g_MainWindow.window), g_MainWindow.toplevelVBox);
|
|
|
|
create_menubar();
|
|
create_toolbar();
|
|
create_filter();
|
|
|
|
/* Setup rombrowser. */
|
|
int value = config_get_number("RomSortType", 16);
|
|
if(value!=GTK_SORT_ASCENDING&&value!=GTK_SORT_DESCENDING)
|
|
{
|
|
g_MainWindow.romSortType = GTK_SORT_ASCENDING;
|
|
config_put_number("RomSortType",GTK_SORT_ASCENDING);
|
|
}
|
|
else
|
|
g_MainWindow.romSortType = value;
|
|
value = config_get_number("RomSortColumn", 17);
|
|
if(value<0||value>16)
|
|
{
|
|
g_MainWindow.romSortColumn = 1;
|
|
config_put_number("RomSortColumn", 1);
|
|
}
|
|
else
|
|
g_MainWindow.romSortColumn = value;
|
|
|
|
create_romBrowser();
|
|
create_statusbar();
|
|
}
|
|
|