Gtk: Switch codebase to gtkmm.

GTK: Remove support for GTK+ 2.0.

GTK 3 is stable and widespread enough now.

GTK: Rearrange headers to eliminate gtk_s9xcore.h

Gtk: Initial gtkmm conversion work.

Gtk: More gtkmm conversion and bug fixing.

Gtk: More gtkmm fixes.

Gtk: More Fixes

OpenGL no longer creates a second window.
Accelerators are fixed.

Gtk: More fixes

Removed GLX context dependency on Gtk.

Gtk: Fix formatting.

Gtk: Remove a #pragma once
This commit is contained in:
Brandon Wright 2020-07-04 17:53:38 -05:00
parent 3c3ea985ef
commit e17ff69533
51 changed files with 3069 additions and 4720 deletions

View File

@ -23,12 +23,9 @@ args += [ '-DDATADIR="' + appdatadir + '"', '-DSNES9XLOCALEDIR="' + localedir +
subdir('data')
subdir('po')
glib_dep = dependency('glib-2.0', version: '> 2.28')
gthread_dep = dependency('gthread-2.0', version: '>= 2.6')
gobject_dep = dependency('gobject-2.0', version: '>= 2.6')
sdl2_dep = dependency('sdl2')
deps += [ glib_dep, gthread_dep, gobject_dep, sdl2_dep ]
deps += sdl2_dep
c_compiler = meson.get_compiler('c')
@ -36,16 +33,7 @@ if c_compiler.version().version_compare('>=7.0.0') and c_compiler.get_id() == 'g
args += '-Wno-format-truncation'
endif
if get_option('gtk3') and not get_option('gtk2')
message('Building with GTK+-3.0')
gtk_dep = dependency('gtk+-3.0', version: '>= 3.22')
gtk_ver = 3
else
message('Building with GTK+-2.0')
gtk_dep = dependency('gtk+-2.0', version: '>= 2.16')
gtk_ver = 2
endif
gtk_dep = dependency('gtkmm-3.0', version: '>= 3.22')
deps += gtk_dep
x11_dep = c_compiler.find_library('X11')
@ -125,7 +113,7 @@ if slang and opengl
endif
wayland = get_option('wayland')
if wayland and gtk_ver == 3
if wayland
wayland_dep = dependency('wayland-egl', required: false)
if wayland_dep.found()
@ -320,7 +308,7 @@ srcs += [
'../filter/snes_ntsc.h',
'../filter/snes_ntsc_impl.h',
'../filter/snes_ntsc.c',
'src/gtk_2_3_compat.h',
'src/gtk_compat.h',
'src/gtk_sound_driver_sdl.h',
'src/gtk_sound_driver_sdl.cpp',
'../fxinst.cpp',
@ -405,7 +393,7 @@ libjma_srcs = [
libjma = static_library('jma',
libjma_srcs,
c_args: args,
cpp_args: [args, '-fexceptions'],
cpp_args: args,
include_directories: include_directories(includes))
sourcify = executable('sourcify', 'src/sourcify.c', native: true)
@ -418,7 +406,7 @@ snes9x_gtk = executable('snes9x-gtk',
srcs,
gtk_snes9x_ui_cpp,
c_args: args,
cpp_args: [args, '-fno-exceptions', '-fno-rtti'],
cpp_args: args,
dependencies: deps,
include_directories: include_directories(includes),
link_with: libjma,
@ -431,7 +419,6 @@ summary = [
' appdatadir: ' + appdatadir,
' localedir: ' + localedir,
'[Options] Build type: ' + get_option('buildtype'),
' GTK+ version: ' + gtk_ver.to_string(),
' Wayland: ' + wayland.to_string(),
' OpenGL: ' + opengl.to_string(),
' slang shaders: ' + slang.to_string(),

View File

@ -11,8 +11,6 @@ option('xbrz', type: 'boolean', value: true, description: 'Enable th
option('zlib', type: 'boolean', value: true, description: 'Enable gzip compression')
option('system-zip', type: 'boolean', value: true, description: 'Build using system minizip library')
option('screenshot', type: 'boolean', value: true, description: 'Enable screenshots')
option('gtk3', type: 'boolean', value: true, description: 'Build with GTK+ 3.0 as the toolkit')
option('wayland', type: 'boolean', value: true, description: 'Build support for Wayland')
option('gtk2', type: 'boolean', value: false, description: 'Build with GTK+ 2.0 as the toolkit')
option('dangerous-hacks', type: 'boolean', value: false, description: 'Allow dangerous hacks to be enabled')
option('appdatadir', type: 'string' , value: '', description: 'Snes9x-only data directory (default: datadir/snes9x)')

View File

@ -1,4 +1,5 @@
#pragma once
#ifndef __BACKGROUND_PARTICLES_H
#define __BACKGROUND_PARTICLES_H
#include <vector>
#include <list>
#include <cstdint>
@ -50,3 +51,4 @@ class Particles
};
} // namespace Background
#endif // __BACKGROUND_PARTICLES_H

View File

@ -1,60 +0,0 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
#ifndef __GTK_2_3_COMPAT_H
#define __GTK_2_3_COMPAT_H
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
#if GTK_MAJOR_VERSION >= 3
#include <gdk/gdkkeysyms-compat.h>
#ifndef USE_WAYLAND
#undef GDK_WINDOWING_WAYLAND
#endif
#ifdef GDK_WINDOWING_WAYLAND
#include <gdk/gdkwayland.h>
#endif
#else // GTK+ 2.0
#define GDK_WINDOWING_X11
#define GDK_IS_X11_WINDOW(window) true
#define GDK_IS_X11_DISPLAY(display) true
#define gdk_x11_window_get_xid(window) GDK_WINDOW_XWINDOW (window)
inline void gdk_x11_display_error_trap_push(GdkDisplay *dpy)
{
gdk_error_trap_push();
}
inline void gdk_x11_display_error_trap_pop_ignored(GdkDisplay *dpy)
{
if (gdk_error_trap_pop())
{
}
}
inline void gdk_window_get_geometry (GdkWindow *window,
gint *x,
gint *y,
gint *width,
gint *height)
{
gdk_window_get_geometry (window, x, y, width, height, NULL);
}
#endif
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
#endif

View File

@ -54,9 +54,7 @@ Binding::Binding (unsigned int key, bool ctrl, bool shift, bool alt)
value |= BINDING_ALT;
}
Binding::Binding (unsigned int device,
unsigned int button,
unsigned int threshold)
Binding::Binding(unsigned int device, unsigned int button, unsigned int threshold)
{
value = BINDING_JOY;
value |= JOY_DEVICE_MASK(device + 1);
@ -83,83 +81,70 @@ Binding &Binding::operator=(const Binding &binding)
bool Binding::operator==(const Binding &binding)
{
if ((value & ~BINDING_THRESHOLD_MASK) ==
(binding.value & ~BINDING_THRESHOLD_MASK))
if ((value & ~BINDING_THRESHOLD_MASK) == (binding.value & ~BINDING_THRESHOLD_MASK))
return true;
return false;
}
void
Binding::clear ()
void Binding::clear()
{
value = 0;
}
unsigned int
Binding::hex ()
unsigned int Binding::hex()
{
return value;
}
unsigned int
Binding::base_hex ()
unsigned int Binding::base_hex()
{
return (value & ~BINDING_THRESHOLD_MASK);
}
bool
Binding::is_joy ()
bool Binding::is_joy()
{
return (value & BINDING_JOY);
}
bool
Binding::is_key ()
bool Binding::is_key()
{
return (value & BINDING_KEY);
}
unsigned int
Binding::get_key ()
unsigned int Binding::get_key()
{
return (value & BINDING_KEY_MASK);
}
unsigned int
Binding::get_device ()
unsigned int Binding::get_device()
{
return JOY_DEVICE_UNMASK(value);
}
unsigned int
Binding::get_threshold ()
unsigned int Binding::get_threshold()
{
return THRESHOLD_UNMASK(value);
}
unsigned int
Binding::get_axis ()
unsigned int Binding::get_axis()
{
return JOY_AXIS_UNMASK(value);
}
GdkModifierType
Binding::get_gdk_modifiers ()
Gdk::ModifierType Binding::get_gdk_modifiers()
{
return (GdkModifierType) (((BINDING_CTRL & value) ? GDK_CONTROL_MASK : 0) |
((BINDING_ALT & value) ? GDK_MOD1_MASK : 0) |
((BINDING_SHIFT & value) ? GDK_SHIFT_MASK : 0));
return (Gdk::ModifierType)(((BINDING_CTRL & value) ? Gdk::CONTROL_MASK : 0) |
((BINDING_ALT & value) ? Gdk::MOD1_MASK : 0) |
((BINDING_SHIFT & value) ? Gdk::SHIFT_MASK : 0));
}
bool
Binding::is_positive ()
bool Binding::is_positive()
{
return JOY_DIRECTION_UNMASK(value) == AXIS_POS;
}
bool
Binding::is_negative ()
bool Binding::is_negative()
{
return JOY_DIRECTION_UNMASK(value) == AXIS_NEG;
}
@ -223,7 +208,6 @@ Binding::Binding (const char *raw_string)
{
value = Binding(device - 1, button, 0).value;
}
}
}
@ -234,8 +218,7 @@ std::string Binding::as_string()
return std::string(buf);
}
void
Binding::to_string (char *str, bool translate)
void Binding::to_string(char *str, bool translate)
{
char buf[256];

View File

@ -7,7 +7,7 @@
#ifndef __GTK_BINDING_H
#define __GTK_BINDING_H
#include "gtk_2_3_compat.h"
#include "gtk_compat.h"
#include <string>
#define AXIS_POS 1
@ -58,7 +58,7 @@ class Binding
unsigned int get_device();
unsigned int get_threshold();
unsigned int get_axis();
GdkModifierType get_gdk_modifiers ();
Gdk::ModifierType get_gdk_modifiers();
private:
unsigned int value;

View File

@ -11,240 +11,145 @@
extern const unsigned char snes9x_ui[];
extern const int snes9x_ui_size;
Glib::RefPtr<Gtk::Builder> global_builder;
bool global_builder_created = false;
GtkBuilderWindow::GtkBuilderWindow(const char *root)
{
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder,
(const gchar *) snes9x_ui,
snes9x_ui_size,
NULL);
if (!global_builder_created)
{
global_builder = Gtk::Builder::create();
global_builder->add_from_string((const gchar *)snes9x_ui, snes9x_ui_size);
global_builder_created = true;
}
window = get_widget (root);
window = get_object<Gtk::Window>(root);
}
GtkBuilderWindow::~GtkBuilderWindow()
{
gtk_widget_destroy (window);
g_object_unref (builder);
}
GtkWidget *
GtkBuilderWindow::get_widget (const char *name)
void GtkBuilderWindow::enable_widget(const char *name, bool state)
{
return GTK_WIDGET (gtk_builder_get_object (builder, name));
auto widget = get_object<Gtk::Widget>(name);
widget->set_sensitive(state);
}
void
GtkBuilderWindow::signal_connection_func (GtkBuilder *builder,
GObject *object,
const gchar *signal_name,
const char *handler_name,
GObject *connect_object,
GConnectFlags flags,
gpointer data)
void GtkBuilderWindow::show_widget(const char *name, bool state)
{
GCallback function = NULL;
GtkBuilderWindow *window = (GtkBuilderWindow *) data;
GtkBuilderWindowCallbacks *callbacks = window->callbacks;
for (int i = 0; callbacks[i].signal; i++)
{
if (!strcmp (handler_name, callbacks[i].signal))
{
function = callbacks[i].function;
break;
}
auto widget = get_object<Gtk::Widget>(name);
widget->set_visible(state);
}
if (function)
void GtkBuilderWindow::resize(int width, int height)
{
if (connect_object)
{
fprintf (stderr, "Error: found a persistent object signal.\n");
g_signal_connect_object (object,
signal_name,
function,
connect_object,
flags);
}
else
{
g_signal_connect_data (object,
signal_name,
function,
data,
NULL,
flags);
}
}
else
{
}
window->resize(width, height);
}
void
GtkBuilderWindow::signal_connect (GtkBuilderWindowCallbacks *callbacks)
void GtkBuilderWindow::refresh()
{
if (!callbacks)
return;
this->callbacks = callbacks;
gtk_builder_connect_signals_full (builder,
signal_connection_func,
(gpointer) this);
this->callbacks = NULL;
window->queue_draw();
}
void
GtkBuilderWindow::enable_widget (const char *name, bool state)
int GtkBuilderWindow::get_width()
{
gtk_widget_set_sensitive (get_widget (name), state);
return window->get_width();
}
void
GtkBuilderWindow::resize (int width, int height)
int GtkBuilderWindow::get_height()
{
if (width > 0 && height > 0)
gtk_window_resize (GTK_WINDOW (window), width, height);
return window->get_height();
}
void
GtkBuilderWindow::refresh ()
void GtkBuilderWindow::set_button_label(const char *name, const char *label)
{
gtk_widget_queue_draw (GTK_WIDGET (window));
get_object<Gtk::Button>(name)->set_label(label);
}
int
GtkBuilderWindow::get_width ()
bool GtkBuilderWindow::get_check(const char *name)
{
int width, height;
gtk_window_get_size (GTK_WINDOW (window), &width, &height);
return width;
}
int
GtkBuilderWindow::get_height ()
{
int width, height;
gtk_window_get_size (GTK_WINDOW (window), &width, &height);
return height;
}
void
GtkBuilderWindow::set_button_label (const char *name, const char *label)
{
gtk_button_set_label (GTK_BUTTON (get_widget (name)), label);
}
unsigned char
GtkBuilderWindow::get_check (const char *name)
{
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (get_widget (name))))
return 1;
return 0;
return get_object<Gtk::ToggleButton>(name)->get_active();
}
int GtkBuilderWindow::get_entry_value(const char *name)
{
return atoi (gtk_entry_get_text (GTK_ENTRY (get_widget (name))));;
auto text = get_object<Gtk::Entry>(name)->get_text();
return std::stoi(text);
}
const char *
GtkBuilderWindow::get_entry_text (const char *name)
std::string GtkBuilderWindow::get_entry_text(const char *name)
{
return gtk_entry_get_text (GTK_ENTRY (get_widget (name)));
return get_object<Gtk::Entry>(name)->get_text();
}
float
GtkBuilderWindow::get_slider (const char *name)
void GtkBuilderWindow::set_entry_value(const char *name, unsigned int value)
{
return (float) gtk_range_get_value (GTK_RANGE (get_widget (name)));
get_object<Gtk::Entry>(name)->set_text(std::to_string(value));
}
unsigned char
GtkBuilderWindow::get_combo (const char *name)
void GtkBuilderWindow::set_entry_text(const char *name, const char *text)
{
return gtk_combo_box_get_active (GTK_COMBO_BOX (get_widget (name)));
get_object<Gtk::Entry>(name)->set_text(text);
}
void
GtkBuilderWindow::set_slider (const char *name, float value)
float GtkBuilderWindow::get_slider(const char *name)
{
gtk_range_set_value (GTK_RANGE (get_widget (name)), (double) value);
return get_object<Gtk::Range>(name)->get_value();
}
void
GtkBuilderWindow::set_check (const char *name, bool value)
int GtkBuilderWindow::get_combo(const char *name)
{
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (get_widget (name)),
value);
return get_object<Gtk::ComboBox>(name)->get_active_row_number();
}
void
GtkBuilderWindow::set_entry_value (const char *name, unsigned int value)
void GtkBuilderWindow::set_slider(const char *name, float value)
{
char text[80];
snprintf (text, 80, "%u", value);
gtk_entry_set_text (GTK_ENTRY (get_widget (name)), text);
get_object<Gtk::Range>(name)->set_value(value);
}
void
GtkBuilderWindow::set_entry_text (const char *name, const char *text)
void GtkBuilderWindow::set_check(const char *name, bool value)
{
gtk_entry_set_text (GTK_ENTRY (get_widget (name)), text);
get_object<Gtk::ToggleButton>(name)->set_active(value);
}
void
GtkBuilderWindow::set_combo (const char *name, unsigned char value)
void GtkBuilderWindow::set_combo(const char *name, unsigned char value)
{
gtk_combo_box_set_active (GTK_COMBO_BOX (get_widget (name)), value);
get_object<Gtk::ComboBox>(name)->set_active(value);
}
void
GtkBuilderWindow::set_spin (const char *name, double value)
void GtkBuilderWindow::set_spin(const char *name, double value)
{
gtk_spin_button_set_value (GTK_SPIN_BUTTON (get_widget (name)),
(double) value);
get_object<Gtk::SpinButton>(name)->set_value(value);
}
void
GtkBuilderWindow::combo_box_append (const char *name, const char *value)
double GtkBuilderWindow::get_spin(const char *name)
{
combo_box_append (GTK_COMBO_BOX (get_widget (name)), value);
return get_object<Gtk::SpinButton>(name)->get_value();
}
void
GtkBuilderWindow::combo_box_append (GtkComboBox *combo, const char *value)
void GtkBuilderWindow::combo_box_append(const char *name, const char *value)
{
return combo_box_append(get_object<Gtk::ComboBox>(name).get(), value);
}
void GtkBuilderWindow::combo_box_append(Gtk::ComboBox *combo, const char *value)
{
GtkListStore *store;
GtkTreeIter iter;
store = GTK_LIST_STORE (gtk_combo_box_get_model (combo));
store = GTK_LIST_STORE(combo->get_model()->gobj());
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, 0, value, -1);
}
GtkWindow *
GtkBuilderWindow::get_window ()
GtkWindow *GtkBuilderWindow::get_window()
{
return GTK_WINDOW (window);
}
double
GtkBuilderWindow::get_spin (const char *name)
{
return gtk_spin_button_get_value (GTK_SPIN_BUTTON (get_widget (name)));
return window->gobj();
}
bool GtkBuilderWindow::has_focus(const char *widget)
{
return gtk_widget_is_focus (get_widget (widget));
return get_object<Gtk::Widget>(widget)->is_focus();
}

View File

@ -7,35 +7,43 @@
#ifndef __GTK_BUILDER_WINDOW_H
#define __GTK_BUILDER_WINDOW_H
#include "gtk_2_3_compat.h"
#include "gtk_compat.h"
typedef struct
{
const char *signal;
GCallback function;
} GtkBuilderWindowCallbacks;
extern Glib::RefPtr<Gtk::Builder> global_builder;
class GtkBuilderWindow
{
public:
GtkBuilderWindow(const char *root);
~GtkBuilderWindow();
GtkWidget *get_widget (const char *name);
template <typename T>
Glib::RefPtr<T> get_object(const char *name)
{
auto object = global_builder->get_object(name);
if (!object)
{
printf("No object named %s\n", name);
exit(1);
}
return Glib::RefPtr<T>::cast_static(object);
}
void resize(int width, int height);
GtkWindow *get_window();
void refresh();
int get_width();
int get_height();
void signal_connect (GtkBuilderWindowCallbacks *callbacks);
void enable_widget(const char *name, bool state);
void show_widget(const char *name, bool state);
void set_button_label(const char *name, const char *label);
unsigned char get_check (const char *name);
bool get_check(const char *name);
int get_entry_value(const char *name);
const char *get_entry_text (const char *name);
unsigned char get_combo (const char *name);
std::string get_entry_text(const char *name);
int get_combo(const char *name);
void combo_box_append(const char *name, const char *value);
void combo_box_append (GtkComboBox *combo, const char *value);
void combo_box_append(Gtk::ComboBox *combo, const char *value);
double get_spin(const char *name);
float get_slider(const char *name);
void set_check(const char *name, bool value);
@ -46,12 +54,7 @@ class GtkBuilderWindow
void set_slider(const char *name, float value);
bool has_focus(const char *widget);
protected:
static void signal_connection_func (GtkBuilder *, GObject *, const gchar *, const char *, GObject *, GConnectFlags, gpointer);
GtkWidget *window;
GtkBuilder *builder;
GtkBuilderWindowCallbacks *callbacks;
Glib::RefPtr<Gtk::Window> window;
};
#endif /* __GTK_BUILDER_WINDOW_H */

View File

@ -4,13 +4,12 @@
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
#include "gtk_s9xcore.h"
#include "gtk_s9x.h"
#include "gtk_cheat.h"
#include "cheats.h"
#include "display.h"
enum
{
enum {
COLUMN_ENABLED = 0,
COLUMN_DESCRIPTION = 1,
COLUMN_CHEAT = 2,
@ -19,211 +18,114 @@ enum
extern SCheatData Cheat;
static void
display_errorbox (const char *error)
static void display_errorbox(const char *error)
{
GtkWidget *dialog = gtk_message_dialog_new (NULL,
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
"%s",
error);
gtk_window_set_title (GTK_WINDOW (dialog), _("Error"));
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
auto dialog = Gtk::MessageDialog(error, false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
dialog.set_title(_("Error"));
dialog.run();
dialog.hide();
}
static void
event_add_code (GtkButton *button, gpointer data)
static Snes9xCheats *cheats_dialog = nullptr;
void open_snes9x_cheats_dialog()
{
((Snes9xCheats *) data)->add_code ();
}
if (!cheats_dialog)
cheats_dialog = new Snes9xCheats;
static void
event_update_code (GtkButton *button, gpointer data)
{
((Snes9xCheats *) data)->update_code ();
}
static void
event_disable_all (GtkButton *button, gpointer data)
{
((Snes9xCheats *) data)->disable_all ();
}
static void
event_remove_code (GtkButton *button, gpointer data)
{
((Snes9xCheats *) data)->remove_code ();
}
static void
event_search_database (GtkButton *button, gpointer data)
{
((Snes9xCheats *) data)->search_database ();
}
static void
event_delete_all_cheats (GtkButton *button, gpointer data)
{
((Snes9xCheats *) data)->delete_all_cheats ();
}
static void
event_code_toggled (GtkCellRendererToggle *cell_renderer,
gchar *path,
gpointer data)
{
int enabled = !gtk_cell_renderer_toggle_get_active (cell_renderer);
((Snes9xCheats *) data)->toggle_code (path, enabled);
}
static void
event_row_activated (GtkTreeView *tree_view,
GtkTreePath *path,
GtkTreeViewColumn *column,
gpointer data)
{
((Snes9xCheats *) data)->row_activated (path);
}
static void
event_row_inserted (GtkTreeModel *tree_model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer data)
{
int *indices = gtk_tree_path_get_indices (path);
((Snes9xCheats *) data)->row_inserted (indices[0]);
}
static void
event_row_deleted (GtkTreeModel *tree_model,
GtkTreePath *path,
gpointer data)
{
int *indices = gtk_tree_path_get_indices (path);
((Snes9xCheats *) data)->row_deleted (indices[0]);
}
void
event_enabled_column_clicked (GtkTreeViewColumn *treeviewcolumn,
gpointer data)
{
((Snes9xCheats *) data)->sort_cheats ();
cheats_dialog->show();
}
Snes9xCheats::Snes9xCheats()
: GtkBuilderWindow("cheat_window")
{
GtkTreeView *view;
GtkCellRenderer *renderer;
GtkBuilderWindowCallbacks callbacks[] =
{
{ "add_code", G_CALLBACK (event_add_code) },
{ "update_code", G_CALLBACK (event_update_code) },
{ "remove_code", G_CALLBACK (event_remove_code) },
{ "search_database", G_CALLBACK (event_search_database) },
{ "disable_all", G_CALLBACK (event_disable_all) },
{ "delete_all_cheats", G_CALLBACK (event_delete_all_cheats) },
{ NULL, NULL}
};
dst_row = -1;
view = GTK_TREE_VIEW (get_widget ("cheat_treeview"));
auto view = get_object<Gtk::TreeView>("cheat_treeview");
view->signal_row_activated().connect(sigc::mem_fun(*this, &Snes9xCheats::row_activated));
view->set_reorderable();
g_signal_connect (view, "row-activated", G_CALLBACK (event_row_activated), (gpointer) this);
auto toggle_renderer = new Gtk::CellRendererToggle();
toggle_renderer->set_activatable();
toggle_renderer->signal_toggled().connect(sigc::mem_fun(*this, &Snes9xCheats::toggle_code));
gtk_tree_view_set_reorderable (view, true);
view->insert_column("\xe2\x86\x91", *toggle_renderer, COLUMN_ENABLED);
auto column = view->get_column(COLUMN_ENABLED);
column->set_clickable();
column->set_alignment(0.5);
column->add_attribute(*toggle_renderer, "active", COLUMN_ENABLED);
column->signal_clicked().connect([&] {
sort_cheats();
});
renderer = gtk_cell_renderer_toggle_new ();
gtk_cell_renderer_toggle_set_activatable (GTK_CELL_RENDERER_TOGGLE (renderer), true);
gtk_tree_view_insert_column_with_attributes (view,
-1,
"\xe2\x86\x91",
renderer,
"active", COLUMN_ENABLED,
NULL);
GtkTreeViewColumn *column = gtk_tree_view_get_column (view, 0);
gtk_tree_view_column_set_clickable (column, true);
gtk_tree_view_column_set_alignment (column, 0.5f);
g_signal_connect (column, "clicked", G_CALLBACK (event_enabled_column_clicked), (gpointer) this);
auto text_renderer = new Gtk::CellRendererText();
view->insert_column(_("Description"), *text_renderer, COLUMN_DESCRIPTION);
column = view->get_column(COLUMN_DESCRIPTION);
column->set_resizable();
column->set_min_width(40);
column->add_attribute(*text_renderer, "text", COLUMN_DESCRIPTION);
g_signal_connect (renderer,
"toggled",
G_CALLBACK (event_code_toggled),
(gpointer) this);
view->insert_column(_("Cheat"), *text_renderer, COLUMN_CHEAT);
column = view->get_column(COLUMN_CHEAT);
column->set_resizable();
column->set_min_width(40);
column->add_attribute(*text_renderer, "text", COLUMN_CHEAT);
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_insert_column_with_attributes (view,
-1,
_("Description"),
renderer,
"text", COLUMN_DESCRIPTION,
NULL);
column = gtk_tree_view_get_column (view, 1);
gtk_tree_view_column_set_resizable (column, true);
gtk_tree_view_column_set_min_width (column, 40);
Gtk::TreeModelColumn<bool> column1;
Gtk::TreeModelColumn<Glib::ustring> column2;
Gtk::TreeModelColumn<Glib::ustring> column3;
Gtk::TreeModelColumnRecord record;
record.add(column1);
record.add(column2);
record.add(column3);
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_insert_column_with_attributes (view,
-1,
_("Cheat"),
renderer,
"text", COLUMN_CHEAT,
NULL);
column = gtk_tree_view_get_column (view, 2);
gtk_tree_view_column_set_resizable (column, true);
gtk_tree_view_column_set_min_width (column, 40);
store = Gtk::ListStore::create(record);
view->set_model(store);
store = gtk_list_store_new (NUM_COLS,
G_TYPE_BOOLEAN,
G_TYPE_STRING,
G_TYPE_STRING);
delete_id = store->signal_row_deleted().connect([&](const Gtk::TreeModel::Path &path) {
row_deleted(get_index_from_path(path));
});
gtk_tree_view_set_model (view, GTK_TREE_MODEL (store));
delete_id = g_signal_connect (store, "row-deleted", G_CALLBACK (event_row_deleted), (gpointer) this);
insert_id = g_signal_connect (store, "row-inserted", G_CALLBACK (event_row_inserted), (gpointer) this);
insert_id = store->signal_row_inserted().connect([&](const Gtk::TreeModel::Path &path, const Gtk::TreeModel::iterator &iter) {
row_inserted(get_index_from_path(path));
});
gtk_widget_realize (window);
get_object<Gtk::Button>("add_code")->signal_clicked().connect(sigc::mem_fun(*this, &Snes9xCheats::add_code));
get_object<Gtk::Button>("remove_code")->signal_clicked().connect(sigc::mem_fun(*this, &Snes9xCheats::remove_code));
get_object<Gtk::Button>("update_button")->signal_clicked().connect(sigc::mem_fun(*this, &Snes9xCheats::update_code));
get_object<Gtk::Button>("disable_all_button")->signal_clicked().connect(sigc::mem_fun(*this, &Snes9xCheats::disable_all));
get_object<Gtk::Button>("delete_all_cheats_button")->signal_clicked().connect(sigc::mem_fun(*this, &Snes9xCheats::delete_all_cheats));
get_object<Gtk::Button>("cheat_search_button")->signal_clicked().connect(sigc::mem_fun(*this, &Snes9xCheats::search_database));
get_object<Gtk::Button>("update_button")->signal_clicked().connect(sigc::mem_fun(*this, &Snes9xCheats::update_code));
signal_connect (callbacks);
gtk_widget_realize(GTK_WIDGET(window->gobj()));
}
Snes9xCheats::~Snes9xCheats()
{
gtk_widget_destroy (window);
g_object_unref (store);
}
void
Snes9xCheats::enable_dnd (bool enable)
void Snes9xCheats::enable_dnd(bool enable)
{
if (enable)
{
g_signal_handler_unblock (G_OBJECT (store), delete_id);
g_signal_handler_unblock (G_OBJECT (store), insert_id);
delete_id.unblock();
insert_id.unblock();
}
else
{
g_signal_handler_block (G_OBJECT (store), delete_id);
g_signal_handler_block (G_OBJECT (store), insert_id);
delete_id.block();
insert_id.unblock();
}
}
void
Snes9xCheats::show ()
void Snes9xCheats::show()
{
top_level->pause_from_focus_change();
gtk_window_set_transient_for (GTK_WINDOW (window),
top_level->get_window ());
window->set_transient_for(*top_level->window.get());
refresh_tree_view();
gtk_dialog_run (GTK_DIALOG (window));
Glib::RefPtr<Gtk::Dialog>::cast_static(window)->run();
window->hide();
top_level->unpause_from_focus_change();
}
@ -251,8 +153,7 @@ static void cheat_gather_enabled ()
}
}
void
Snes9xCheats::row_deleted (int src_row)
void Snes9xCheats::row_deleted(int src_row)
{
if (dst_row >= 0)
{
@ -264,158 +165,124 @@ Snes9xCheats::row_deleted (int src_row)
}
}
void
Snes9xCheats::row_inserted (int new_row)
void Snes9xCheats::row_inserted(int new_row)
{
dst_row = new_row;
}
int
Snes9xCheats::get_selected_index ()
int Snes9xCheats::get_selected_index()
{
GtkTreeSelection *selection;
GList *rows;
gint *indices;
int index;
GtkTreeModel *model = GTK_TREE_MODEL (store);
selection =
gtk_tree_view_get_selection (
GTK_TREE_VIEW (get_widget ("cheat_treeview")));
rows = gtk_tree_selection_get_selected_rows (selection,
&model);
if (rows)
{
indices = gtk_tree_path_get_indices ((GtkTreePath *) (rows->data));
index = indices[0];
for (GList *i = rows; i; i = i->next)
gtk_tree_path_free ((GtkTreePath *)(i->data));
g_list_free (rows);
}
else
index = -1;
return index;
auto selection = get_object<Gtk::TreeView>("cheat_treeview")->get_selection();
auto rows = selection->get_selected_rows();
if (rows.empty())
return -1;
auto indices = gtk_tree_path_get_indices(rows[0].gobj());
return indices[0];
}
int
Snes9xCheats::get_index_from_path (const gchar *path)
int Snes9xCheats::get_index_from_path(Gtk::TreeModel::Path path)
{
GtkTreePath *tree_path = gtk_tree_path_new_from_string (path);
gint *indices = gtk_tree_path_get_indices (tree_path);
gint *indices = gtk_tree_path_get_indices(path.gobj());
int index = indices[0];
gtk_tree_path_free (tree_path);
return index;
}
void
Snes9xCheats::refresh_tree_view ()
int Snes9xCheats::get_index_from_path(const Glib::ustring &path)
{
GtkTreeIter iter;
unsigned int list_size;
return get_index_from_path(Gtk::TreeModel::Path(path));
}
void Snes9xCheats::refresh_tree_view()
{
enable_dnd(false);
list_size = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL);
auto list_size = store->children().size();
if (Cheat.g.size() == 0)
return;
for (unsigned int i = 0; i < Cheat.g.size() - list_size; i++)
gtk_list_store_append (store, &iter);
gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
store->append();
auto iter = store->children().begin();
for (unsigned int i = 0; i < Cheat.g.size (); i++)
{
char *str = S9xCheatGroupToText(i);
if (i > 0)
gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
gtk_list_store_set (store, &iter,
COLUMN_DESCRIPTION,
!strcmp (Cheat.g [i].name, "") ? _("No description")
: Cheat.g [i].name,
COLUMN_CHEAT, str,
COLUMN_ENABLED, Cheat.g [i].enabled,
-1);
Glib::ustring description = Cheat.g[i].name[0] == '\0' ? "" :Cheat.g[i].name;
iter->set_value(COLUMN_ENABLED, Cheat.g[i].enabled);
iter->set_value(COLUMN_DESCRIPTION, description);
iter->set_value(COLUMN_CHEAT, Glib::ustring(str));
iter++;
delete[] str;
}
enable_dnd(true);
}
void
Snes9xCheats::add_code ()
void Snes9xCheats::add_code()
{
const char *description;
const gchar *code = get_entry_text ("code_entry");
std::string code = get_entry_text("code_entry");
std::string description = get_entry_text("description_entry");
description = get_entry_text ("description_entry");
if (description[0] == '\0')
if (description.empty())
description = _("No description");
if (S9xAddCheatGroup (description, code) < 0)
if (S9xAddCheatGroup(description.c_str(), code.c_str()) < 0)
{
display_errorbox(_("Couldn't find any cheat codes in input."));
return;
}
code = (const gchar *) S9xCheatGroupToText (Cheat.g.size () - 1);
set_entry_text ("code_entry", code);
delete[] code;
auto parsed_code = S9xCheatGroupToText(Cheat.g.size() - 1);
set_entry_text("code_entry", parsed_code);
delete[] parsed_code;
gtk_widget_grab_focus (get_widget ("code_entry"));
get_object<Gtk::Entry>("code_entry")->grab_focus();
refresh_tree_view();
while (gtk_events_pending ())
gtk_main_iteration ();
while (Gtk::Main::events_pending())
Gtk::Main::iteration(false);
GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (get_widget ("cheat_treeview")));
GtkTreePath *path = gtk_tree_path_new_from_indices (Cheat.g.size () - 1, -1);
gtk_tree_selection_select_path (selection, path);
gtk_tree_path_free (path);
auto selection = get_object<Gtk::TreeView>("cheat_treeview")->get_selection();
Gtk::TreePath path;
path.push_back(Cheat.g.size() - 1);
selection->select(path);
GtkScrolledWindow *scroll = GTK_SCROLLED_WINDOW (get_widget ("cheat_scrolledwindow"));
GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment (scroll);
gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj));
auto adj = get_object<Gtk::ScrolledWindow>("cheat_scrolledwindow")->get_vadjustment();
adj->set_value(adj->get_upper());
}
void
Snes9xCheats::remove_code ()
void Snes9xCheats::remove_code()
{
int index = get_selected_index();
GtkTreeIter iter;
if (index < 0)
return;
enable_dnd(false);
gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, NULL, index);
gtk_list_store_remove (store, &iter);
Gtk::TreePath path;
path.push_back(index);
auto iter = store->get_iter(path);
store->erase(iter);
enable_dnd(true);
S9xDeleteCheatGroup(index);
}
void
Snes9xCheats::delete_all_cheats ()
void Snes9xCheats::delete_all_cheats()
{
enable_dnd(false);
S9xDeleteCheats();
gtk_list_store_clear (store);
store->clear();
enable_dnd(true);
}
void
Snes9xCheats::search_database ()
void Snes9xCheats::search_database()
{
std::string filename;
int result;
@ -463,52 +330,40 @@ Snes9xCheats::search_database ()
if (result < reason)
reason = result;
GtkMessageDialog *dialog;
GtkDialogFlags flags = GTK_DIALOG_DESTROY_WITH_PARENT;
dialog = GTK_MESSAGE_DIALOG (gtk_message_dialog_new (get_window (),
flags,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
reason == -1 ? _("Couldn't Find Cheats Database") :
_("No Matching Game Found")));
gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG (dialog),
reason == -1 ?
_("The database file <b>cheats.bml</b> was not found. It is normally installed with "
"Snes9x, but you may also place a custom copy in your configuration or cheats directory.") :
_("No matching game was found in the databases. If you are using a non-official "
auto dialog = Gtk::MessageDialog(*window.get(), reason == -1 ? _("Couldn't Find Cheats Database") : _("No Matching Game Found"), true);
dialog.set_secondary_text(reason == -1 ? _("The database file <b>cheats.bml</b> was not found. It is normally installed with "
"Snes9x, but you may also place a custom copy in your configuration or cheats directory.")
: _("No matching game was found in the databases. If you are using a non-official "
"translation or modified copy, you may be able to find and manually enter the codes."));
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (GTK_WIDGET (dialog));
dialog.run();
dialog.hide();
}
void
Snes9xCheats::sort_cheats ()
void Snes9xCheats::sort_cheats()
{
cheat_gather_enabled();
refresh_tree_view();
}
void
Snes9xCheats::row_activated (GtkTreePath *path)
void Snes9xCheats::row_activated(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column)
{
gint *indices = gtk_tree_path_get_indices (path);
int index = get_index_from_path(path);
char *cheat_text;
cheat_text = S9xCheatGroupToText (indices[0]);
cheat_text = S9xCheatGroupToText(index);
set_entry_text("code_entry", cheat_text);
delete[] cheat_text;
set_entry_text ("description_entry", Cheat.g[indices[0]].name);
set_entry_text("description_entry", Cheat.g[index].name);
}
void
Snes9xCheats::toggle_code (const gchar *path, int enabled)
void Snes9xCheats::toggle_code(const Glib::ustring &path)
{
GtkTreeIter iter;
int index = get_index_from_path(path);
GtkTreePath *treepath = gtk_tree_path_new_from_string (path);
gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, treepath);
gtk_list_store_set (store, &iter, COLUMN_ENABLED, enabled, -1);
auto iter = store->get_iter(path);
bool enabled;
iter->get_value(COLUMN_ENABLED, enabled);
enabled = !enabled;
iter->set_value(COLUMN_ENABLED, enabled);
if (enabled)
S9xEnableCheatGroup(index);
@ -516,39 +371,35 @@ Snes9xCheats::toggle_code (const gchar *path, int enabled)
S9xDisableCheatGroup(index);
}
void
Snes9xCheats::update_code ()
void Snes9xCheats::update_code()
{
int index = get_selected_index();
if (index < 0)
return;
const char *description;
char *code = (char *) get_entry_text ("code_entry");
description = get_entry_text ("description_entry");
if (description[0] == '\0')
std::string code = get_entry_text("code_entry");
std::string description = get_entry_text("description_entry");
if (description.empty())
description = _("No description");
code = S9xCheatValidate (code);
if (!code)
auto parsed_code = S9xCheatValidate(code.c_str());
if (!parsed_code)
{
display_errorbox(_("Couldn't find any cheat codes in input."));
return;
}
S9xModifyCheatGroup (index, description, code);
set_entry_text ("code_entry", code);
delete[] code;
S9xModifyCheatGroup(index, description.c_str(), parsed_code);
set_entry_text("code_entry", parsed_code);
delete[] parsed_code;
gtk_widget_grab_focus (get_widget ("code_entry"));
get_object<Gtk::Entry>("code_entry")->grab_focus();
refresh_tree_view();
}
void
Snes9xCheats::disable_all ()
void Snes9xCheats::disable_all()
{
for (unsigned int i = 0; i < Cheat.g.size(); i++)
{
@ -558,4 +409,3 @@ Snes9xCheats::disable_all ()
refresh_tree_view();
}

View File

@ -9,8 +9,9 @@
#include "gtk_builder_window.h"
enum
{
void open_snes9x_cheats_dialog();
enum {
TYPE_GAME_GENIE = 0,
TYPE_ACTION_REPLAY = 1,
TYPE_GOLDFINGER = 2
@ -26,8 +27,8 @@ class Snes9xCheats : public GtkBuilderWindow
void remove_code();
void search_database();
void delete_all_cheats();
void toggle_code (const gchar *path, int enabled);
void row_activated (GtkTreePath *path);
void toggle_code(const Glib::ustring &path);
void row_activated(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column);
void row_deleted(int src_row);
void row_inserted(int row);
void enable_dnd(bool);
@ -38,12 +39,13 @@ class Snes9xCheats : public GtkBuilderWindow
private:
void refresh_tree_view();
int get_selected_index();
int get_index_from_path (const gchar *path);
int get_index_from_path(const Glib::ustring &path);
int get_index_from_path(Gtk::TreeModel::Path path);
unsigned long insert_id;
unsigned long delete_id;
sigc::connection insert_id;
sigc::connection delete_id;
int dst_row;
GtkListStore *store;
Glib::RefPtr<Gtk::ListStore> store;
};
#endif /* __GTK_CHEAT_H */

29
gtk/src/gtk_compat.h Normal file
View File

@ -0,0 +1,29 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
#ifndef __GTK_COMPAT_H
#define __GTK_COMPAT_H
#include <gtkmm.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkkeysyms-compat.h>
#ifndef USE_WAYLAND
#undef GDK_WINDOWING_WAYLAND
#endif
#ifdef GDK_WINDOWING_WAYLAND
#include <gdk/gdkwayland.h>
#endif
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
#endif

View File

@ -14,6 +14,10 @@
#include "gtk_sound.h"
#include "gtk_display.h"
#include "conffile.h"
#include "cheats.h"
#include "apu/apu.h"
#include "netplay.h"
#include "controls.h"
static bool directory_exists(std::string str)
{
@ -38,7 +42,7 @@ std::string get_config_dir()
if (!env_home && !env_xdg_config_home)
{
return std::string(".snes9x");
return std::string{".snes9x"};
}
std::string config;
@ -70,7 +74,6 @@ void S9xParsePortConfig(ConfigFile &conf, int pass)
Snes9xConfig::Snes9xConfig()
{
joystick = NULL;
joystick_threshold = 40;
}
@ -103,8 +106,8 @@ int Snes9xConfig::load_defaults()
default_esc_behavior = 1;
prevent_screensaver = false;
sound_driver = 0;
sound_buffer_size = 32;
sound_playback_rate = 5;
sound_buffer_size = 48;
sound_playback_rate = 7;
sound_input_rate = 31950;
auto_input_rate = true;
last_directory.clear();
@ -149,7 +152,7 @@ int Snes9xConfig::load_defaults()
sync_to_vblank = true;
use_pbos = true;
pbo_format = 0;
npot_textures = false;
npot_textures = true;
use_shaders = false;
shader_filename.clear();
use_glfinish = false;
@ -206,26 +209,26 @@ int Snes9xConfig::load_defaults()
void Snes9xConfig::joystick_register_centers()
{
for (int i = 0; joystick[i] != NULL; i++)
joystick[i]->register_centers();
for (auto &j : joystick)
j.register_centers();
}
void Snes9xConfig::flush_joysticks()
{
for (int i = 0; joystick[i] != NULL; i++)
joystick[i]->flush();
for (auto &j : joystick)
j.flush();
}
void Snes9xConfig::set_joystick_mode(int mode)
{
for (int i = 0; joystick[i] != NULL; i++)
joystick[i]->mode = mode;
for (auto &j : joystick)
j.mode = mode;
}
int Snes9xConfig::save_config_file()
{
ConfigFile cf;
std::string section = "";
std::string section;
auto outbool = [&](std::string name, bool b, std::string comment = "") {
cf.SetBool((section + "::" + name).c_str(), b, "true", "false", comment.c_str());

View File

@ -7,14 +7,14 @@
#ifndef __GTK_CONFIG_H
#define __GTK_CONFIG_H
#include "gtk_control.h"
#include "filter/snes_ntsc.h"
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#include <string>
#include <array>
#include "gtk_control.h"
#include "filter/snes_ntsc.h"
enum {
HWA_NONE = 0,
HWA_OPENGL = 1,
@ -167,7 +167,7 @@ class Snes9xConfig
bool use_sync_control;
#endif
JoyDevice **joystick;
std::vector<JoyDevice> joystick;
int joystick_threshold;
};

View File

@ -6,12 +6,17 @@
#include <fcntl.h>
#include "gtk_s9xcore.h"
#include "SDL_joystick.h"
#include "gtk_s9x.h"
#include "gtk_config.h"
#include "gtk_control.h"
#include "gtk_file.h"
#include "snes9x.h"
#include "controls.h"
#include "display.h"
#include "gfx.h"
const BindingLink b_links[] =
{
/* Joypad-specific bindings. "Joypad# " will be prepended */
@ -215,22 +220,18 @@ void S9xHandlePortCommand (s9xcommand_t cmd, int16 data1, int16 data2)
{
quit_binding_down = false;
}
if (cmd.port[0] == PORT_COMMAND_FULLSCREEN)
{
top_level->toggle_fullscreen_mode();
}
else if (cmd.port[0] == PORT_COMMAND_SAVE_SPC)
{
top_level->save_spc_dialog();
}
else if (cmd.port[0] == PORT_OPEN_ROM)
{
top_level->open_rom_dialog();
}
else if (cmd.port[0] == PORT_PAUSE)
{
if (!(top_level->user_pause))
@ -238,65 +239,53 @@ void S9xHandlePortCommand (s9xcommand_t cmd, int16 data1, int16 data2)
else
top_level->unpause_from_user();
}
else if (cmd.port[0] == PORT_REWIND)
{
Settings.Rewinding = false;
}
else if (cmd.port[0] == PORT_SEEK_TO_FRAME)
{
top_level->movie_seek_dialog();
}
else if (cmd.port[0] == PORT_SWAP_CONTROLLERS)
{
swap_controllers_1_2();
}
else if (cmd.port[0] == PORT_QUIT)
{
if (quit_binding_down)
S9xExit();
}
else if (cmd.port[0] >= PORT_QUICKLOAD0 && cmd.port[0] <= PORT_QUICKLOAD9)
{
S9xQuickLoadSlot(cmd.port[0] - PORT_QUICKLOAD0);
}
else if (cmd.port[0] == PORT_SAVESLOT)
{
S9xQuickSaveSlot(gui_config->current_save_slot);
}
else if (cmd.port[0] == PORT_LOADSLOT)
{
S9xQuickLoadSlot(gui_config->current_save_slot);
}
else if (cmd.port[0] == PORT_INCREMENTSAVESLOT)
{
change_slot(1);
S9xQuickSaveSlot(gui_config->current_save_slot);
}
else if (cmd.port[0] == PORT_DECREMENTLOADSLOT)
{
change_slot(-1);
S9xQuickLoadSlot(gui_config->current_save_slot);
}
else if (cmd.port[0] == PORT_INCREMENTSLOT)
{
change_slot(1);
}
else if (cmd.port[0] == PORT_DECREMENTSLOT)
{
change_slot(-1);
}
else if (cmd.port[0] == PORT_GRABMOUSE)
{
top_level->toggle_grab_mouse();
@ -333,128 +322,102 @@ s9xcommand_t S9xGetPortCommandT (const char *name)
{
cmd.port[0] = PORT_COMMAND_FULLSCREEN;
}
else if (!strcasecmp(name, "GTK_save_spc"))
{
cmd.port[0] = PORT_COMMAND_SAVE_SPC;
}
else if (!strcasecmp(name, "GTK_open_rom"))
{
cmd.port[0] = PORT_OPEN_ROM;
}
else if (!strcasecmp(name, "GTK_pause"))
{
cmd.port[0] = PORT_PAUSE;
}
else if (!strcasecmp(name, "GTK_seek_to_frame"))
{
cmd.port[0] = PORT_SEEK_TO_FRAME;
}
else if (!strcasecmp(name, "GTK_quit"))
{
cmd.port[0] = PORT_QUIT;
}
else if (!strcasecmp(name, "GTK_swap_controllers"))
{
cmd.port[0] = PORT_SWAP_CONTROLLERS;
}
else if (!strcasecmp(name, "GTK_rewind"))
{
cmd.port[0] = PORT_REWIND;
}
else if (strstr(name, "QuickLoad000"))
{
cmd.port[0] = PORT_QUICKLOAD0;
}
else if (strstr(name, "QuickLoad001"))
{
cmd.port[0] = PORT_QUICKLOAD1;
}
else if (strstr(name, "QuickLoad002"))
{
cmd.port[0] = PORT_QUICKLOAD2;
}
else if (strstr(name, "QuickLoad003"))
{
cmd.port[0] = PORT_QUICKLOAD3;
}
else if (strstr(name, "QuickLoad004"))
{
cmd.port[0] = PORT_QUICKLOAD4;
}
else if (strstr(name, "QuickLoad005"))
{
cmd.port[0] = PORT_QUICKLOAD5;
}
else if (strstr(name, "QuickLoad006"))
{
cmd.port[0] = PORT_QUICKLOAD6;
}
else if (strstr(name, "QuickLoad007"))
{
cmd.port[0] = PORT_QUICKLOAD7;
}
else if (strstr(name, "QuickLoad008"))
{
cmd.port[0] = PORT_QUICKLOAD8;
}
else if (strstr(name, "QuickLoad009"))
{
cmd.port[0] = PORT_QUICKLOAD9;
}
else if (strstr(name, "GTK_state_save_current"))
{
cmd.port[0] = PORT_SAVESLOT;
}
else if (strstr(name, "GTK_state_load_current"))
{
cmd.port[0] = PORT_LOADSLOT;
}
else if (strstr(name, "GTK_state_increment_save"))
{
cmd.port[0] = PORT_INCREMENTSAVESLOT;
}
else if (strstr(name, "GTK_state_decrement_load"))
{
cmd.port[0] = PORT_DECREMENTLOADSLOT;
}
else if (strstr(name, "GTK_state_increment"))
{
cmd.port[0] = PORT_INCREMENTSLOT;
}
else if (strstr(name, "GTK_state_decrement"))
{
cmd.port[0] = PORT_DECREMENTSLOT;
}
else if (strstr(name, "GTK_grab_mouse"))
{
cmd.port[0] = PORT_GRABMOUSE;
}
else
{
cmd = S9xGetCommandT(name);
@ -470,9 +433,9 @@ void S9xProcessEvents (bool8 block)
if (S9xGrabJoysticks())
{
for (int i = 0; gui_config->joystick[i]; i++)
for (size_t i = 0; i < gui_config->joystick.size(); i++)
{
while (gui_config->joystick[i]->get_event (&event))
while (gui_config->joystick[i].get_event(&event))
{
binding = Binding(i, event.parameter, 0);
S9xReportButton(binding.hex(), event.state == JOY_PRESSED ? 1 : 0);
@ -492,18 +455,16 @@ static void poll_joystick_events ()
{
if (event.type == SDL_JOYAXISMOTION)
{
gui_config->joystick[event.jaxis.which]->handle_event (&event);
gui_config->joystick[event.jaxis.which].handle_event(&event);
}
else if (event.type == SDL_JOYHATMOTION)
{
gui_config->joystick[event.jhat.which]->handle_event (&event);
gui_config->joystick[event.jhat.which].handle_event(&event);
}
else if (event.type == SDL_JOYBUTTONUP ||
event.type == SDL_JOYBUTTONDOWN)
{
gui_config->joystick[event.jbutton.which]->handle_event (&event);
gui_config->joystick[event.jbutton.which].handle_event(&event);
}
}
}
@ -511,25 +472,12 @@ static void poll_joystick_events ()
void S9xInitInputDevices()
{
SDL_Init(SDL_INIT_JOYSTICK);
size_t num_joysticks = SDL_NumJoysticks();
gui_config->joystick.resize(num_joysticks);
for (int i = 0; ; i++)
for (size_t i = 0; i < num_joysticks; i++)
{
gui_config->joystick = (JoyDevice **)
realloc (gui_config->joystick,
sizeof (JoyDevice *) * (i + 1));
gui_config->joystick[i] = new JoyDevice (i);
if (!gui_config->joystick[i]->enabled)
{
delete gui_config->joystick[i];
gui_config->joystick[i] = NULL;
break;
}
else
{
gui_config->joystick[i]->joynum = i;
}
gui_config->joystick[i].set_sdl_joystick_num(i);
}
//First plug in both, they'll change later as needed
@ -539,38 +487,45 @@ void S9xInitInputDevices ()
void S9xDeinitInputDevices()
{
for (int i = 0; gui_config->joystick[i] != NULL; i++)
{
delete gui_config->joystick[i];
}
free (gui_config->joystick);
gui_config->joystick.clear();
SDL_Quit();
}
JoyDevice::JoyDevice (unsigned int device_num)
JoyDevice::JoyDevice()
{
enabled = false;
axis = NULL;
filedes = NULL;
mode = JOY_MODE_INDIVIDUAL;
}
JoyDevice::~JoyDevice()
{
if (enabled)
{
SDL_JoystickClose(filedes);
}
}
bool JoyDevice::set_sdl_joystick_num(unsigned int device_num)
{
if ((int)device_num >= SDL_NumJoysticks())
return;
{
enabled = false;
return false;
}
filedes = SDL_JoystickOpen(device_num);
if (!filedes)
return;
return false;
enabled = true;
num_axes = SDL_JoystickNumAxes (filedes);
num_hats = SDL_JoystickNumHats (filedes);
axis = new int[num_axes];
hat = new int[num_hats];
calibration = new Calibration[num_axes];
int num_axes = SDL_JoystickNumAxes(filedes);
int num_hats = SDL_JoystickNumHats(filedes);
axis.resize(num_axes);
hat.resize(num_hats);
calibration.resize(num_axes);
for (int i = 0; i < num_axes; i++)
{
@ -586,20 +541,10 @@ JoyDevice::JoyDevice (unsigned int device_num)
num_axes,
num_hats);
memset (axis, 0, sizeof (int) * num_axes);
}
for (auto &i : axis)
i = 0;
JoyDevice::~JoyDevice ()
{
if (enabled)
{
SDL_JoystickClose (filedes);
delete[] axis;
delete[] hat;
delete[] calibration;
}
enabled = false;
return true;
}
void JoyDevice::add_event(unsigned int parameter, unsigned int state)
@ -611,7 +556,7 @@ void JoyDevice::add_event (unsigned int parameter, unsigned int state)
void JoyDevice::register_centers()
{
for (int i = 0; i < num_axes; i++)
for (size_t i = 0; i < axis.size(); i++)
{
calibration[i].center = SDL_JoystickGetAxis(filedes, i);
@ -722,7 +667,6 @@ void JoyDevice::handle_event (SDL_Event *event)
}
axis[event->jaxis.axis] = event->jaxis.value;
}
else if (event->type == SDL_JOYBUTTONUP ||
@ -737,49 +681,49 @@ void JoyDevice::handle_event (SDL_Event *event)
if ((event->jhat.value & SDL_HAT_UP) &&
!(hat[event->jhat.hat] & SDL_HAT_UP))
{
add_event (JOY_AXIS (num_axes + (event->jhat.hat * 2), AXIS_POS), 1);
add_event(JOY_AXIS(axis.size() + (event->jhat.hat * 2), AXIS_POS), 1);
}
if (!(event->jhat.value & SDL_HAT_UP) &&
(hat[event->jhat.hat] & SDL_HAT_UP))
{
add_event (JOY_AXIS (num_axes + (event->jhat.hat * 2), AXIS_POS), 0);
add_event(JOY_AXIS(axis.size() + (event->jhat.hat * 2), AXIS_POS), 0);
}
if ((event->jhat.value & SDL_HAT_DOWN) &&
!(hat[event->jhat.hat] & SDL_HAT_DOWN))
{
add_event (JOY_AXIS (num_axes + (event->jhat.hat * 2), AXIS_NEG), 1);
add_event(JOY_AXIS(axis.size() + (event->jhat.hat * 2), AXIS_NEG), 1);
}
if (!(event->jhat.value & SDL_HAT_DOWN) &&
(hat[event->jhat.hat] & SDL_HAT_DOWN))
{
add_event (JOY_AXIS (num_axes + (event->jhat.hat * 2), AXIS_NEG), 0);
add_event(JOY_AXIS(axis.size() + (event->jhat.hat * 2), AXIS_NEG), 0);
}
if ((event->jhat.value & SDL_HAT_LEFT) &&
!(hat[event->jhat.hat] & SDL_HAT_LEFT))
{
add_event (JOY_AXIS (num_axes + (event->jhat.hat * 2) + 1, AXIS_NEG), 1);
add_event(JOY_AXIS(axis.size() + (event->jhat.hat * 2) + 1, AXIS_NEG), 1);
}
if (!(event->jhat.value & SDL_HAT_LEFT) &&
(hat[event->jhat.hat] & SDL_HAT_LEFT))
{
add_event (JOY_AXIS (num_axes + (event->jhat.hat * 2) + 1, AXIS_NEG), 0);
add_event(JOY_AXIS(axis.size() + (event->jhat.hat * 2) + 1, AXIS_NEG), 0);
}
if ((event->jhat.value & SDL_HAT_RIGHT) &&
!(hat[event->jhat.hat] & SDL_HAT_RIGHT))
{
add_event (JOY_AXIS (num_axes + (event->jhat.hat * 2) + 1, AXIS_POS), 1);
add_event(JOY_AXIS(axis.size() + (event->jhat.hat * 2) + 1, AXIS_POS), 1);
}
if (!(event->jhat.value & SDL_HAT_RIGHT) &&
(hat[event->jhat.hat] & SDL_HAT_RIGHT))
{
add_event (JOY_AXIS (num_axes + (event->jhat.hat * 2) + 1, AXIS_POS), 0);
add_event(JOY_AXIS(axis.size() + (event->jhat.hat * 2) + 1, AXIS_POS), 0);
}
hat[event->jhat.hat] = event->jhat.value;

View File

@ -18,21 +18,18 @@
const int NUM_JOYPADS = 10;
enum
{
enum {
JOY_MODE_GLOBAL = 0,
JOY_MODE_INDIVIDUAL = 1,
JOY_MODE_CALIBRATE = 2
};
enum
{
enum {
JOY_RELEASED = 0,
JOY_PRESSED = 1
};
enum
{
enum {
PORT_COMMAND_FULLSCREEN = 1,
PORT_COMMAND_SAVE_SPC = 2,
PORT_OPEN_ROM = 3,
@ -97,22 +94,21 @@ typedef struct Calibration
class JoyDevice
{
public:
JoyDevice (unsigned int device_num);
JoyDevice();
~JoyDevice();
int get_event(JoyEvent *event);
void flush();
void handle_event(SDL_Event *event);
void register_centers();
bool set_sdl_joystick_num(unsigned int device_num);
SDL_Joystick *filedes;
Calibration *calibration;
std::queue<JoyEvent> queue;
int mode;
int joynum;
int num_axes;
int num_hats;
int *axis;
int *hat;
std::vector<Calibration> calibration;
std::vector<int> axis;
std::vector<int> hat;
bool enabled;
private:

View File

@ -4,7 +4,7 @@
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
#include "gtk_2_3_compat.h"
#include "gtk_compat.h"
#include <sched.h>
#include "gtk_s9x.h"
@ -12,6 +12,13 @@
#include "gtk_display_driver.h"
#include "gtk_display_driver_gtk.h"
#include "snes9x.h"
#include "memmap.h"
#include "cpuexec.h"
#include "ppu.h"
#include "gfx.h"
#include "netplay.h"
#if defined(USE_XV) && defined(GDK_WINDOWING_X11)
#include "gtk_display_driver_xv.h"
#endif
@ -1284,11 +1291,11 @@ void S9xDisplayReconfigure()
void S9xQueryDrivers()
{
GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (top_level->get_window()));
GdkDisplay *gdk_display = top_level->window->get_display()->gobj();
gui_config->allow_xv = false;
#if defined(USE_XV) && defined(GDK_WINDOWING_X11)
if (GDK_IS_X11_DISPLAY (display))
if (GDK_IS_X11_DISPLAY(gdk_display))
gui_config->allow_xv = S9xXVDisplayDriver::query_availability();
#endif
@ -1300,10 +1307,10 @@ void S9xQueryDrivers()
gui_config->allow_xrandr = false;
#ifdef GDK_WINDOWING_X11
if (GDK_IS_X11_DISPLAY(display))
if (GDK_IS_X11_DISPLAY(gdk_display))
{
Display *dpy = gdk_x11_display_get_xdisplay(gtk_widget_get_display(GTK_WIDGET(top_level->get_window())));
Window xid = gdk_x11_window_get_xid(gtk_widget_get_window(GTK_WIDGET(top_level->get_window())));
Display *dpy = gdk_x11_display_get_xdisplay(gdk_display);
Window xid = gdk_x11_window_get_xid(top_level->window->get_window()->gobj());
gui_config->allow_xrandr = true;
gui_config->xrr_screen_resources = XRRGetScreenResourcesCurrent(dpy, xid);
@ -1397,31 +1404,29 @@ bool8 S9xDeinitUpdate(int width, int height)
static void S9xInitDriver()
{
// Only OpenGL is supported on Wayland
#ifdef GDK_WINDOWING_WAYLAND
if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default()))
{
gui_config->hw_accel = HWA_OPENGL;
}
#endif
switch (gui_config->hw_accel)
{
#ifdef USE_OPENGL
case HWA_OPENGL:
driver = new S9xOpenGLDisplayDriver(top_level,
gui_config);
driver = new S9xOpenGLDisplayDriver(top_level, gui_config);
break;
#endif
#if defined(USE_XV) && defined(GDK_WINDOWING_X11)
case HWA_XV:
driver = new S9xXVDisplayDriver(top_level, gui_config);
break;
#endif
default:
default:
driver = new S9xGTKDisplayDriver(top_level, gui_config);
}
@ -1430,7 +1435,6 @@ static void S9xInitDriver()
if (gui_config->hw_accel > 0)
{
delete driver;
gui_config->hw_accel = HWA_NONE;
S9xInitDriver();
@ -1452,6 +1456,7 @@ S9xDisplayDriver *S9xDisplayGetDriver()
void S9xDeinitDisplay()
{
if (driver)
driver->deinit();
delete driver;

View File

@ -20,8 +20,7 @@
#include "filter_epx_unsafe.h"
#include "filter/snes_ntsc.h"
enum
{
enum {
FILTER_NONE = 0,
FILTER_SUPEREAGLE = 1,
FILTER_2XSAI = 2,
@ -42,21 +41,18 @@ enum
NUM_FILTERS = 17
};
enum
{
enum {
NTSC_COMPOSITE = 0,
NTSC_SVIDEO = 1,
NTSC_RGB = 2
};
enum
{
enum {
ENDIAN_NORMAL = 0,
ENDIAN_SWAPPED = 1
};
enum
{
enum {
JOB_FILTER = 0,
JOB_CONVERT = 1,
JOB_SCALE_AND_CONVERT = 2,
@ -81,7 +77,8 @@ typedef struct thread_job_t
volatile bool complete;
} thread_job_t;
struct S9xRect {
struct S9xRect
{
int x;
int y;
int w;

View File

@ -26,7 +26,7 @@ class S9xDisplayDriver
protected:
Snes9xWindow *window;
Snes9xConfig *config;
GtkWidget *drawing_area;
Gtk::DrawingArea *drawing_area;
};
#endif /* __GTK_DISPLAY_DRIVER_H*/

View File

@ -4,29 +4,25 @@
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
#include "gtk_2_3_compat.h"
#include "gtk_compat.h"
#include <cairo.h>
#include "gtk_display.h"
#include "gtk_display_driver_gtk.h"
#include "snes9x.h"
S9xGTKDisplayDriver::S9xGTKDisplayDriver(Snes9xWindow *window,
Snes9xConfig *config)
{
this->window = window;
this->config = config;
this->drawing_area = GTK_WIDGET(window->drawing_area);
this->drawing_area = window->drawing_area;
}
void S9xGTKDisplayDriver::update(uint16_t *buffer, int width, int height, int stride_in_pixels)
{
GtkAllocation allocation;
if (width <= 0)
return;
gtk_widget_get_allocation(drawing_area, &allocation);
S9xRect dst = S9xApplyAspect(width, height, allocation.width, allocation.height);
S9xRect dst = S9xApplyAspect(width, height, drawing_area->get_width(), drawing_area->get_height());
output(buffer, stride_in_pixels * 2, dst.x, dst.y, width, height, dst.w, dst.h);
}
@ -48,7 +44,6 @@ void S9xGTKDisplayDriver::output(void *src,
}
cairo_t *cr = window->get_cairo();
cairo_surface_t *surface;
surface = cairo_image_surface_create_for_data((unsigned char *)src, CAIRO_FORMAT_RGB16_565, width, height, src_pitch);
@ -94,12 +89,8 @@ void S9xGTKDisplayDriver::deinit()
void S9xGTKDisplayDriver::clear()
{
int width, height;
GtkAllocation allocation;
gtk_widget_get_allocation(drawing_area, &allocation);
width = allocation.width;
height = allocation.height;
int width = drawing_area->get_width();
int height = drawing_area->get_height();
cairo_t *cr = window->get_cairo();

View File

@ -4,7 +4,7 @@
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
#include "gtk_2_3_compat.h"
#include "gtk_compat.h"
#include <dlfcn.h>
#include <sys/stat.h>
#include <fcntl.h>
@ -85,26 +85,23 @@ S9xOpenGLDisplayDriver::S9xOpenGLDisplayDriver(Snes9xWindow *window, Snes9xConfi
{
this->window = window;
this->config = config;
this->drawing_area = GTK_WIDGET(window->drawing_area);
this->drawing_area = window->drawing_area;
}
void S9xOpenGLDisplayDriver::update(uint16_t *buffer, int width, int height, int stride_in_pixels)
{
GtkAllocation allocation;
gtk_widget_get_allocation(drawing_area, &allocation);
Gtk::Allocation allocation = drawing_area->get_allocation();
if (output_window_width != allocation.width ||
output_window_height != allocation.height)
if (output_window_width != allocation.get_width() ||
output_window_height != allocation.get_height())
{
resize();
}
#if GTK_CHECK_VERSION(3, 10, 0)
int gdk_scale_factor = gdk_window_get_scale_factor(gdk_window);
int scale_factor = drawing_area->get_scale_factor();
allocation.width *= gdk_scale_factor;
allocation.height *= gdk_scale_factor;
#endif
allocation.set_width(allocation.get_width() * scale_factor);
allocation.set_height(allocation.get_height() * scale_factor);
if (!legacy)
glActiveTexture(GL_TEXTURE0);
@ -118,8 +115,8 @@ void S9xOpenGLDisplayDriver::update(uint16_t *buffer, int width, int height, int
glClear(GL_COLOR_BUFFER_BIT);
S9xRect content = S9xApplyAspect(width, height, allocation.width, allocation.height);
glViewport(content.x, allocation.height - content.y - content.h, content.w, content.h);
S9xRect content = S9xApplyAspect(width, height, allocation.get_width(), allocation.get_height());
glViewport(content.x, allocation.get_height() - content.y - content.h, content.w, content.h);
window->set_mouseable_area(content.x, content.y, content.w, content.h);
update_texture_size(width, height);
@ -183,7 +180,7 @@ void S9xOpenGLDisplayDriver::update(uint16_t *buffer, int width, int height, int
if (using_glsl_shaders)
{
glsl_shader->render(texmap, width, height, content.x, allocation.height - content.y - content.h, content.w, content.h, S9xViewportCallback);
glsl_shader->render(texmap, width, height, content.x, allocation.get_height() - content.y - content.h, content.w, content.h, S9xViewportCallback);
swap_buffers();
return;
}
@ -468,24 +465,26 @@ void S9xOpenGLDisplayDriver::resize()
bool S9xOpenGLDisplayDriver::create_context()
{
gdk_window = gtk_widget_get_window(drawing_area);
gdk_window = drawing_area->get_window()->gobj();
GdkDisplay *gdk_display = drawing_area->get_display()->gobj();
#ifdef GDK_WINDOWING_WAYLAND
if (GDK_IS_WAYLAND_WINDOW(gdk_window))
{
if (!wl.attach(GTK_WIDGET(drawing_area->gobj())))
return false;
context = &wl;
}
#endif
#ifdef GDK_WINDOWING_X11
if (GDK_IS_X11_WINDOW(gdk_window))
{
if (!glx.attach(gdk_x11_display_get_xdisplay(gdk_display), gdk_x11_window_get_xid(gdk_window)))
return false;
context = &glx;
}
#endif
if (!context->attach(drawing_area))
return false;
if (!context->create_context())
return false;

View File

@ -14,7 +14,7 @@
#include "gtk_opengl_context.h"
#include "gtk_2_3_compat.h"
#include "gtk_compat.h"
#ifdef GDK_WINDOWING_X11
#include "gtk_glx_context.h"
#endif

View File

@ -4,7 +4,7 @@
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
#include "gtk_2_3_compat.h"
#include "gtk_compat.h"
#include <X11/extensions/XShm.h>
#include <X11/extensions/Xv.h>
#include <X11/extensions/Xvlib.h>
@ -31,15 +31,14 @@ static int get_inv_shift(uint32 mask, int bpp)
return (bpp - i);
}
S9xXVDisplayDriver::S9xXVDisplayDriver(Snes9xWindow *window,
Snes9xConfig *config)
S9xXVDisplayDriver::S9xXVDisplayDriver(Snes9xWindow *window, Snes9xConfig *config)
{
this->window = window;
this->config = config;
this->drawing_area = GTK_WIDGET(window->drawing_area);
display =
gdk_x11_display_get_xdisplay(gtk_widget_get_display(drawing_area));
last_known_width = last_known_height = -1;
this->drawing_area = window->drawing_area;
display = gdk_x11_display_get_xdisplay(drawing_area->get_display()->gobj());
last_known_width = -1;
last_known_height = -1;
}
void S9xXVDisplayDriver::resize_window(int width, int height)
@ -59,12 +58,13 @@ void S9xXVDisplayDriver::create_window(int width, int height)
window_attr.y = 0;
window_attr.wclass = GDK_INPUT_OUTPUT;
window_attr.window_type = GDK_WINDOW_CHILD;
window_attr.visual = gdk_x11_screen_lookup_visual(gtk_widget_get_screen(drawing_area), vi->visualid);
window_attr.visual = gdk_x11_screen_lookup_visual(drawing_area->get_screen()->gobj(), vi->visualid);
gdk_window = gdk_window_new(gtk_widget_get_window(drawing_area),
gdk_window = gdk_window_new(drawing_area->get_window()->gobj(),
&window_attr,
GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL);
gdk_window_set_user_data(gdk_window, (gpointer)drawing_area);
gdk_window_set_user_data(gdk_window, (gpointer)drawing_area->gobj());
gdk_window_show(gdk_window);
xwindow = gdk_x11_window_get_xid(gdk_window);
@ -76,26 +76,22 @@ void S9xXVDisplayDriver::create_window(int width, int height)
void S9xXVDisplayDriver::update(uint16_t *buffer, int width, int height, int stride_in_pixels)
{
int current_width, current_height;
GtkAllocation allocation;
gtk_widget_get_allocation(drawing_area, &allocation);
auto allocation = drawing_area->get_allocation();
if (output_window_width != allocation.width ||
output_window_height != allocation.height)
if (output_window_width != allocation.get_width() ||
output_window_height != allocation.get_height())
{
resize_window(allocation.width, allocation.height);
resize_window(allocation.get_width(), allocation.get_height());
}
#if GTK_CHECK_VERSION(3, 10, 0)
int gdk_scale_factor = gdk_window_get_scale_factor(gdk_window);
int scale_factor = drawing_area->get_scale_factor();
allocation.width *= gdk_scale_factor;
allocation.height *= gdk_scale_factor;
allocation.set_width(allocation.get_width() * scale_factor);
allocation.set_height(allocation.get_height() * scale_factor);
#endif
current_width = allocation.width;
current_height = allocation.height;
current_width = allocation.get_width();
current_height = allocation.get_height();
update_image_size(width, height);
@ -178,7 +174,7 @@ void S9xXVDisplayDriver::update_image_size(int width, int height)
{
/* Can't recover, send exit. */
fprintf(stderr, "Couldn't reallocate shared memory.\n");
S9xExit();
exit(1);
}
else if (shm.shmaddr != (void *)-1)
{
@ -209,10 +205,10 @@ int S9xXVDisplayDriver::init()
GdkWindow *root;
/* Setup XV */
gtk_widget_realize(drawing_area);
gtk_widget_realize(GTK_WIDGET(drawing_area->gobj()));
display = gdk_x11_display_get_xdisplay(gtk_widget_get_display(drawing_area));
screen = gtk_widget_get_screen(drawing_area);
display = gdk_x11_display_get_xdisplay(drawing_area->get_display()->gobj());
screen = drawing_area->get_screen()->gobj();
root = gdk_screen_get_root_window(screen);
xv_portid = -1;
@ -391,7 +387,7 @@ int S9xXVDisplayDriver::init()
}
xcolormap = XCreateColormap(display,
gdk_x11_window_get_xid(gtk_widget_get_window(drawing_area)),
gdk_x11_window_get_xid(drawing_area->get_window()->gobj()),
vi->visual,
AllocNone);
@ -443,20 +439,10 @@ void S9xXVDisplayDriver::deinit()
void S9xXVDisplayDriver::clear()
{
int width, height;
GtkAllocation allocation;
GC xgc = XDefaultGC(display, XDefaultScreen(display));
gtk_widget_get_allocation(drawing_area, &allocation);
#if GTK_CHECK_VERSION(3, 10, 0)
int gdk_scale_factor = gdk_window_get_scale_factor(gdk_window);
allocation.width *= gdk_scale_factor;
allocation.height *= gdk_scale_factor;
#endif
width = allocation.width;
height = allocation.height;
int width = drawing_area->get_width() * drawing_area->get_scale_factor();
int height = drawing_area->get_height() * drawing_area->get_scale_factor();
if (window->last_width <= 0 || window->last_height <= 0)
{

View File

@ -7,14 +7,14 @@
#ifndef __GTK_DISPLAY_DRIVER_XV_H
#define __GTK_DISPLAY_DRIVER_XV_H
#include "gtk_s9x.h"
#include "gtk_display_driver.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/XShm.h>
#include <X11/extensions/Xvlib.h>
#include "gtk_s9x.h"
#include "gtk_display_driver.h"
const uint32 FOURCC_YUY2 = 0x32595559;
class S9xXVDisplayDriver : public S9xDisplayDriver

View File

@ -7,27 +7,29 @@
#include <sys/stat.h>
#include <errno.h>
#include "gtk_2_3_compat.h"
#include "gtk_compat.h"
#include "gtk_s9x.h"
#include "display.h"
#include "memmap.h"
#include "snapshot.h"
#include "cheats.h"
static char buf[PATH_MAX];
const char *
S9xChooseMovieFilename (bool8 read_only)
const char *S9xChooseMovieFilename(bool8 read_only)
{
static char path[PATH_MAX];
if (!gui_config->rom_loaded)
return "";
const char *str = top_level->open_movie_dialog (read_only);
strcpy (path, str);
auto filename = top_level->open_movie_dialog(read_only);
strcpy(path, filename.c_str());
return path;
}
const char *
S9xChooseFilename (bool8 read_only)
const char *S9xChooseFilename(bool8 read_only)
{
return "";
}
@ -37,8 +39,7 @@ S9xChooseFilename (bool8 read_only)
#define SLASH_CHAR '/'
#endif
void
_splitpath (const char *path, char *drive, char *dir, char *fname, char *ext)
void _splitpath(const char *path, char *drive, char *dir, char *fname, char *ext)
{
char *slash = strrchr((char *)path, SLASH_CHAR);
char *dot = strrchr((char *)path, '.');
@ -83,12 +84,7 @@ _splitpath (const char *path, char *drive, char *dir, char *fname, char *ext)
}
}
void
_makepath (char *path,
const char *drive,
const char *dir,
const char *fname,
const char *ext)
void _makepath(char *path, const char *drive, const char *dir, const char *fname, const char *ext)
{
if (dir && *dir)
{
@ -107,8 +103,7 @@ _makepath (char *path,
}
}
const char *
S9xGetFilenameInc (const char *e, enum s9x_getdirtype dirtype)
const char *S9xGetFilenameInc(const char *e, enum s9x_getdirtype dirtype)
{
static char filename[PATH_MAX + 1];
char dir[_MAX_DIR + 1];
@ -126,14 +121,12 @@ S9xGetFilenameInc (const char *e, enum s9x_getdirtype dirtype)
{
snprintf(filename, PATH_MAX, "%s" SLASH_STR "%s%03d%s", d, fname, i, e);
i++;
}
while (stat (filename, &buf) == 0 && i != 0); /* Overflow? ...riiight :-) */
} while (stat(filename, &buf) == 0 && i != 0); /* Overflow? ...riiight :-) */
return (filename);
}
const char *
S9xGetDirectory (enum s9x_getdirtype dirtype)
const char *S9xGetDirectory(enum s9x_getdirtype dirtype)
{
static char path[PATH_MAX + 1];
@ -207,8 +200,7 @@ S9xGetDirectory (enum s9x_getdirtype dirtype)
return path;
}
const char *
S9xGetFilename (const char *ex, enum s9x_getdirtype dirtype)
const char *S9xGetFilename(const char *ex, enum s9x_getdirtype dirtype)
{
static char filename[PATH_MAX + 1];
char dir[_MAX_DIR + 1];
@ -224,8 +216,7 @@ S9xGetFilename (const char *ex, enum s9x_getdirtype dirtype)
return (filename);
}
const char *
S9xBasename (const char *f)
const char *S9xBasename(const char *f)
{
const char *p;
@ -235,8 +226,7 @@ S9xBasename (const char *f)
return f;
}
const char *
S9xBasenameNoExt (const char *f)
const char *S9xBasenameNoExt(const char *f)
{
static char filename[PATH_MAX];
const char *base, *ext;
@ -260,8 +250,7 @@ S9xBasenameNoExt (const char *f)
return filename;
}
static int
file_exists (const char *name)
static int file_exists(const char *name)
{
FILE *f = NULL;
@ -276,8 +265,7 @@ file_exists (const char *name)
}
}
bool8
S9xOpenSnapshotFile (const char *fname, bool8 read_only, STREAM *file)
bool8 S9xOpenSnapshotFile(const char *fname, bool8 read_only, STREAM *file)
{
char filename[PATH_MAX + 1];
char drive[_MAX_DRIVE + 1];
@ -367,15 +355,13 @@ void S9xCloseSnapshotFile (STREAM file)
#endif
}
void
S9xAutoSaveSRAM ()
void S9xAutoSaveSRAM()
{
Memory.SaveSRAM(S9xGetFilename(".srm", SRAM_DIR));
S9xSaveCheatFile(S9xGetFilename(".cht", CHEAT_DIR));
}
void
S9xLoadState (const char *filename)
void S9xLoadState(const char *filename)
{
S9xFreezeGame(S9xGetFilename(".undo", SNAPSHOT_DIR));
@ -390,8 +376,7 @@ S9xLoadState (const char *filename)
}
}
void
S9xSaveState (const char *filename)
void S9xSaveState(const char *filename)
{
if (S9xFreezeGame(filename))
{
@ -404,82 +389,8 @@ S9xSaveState (const char *filename)
}
}
char *
S9xOpenROMDialog ()
{
GtkWidget *dialog;
GtkFileFilter *filter;
char *filename = NULL;
gint result;
const char *extensions[] =
{
"*.smc", "*.SMC", "*.fig", "*.FIG", "*.sfc", "*.SFC",
"*.jma", "*.JMA", "*.zip", "*.ZIP", "*.gd3", "*.GD3",
"*.swc", "*.SWC", "*.gz" , "*.GZ", "*.bs", "*.BS",
NULL
};
top_level->pause_from_focus_change ();
dialog = gtk_file_chooser_dialog_new (_("Open SNES ROM Image"),
top_level->get_window (),
GTK_FILE_CHOOSER_ACTION_OPEN,
"gtk-cancel", GTK_RESPONSE_CANCEL,
"gtk-open", GTK_RESPONSE_ACCEPT,
NULL);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("SNES ROM Images"));
for (int i = 0; extensions[i]; i++)
{
gtk_file_filter_add_pattern (filter, extensions[i]);
}
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("All Files"));
gtk_file_filter_add_pattern (filter, "*.*");
gtk_file_filter_add_pattern (filter, "*");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
if (!gui_config->last_directory.empty ())
{
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog),
gui_config->last_directory.c_str ());
}
result = gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_hide (dialog);
if (result == GTK_RESPONSE_ACCEPT)
{
char *directory;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
directory =
gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
if (directory)
{
gui_config->last_directory = directory;
g_free (directory);
}
}
else
{
filename = NULL;
}
gtk_widget_destroy (dialog);
top_level->unpause_from_focus_change ();
return filename;
}
/* QuickSave/Load from S9x base controls.cpp */
void
S9xQuickSaveSlot (int slot)
void S9xQuickSaveSlot(int slot)
{
char def[PATH_MAX];
char filename[PATH_MAX];
@ -555,4 +466,3 @@ void S9xQuickLoadSlot (int slot)
S9X_FREEZE_FILE_NOT_FOUND,
"Freeze file not found");
}

View File

@ -7,7 +7,6 @@
#ifndef __GTK_FILE_H
#define __GTK_FILE_H
char *S9xOpenROMDialog ();
const char *S9xBasenameNoExt(const char *);
void S9xLoadState(const char *filename);

View File

@ -6,18 +6,14 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "gtk_s9x.h"
#include "gtk_glx_context.h"
#include "gtk_2_3_compat.h"
GTKGLXContext::GTKGLXContext()
{
gdk_display = NULL;
parent_gdk_window = NULL;
gdk_window = NULL;
display = NULL;
vi = NULL;
context = NULL;
version_major = -1;
@ -30,18 +26,10 @@ GTKGLXContext::~GTKGLXContext ()
{
if (context)
glXDestroyContext(display, context);
if (gdk_window)
gdk_window_destroy (gdk_window);
if (vi)
XFree (vi);
}
bool GTKGLXContext::attach (GtkWidget *widget)
bool GTKGLXContext::attach(Display *dpy, Window xid)
{
GdkScreen *gdk_screen;
GdkWindow *window;
GLXFBConfig *fbconfigs;
int num_fbconfigs;
@ -54,17 +42,8 @@ bool GTKGLXContext::attach (GtkWidget *widget)
None
};
window = gtk_widget_get_window (widget);
this->widget = widget;
if (!GDK_IS_X11_WINDOW (window))
return false;
parent_gdk_window = window;
gdk_display = gdk_window_get_display (window);
gdk_screen = gdk_window_get_screen (window);
screen = gdk_x11_screen_get_screen_number (gdk_screen);
display = GDK_DISPLAY_XDISPLAY (gdk_display);
this->xid = xid;
display = dpy;
glXQueryVersion(display, &version_major, &version_minor);
if (version_major < 2 && version_minor < 3)
@ -77,23 +56,6 @@ bool GTKGLXContext::attach (GtkWidget *widget)
return false;
}
fbconfig = fbconfigs[0];
XFree(fbconfigs);
vi = glXGetVisualFromFBConfig (display, fbconfig);
gdk_window_get_geometry (parent_gdk_window, &x, &y, &width, &height);
memset (&window_attr, 0, sizeof (GdkWindowAttr));
window_attr.event_mask = GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK;
window_attr.width = width;
window_attr.height = height;
window_attr.wclass = GDK_INPUT_OUTPUT;
window_attr.window_type = GDK_WINDOW_CHILD;
window_attr.visual = gdk_x11_screen_lookup_visual (gdk_screen, vi->visualid);
gdk_window = gdk_window_new (window, &window_attr, GDK_WA_VISUAL);
gdk_window_set_user_data (gdk_window, (gpointer) widget);
gdk_window_show (gdk_window);
xid = gdk_x11_window_get_xid (gdk_window);
return true;
}
@ -109,12 +71,15 @@ bool GTKGLXContext::create_context ()
const char *extensions = glXQueryExtensionsString(display, screen);
gdk_x11_display_error_trap_push(gdk_display);
XSetErrorHandler([](Display *dpy, XErrorEvent *event) -> int {
printf("XError: type: %d code: %d\n", event->type, event->error_code);
return X_OK;
});
if (strstr(extensions, "GLX_ARB_create_context"))
context = glXCreateContextAttribsARB(display, fbconfig, NULL, True, context_attribs);
if (!context)
context = glXCreateNewContext(display, fbconfig, GLX_RGBA_TYPE, NULL, True);
gdk_x11_display_error_trap_pop_ignored(gdk_display);
XSetErrorHandler(nullptr);
if (!context)
{
@ -130,20 +95,16 @@ bool GTKGLXContext::create_context ()
void GTKGLXContext::resize()
{
gdk_window_get_geometry (parent_gdk_window, &x, &y, &width, &height);
while (!ready())
usleep(100);
if (window_attr.width == width && window_attr.height == height)
return;
window_attr.width = width;
window_attr.height = height;
gdk_window_destroy (gdk_window);
gdk_window = gdk_window_new (parent_gdk_window, &window_attr, GDK_WA_VISUAL);
gdk_window_set_user_data (gdk_window, (gpointer) widget);
gdk_window_show (gdk_window);
xid = gdk_x11_window_get_xid (gdk_window);
unsigned int width;
unsigned int height;
glXQueryDrawable(display, xid, GLX_WIDTH, &width);
glXQueryDrawable(display, xid, GLX_HEIGHT, &height);
this->width = width;
this->height = height;
make_current();
}
@ -186,5 +147,3 @@ void GTKGLXContext::swap_interval (int frames)
glXSwapIntervalMESA(frames);
#endif
}

View File

@ -7,17 +7,16 @@
#ifndef __GTK_GLX_CONTEXT_H
#define __GTK_GLX_CONTEXT_H
#include "gtk_2_3_compat.h"
#include <epoxy/glx.h>
#include "gtk_opengl_context.h"
#include <epoxy/glx.h>
class GTKGLXContext : public OpenGLContext
{
public:
GTKGLXContext();
~GTKGLXContext();
bool attach (GtkWidget *widget);
bool attach(Display *dpy, Window xid);
bool create_context();
void resize();
void swap_buffers();
@ -25,18 +24,10 @@ class GTKGLXContext : public OpenGLContext
void make_current();
bool ready();
GtkWidget *widget;
GdkDisplay *gdk_display;
GdkWindow *parent_gdk_window;
GdkWindow *gdk_window;
GdkWindowAttr window_attr;
GLXContext context;
GLXFBConfig fbconfig;
Display *display;
int screen;
XVisualInfo *vi;
Window xid;
int version_major;

View File

@ -10,6 +10,12 @@
#include "gtk_netplay_dialog.h"
#include "gtk_netplay.h"
#include "gtk_sound.h"
#include "snes9x.h"
#include "memmap.h"
#include "netplay.h"
#include "cpuexec.h"
#include "display.h"
#include "ppu.h"
uint16 MovieGetJoypad(int i);
void MovieSetJoypad(int i, uint16 buttons);
@ -19,8 +25,7 @@ static GThread *npthread;
extern SNPServer NPServer;
static void
S9xNetplayPreconnect ()
static void S9xNetplayPreconnect()
{
S9xNetplayDisconnect();
@ -33,8 +38,7 @@ S9xNetplayPreconnect ()
NetPlay.Waiting4EmulationThread = false;
}
static void
S9xNetplayConnect ()
static void S9xNetplayConnect()
{
GtkWidget *msg;
@ -43,7 +47,7 @@ S9xNetplayConnect ()
uint32 flags = CPU.Flags;
if (!gui_config->netplay_last_rom.empty() &&
!top_level->try_open_rom (gui_config->netplay_last_rom.c_str ()))
!top_level->try_open_rom(gui_config->netplay_last_rom))
{
return;
}
@ -81,15 +85,13 @@ S9xNetplayConnect ()
top_level->configure_widgets();
}
void
S9xNetplaySyncClients ()
void S9xNetplaySyncClients()
{
if (Settings.NetPlay && Settings.NetPlayServer)
S9xNPServerQueueSyncAll();
}
void
S9xNetplayStopServer ()
void S9xNetplayStopServer()
{
S9xNPStopServer();
@ -98,8 +100,7 @@ S9xNetplayStopServer ()
gui_config->netplay_server_up = false;
}
void
S9xNetplayDisconnect ()
void S9xNetplayDisconnect()
{
if (Settings.NetPlay)
{
@ -118,16 +119,14 @@ S9xNetplayDisconnect ()
top_level->configure_widgets();
}
static gpointer
S9xNetplayServerThread (gpointer)
static gpointer S9xNetplayServerThread(gpointer)
{
S9xNPStartServer(gui_config->netplay_default_port);
return NULL;
}
void
S9xNetplayStartServer ()
void S9xNetplayStartServer()
{
uint32 flags;
@ -136,7 +135,7 @@ S9xNetplayStartServer ()
flags = CPU.Flags;
if (gui_config->netplay_last_rom.empty() ||
!top_level->try_open_rom (gui_config->netplay_last_rom.c_str ()))
!top_level->try_open_rom(gui_config->netplay_last_rom))
{
return;
}
@ -166,8 +165,7 @@ S9xNetplayStartServer ()
top_level->configure_widgets();
}
void
S9xNetplayDialogOpen ()
void S9xNetplayDialogOpen()
{
Snes9xNetplayDialog *np_dialog;
@ -197,8 +195,7 @@ S9xNetplayDialogOpen ()
top_level->unpause_from_focus_change();
}
int
S9xNetplaySyncSpeed ()
int S9xNetplaySyncSpeed()
{
if (!Settings.NetPlay || !NetPlay.Connected)
return 0;
@ -266,8 +263,7 @@ S9xNetplaySyncSpeed ()
return 1;
}
int
S9xNetplayPush ()
int S9xNetplayPush()
{
if (gui_config->netplay_activated &&
(!Settings.NetPlay || !NetPlay.Connected))
@ -308,8 +304,7 @@ S9xNetplayPush ()
return 0;
}
void
S9xNetplayPop ()
void S9xNetplayPop()
{
if (!Settings.NetPlay)
return;
@ -317,7 +312,3 @@ S9xNetplayPop ()
for (int i = 0; i < 8; i++)
MovieSetJoypad(i, local_joypads[i]);
}

View File

@ -6,59 +6,32 @@
#include "gtk_netplay_dialog.h"
#include "gtk_s9x.h"
#include "gtk_file.h"
static void
event_browse_clicked (GtkButton *button, gpointer data)
Snes9xNetplayDialog::Snes9xNetplayDialog(Snes9xConfig *config)
: GtkBuilderWindow("netplay_dialog")
{
char *filename;
Snes9xNetplayDialog *np_dialog = (Snes9xNetplayDialog *) data;
get_object<Gtk::RadioButton>("host_radio")->signal_toggled().connect([&] {
update_state();
});
filename = S9xOpenROMDialog ();
get_object<Gtk::Button>("clear_netplay")->signal_clicked().connect([&] {
get_object<Gtk::Entry>("rom_image")->set_text("");
});
if (filename)
{
gtk_entry_set_text (GTK_ENTRY (np_dialog->get_widget ("rom_image")),
filename);
g_free (filename);
}
}
static void
event_clear_clicked (GtkButton *button, gpointer data)
{
Snes9xNetplayDialog *np_dialog = (Snes9xNetplayDialog *) data;
gtk_entry_set_text (GTK_ENTRY (np_dialog->get_widget ("rom_image")), "");
}
static void
event_server_toggled (GtkToggleButton *toggle, gpointer data)
{
Snes9xNetplayDialog *np_dialog = (Snes9xNetplayDialog *) data;
np_dialog->update_state ();
}
Snes9xNetplayDialog::Snes9xNetplayDialog (Snes9xConfig *config) :
GtkBuilderWindow ("netplay_dialog")
{
GtkBuilderWindowCallbacks callbacks[] =
{
{ "server_toggled", G_CALLBACK (event_server_toggled) },
{ "browse_clicked", G_CALLBACK (event_browse_clicked) },
{ "clear_clicked", G_CALLBACK (event_clear_clicked) },
{ NULL, NULL }
};
signal_connect (callbacks);
get_object<Gtk::Button>("browse_button")->signal_clicked().connect([&] {
auto filename = top_level->open_rom_dialog(false);
if (!filename.empty())
get_object<Gtk::Entry>("rom_image")->set_text(filename);
});
this->config = config;
}
void
Snes9xNetplayDialog::update_state ()
Snes9xNetplayDialog::~Snes9xNetplayDialog()
{
}
void Snes9xNetplayDialog::update_state()
{
if (get_check("host_radio"))
{
@ -77,8 +50,7 @@ Snes9xNetplayDialog::update_state ()
}
}
void
Snes9xNetplayDialog::settings_to_dialog ()
void Snes9xNetplayDialog::settings_to_dialog()
{
set_entry_text("rom_image", config->netplay_last_rom.c_str());
set_entry_text("ip_entry", config->netplay_last_host.c_str());
@ -93,8 +65,7 @@ Snes9xNetplayDialog::settings_to_dialog ()
update_state();
}
void
Snes9xNetplayDialog::settings_from_dialog ()
void Snes9xNetplayDialog::settings_from_dialog()
{
config->netplay_last_rom = get_entry_text("rom_image");
config->netplay_last_host = get_entry_text("ip_entry");
@ -110,29 +81,16 @@ Snes9xNetplayDialog::settings_from_dialog ()
bool Snes9xNetplayDialog::show()
{
int result;
settings_to_dialog();
result = gtk_dialog_run (GTK_DIALOG (window));
auto result = Glib::RefPtr<Gtk::Dialog>::cast_static(window)->run();
window->hide();
gtk_widget_hide (window);
if (result == GTK_RESPONSE_OK)
if (result == Gtk::RESPONSE_OK)
{
settings_from_dialog();
return true;
}
else
{
return false;
}
}
Snes9xNetplayDialog::~Snes9xNetplayDialog ()
{
gtk_widget_destroy (window);
}

View File

@ -24,5 +24,4 @@ class Snes9xNetplayDialog : public GtkBuilderWindow
void settings_from_dialog();
};
#endif /* __GTK_NETPLAY_DIALOG_H */

View File

@ -7,19 +7,19 @@
#ifndef __GTK_OPENGL_CONTEXT_H
#define __GTK_OPENGL_CONTEXT_H
#include "gtk_2_3_compat.h"
class OpenGLContext
{
public:
virtual ~OpenGLContext(){};
virtual bool attach (GtkWidget *widget) = 0;
virtual bool create_context() = 0;
virtual void resize() = 0;
virtual void swap_buffers() = 0;
virtual void swap_interval(int frames) = 0;
virtual void make_current() = 0;
virtual bool ready() { return true; };
virtual bool ready()
{
return true;
};
int x;
int y;

File diff suppressed because it is too large Load Diff

View File

@ -7,12 +7,11 @@
#ifndef __GTK_PREFERENCES_H
#define __GTK_PREFERENCES_H
#include "gtk_2_3_compat.h"
#include "gtk_compat.h"
#include "gtk_s9x.h"
#include "gtk_builder_window.h"
gboolean snes9x_preferences_open (GtkWidget *widget,
gpointer data);
void snes9x_preferences_open(Snes9xWindow *window, Snes9xConfig *config);
class Snes9xPreferences : public GtkBuilderWindow
{
@ -23,7 +22,6 @@ class Snes9xPreferences : public GtkBuilderWindow
void bindings_to_dialog(int joypad);
int get_focused_binding();
void store_binding(const char *string, Binding binding);
void browse_folder_dialog ();
int hw_accel_value(int combo_value);
int combo_value(int hw_accel);
void focus_next();
@ -33,9 +31,15 @@ class Snes9xPreferences : public GtkBuilderWindow
void load_ntsc_settings();
void store_ntsc_settings();
void calibration_dialog();
void connect_signals();
void input_rate_changed();
bool key_pressed(GdkEventKey *event);
void scale_method_changed();
void shader_select();
void game_data_browse(std::string folder);
void about_dialog();
Snes9xConfig *config;
GtkToggleButton *last_toggled;
bool awaiting_key;
bool polling_joystick;
std::array<JoypadBinding, NUM_JOYPADS> pad;
@ -44,8 +48,6 @@ class Snes9xPreferences : public GtkBuilderWindow
private:
void get_settings_from_dialog();
void move_settings_to_dialog();
unsigned int *mode_indices;
};
#endif /* __GTK_PREFERENCES_H */

View File

@ -6,7 +6,9 @@
#include <stdio.h>
#include <signal.h>
#include "gtk_2_3_compat.h"
#include "giomm/application.h"
#include "glibmm/main.h"
#include "gtk_compat.h"
#include "gtk_config.h"
#include "gtk_s9x.h"
#include "gtk_control.h"
@ -15,13 +17,22 @@
#include "gtk_netplay.h"
#include "statemanager.h"
#include "background_particles.h"
#include "snes9x.h"
#include "display.h"
#include "apu/apu.h"
#include "netplay.h"
#include "movie.h"
#include "controls.h"
#include "snapshot.h"
#include "gfx.h"
#include "memmap.h"
#include "ppu.h"
void S9xPostRomInit ();
static void S9xThrottle(int);
static void S9xCheckPointerTimer();
static gboolean S9xIdleFunc (gpointer data);
static gboolean S9xPauseFunc (gpointer data);
static gboolean S9xScreenSaverCheckFunc (gpointer data);
static bool S9xIdleFunc();
static bool S9xPauseFunc();
static bool S9xScreenSaverCheckFunc();
Snes9xWindow *top_level;
Snes9xConfig *gui_config;
@ -29,9 +40,9 @@ StateManager state_manager;
gint64 frame_clock = -1;
gint64 pointer_timestamp = -1;
Background::Particles particles(Background::Particles::Mode::Snow);
Background::Particles particles(Background::Particles::Snow);
void S9xTerm (int signal)
static void S9xTerm(int signal)
{
S9xExit();
}
@ -39,8 +50,7 @@ void S9xTerm (int signal)
int main(int argc, char *argv[])
{
struct sigaction sig_callback;
gtk_init (&argc, &argv);
auto app = Gtk::Application::create(argc, argv, "com.snes9x.gtk", Gio::APPLICATION_NON_UNIQUE);
setlocale(LC_ALL, "");
bindtextdomain(GETTEXT_PACKAGE, SNES9XLOCALEDIR);
@ -49,10 +59,9 @@ int main (int argc, char *argv[])
memset(&Settings, 0, sizeof(Settings));
/* Allow original config file for backend settings */
// Original config fills out values this port doesn't.
S9xLoadConfigFiles(argv, argc);
/* Perform our config here */
gui_config = new Snes9xConfig();
S9xInitInputDevices();
@ -61,13 +70,9 @@ int main (int argc, char *argv[])
char *rom_filename = S9xParseArgs(argv, argc);
#if GTK_MAJOR_VERSION >= 3
auto settings = gtk_settings_get_default();
g_object_set(settings,
"gtk-menu-images", gui_config->enable_icons,
"gtk_button_images", gui_config->enable_icons,
NULL);
#endif
auto settings = Gtk::Settings::get_default();
settings->set_property("gtk-menu-images", gui_config->enable_icons);
settings->set_property("gtk-button-images", gui_config->enable_icons);
S9xReportControllers();
@ -76,16 +81,14 @@ int main (int argc, char *argv[])
top_level = new Snes9xWindow(gui_config);
/* If we're going to fullscreen, do it before showing window to avoid flicker. */
// Setting fullscreen before showing the window avoids some flicker.
if ((gui_config->full_screen_on_open && rom_filename) || (gui_config->fullscreen))
gtk_window_fullscreen (top_level->get_window ());
top_level->window->fullscreen();
top_level->show();
S9xInitDisplay(argc, argv);
Memory.PostRomInitFunc = S9xPostRomInit;
S9xPortSoundInit();
for (int port = 0; port < 2; port++)
@ -118,38 +121,39 @@ int main (int argc, char *argv[])
}
gui_config->rebind_keys();
top_level->update_accels ();
top_level->update_accelerators();
Settings.Paused = true;
g_timeout_add (100, S9xPauseFunc, NULL);
g_timeout_add (10000, S9xScreenSaverCheckFunc, NULL);
Glib::signal_timeout().connect(sigc::ptr_fun(S9xPauseFunc), 100);
Glib::signal_timeout().connect(sigc::ptr_fun(S9xScreenSaverCheckFunc), 10000);
S9xNoROMLoaded();
if (rom_filename)
{
if (S9xOpenROM(rom_filename) && gui_config->full_screen_on_open)
gtk_window_unfullscreen (top_level->get_window());
top_level->window->unfullscreen();
}
memset(&sig_callback, 0, sizeof(struct sigaction));
sig_callback.sa_handler = S9xTerm;
sigaction (15 /* SIGTERM */, &sig_callback, NULL);
sigaction (3 /* SIGQUIT */, &sig_callback, NULL);
sigaction (2 /* SIGINT */, &sig_callback, NULL);
sigaction(15, &sig_callback, NULL); // SIGTERM
sigaction(3, &sig_callback, NULL); // SIGQUIT
sigaction(2, &sig_callback, NULL); // SIGINT
// Perform the complete fullscreen process, including mode sets, which
// didn't happen in the earlier Gtk call.
if (gui_config->fullscreen)
{
top_level->enter_fullscreen_mode();
}
gui_config->flush_joysticks();
if (rom_filename && *Settings.InitialSnapshotFilename)
S9xUnfreezeGame(Settings.InitialSnapshotFilename);
gtk_main ();
app->run(*top_level->window.get());
return 0;
}
@ -259,7 +263,7 @@ void S9xNoROMLoaded ()
top_level->configure_widgets();
}
static gboolean S9xPauseFunc (gpointer data)
static bool S9xPauseFunc()
{
S9xProcessEvents(true);
@ -281,10 +285,8 @@ static gboolean S9xPauseFunc (gpointer data)
}
/* Resume high-performance callback */
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
S9xIdleFunc,
NULL,
NULL);
Glib::signal_idle().connect(sigc::ptr_fun(S9xIdleFunc));
return false;
}
@ -304,12 +306,12 @@ static gboolean S9xPauseFunc (gpointer data)
}
}
g_timeout_add(8, S9xPauseFunc, NULL);
Glib::signal_timeout().connect(sigc::ptr_fun(S9xPauseFunc), 8);
return false;
}
gboolean S9xIdleFunc (gpointer data)
static bool S9xIdleFunc()
{
if (Settings.Paused && gui_config->rom_loaded)
{
@ -323,7 +325,7 @@ gboolean S9xIdleFunc (gpointer data)
}
/* Move to a timer-based function to use less CPU */
g_timeout_add (8, S9xPauseFunc, NULL);
Glib::signal_timeout().connect(sigc::ptr_fun(S9xPauseFunc), 8);
return false;
}
@ -355,21 +357,10 @@ gboolean S9xIdleFunc (gpointer data)
else if (IPPU.TotalEmulatedFrames % gui_config->rewind_granularity == 0)
state_manager.push();
static int muted_from_turbo = false;
static int mute_saved_state = false;
if ((Settings.TurboMode || Settings.Rewinding) && !muted_from_turbo && gui_config->mute_sound_turbo)
{
muted_from_turbo = true;
mute_saved_state = Settings.Mute;
S9xSetSoundMute (true);
}
if (!(Settings.TurboMode || Settings.Rewinding) && muted_from_turbo)
{
muted_from_turbo = false;
Settings.Mute = mute_saved_state;
}
if ((Settings.TurboMode || Settings.Rewinding) && gui_config->mute_sound_turbo)
Settings.Mute |= 0x80;
else
Settings.Mute &= ~0x80;
S9xMainLoop();
@ -379,7 +370,7 @@ gboolean S9xIdleFunc (gpointer data)
return true;
}
gboolean S9xScreenSaverCheckFunc (gpointer data)
static bool S9xScreenSaverCheckFunc()
{
if (!Settings.Paused &&
@ -496,8 +487,7 @@ static void S9xThrottle (int method)
if (Settings.TurboMode)
{
IPPU.FrameSkip++;
if ((IPPU.FrameSkip >= Settings.TurboSkipFrames)
&& !Settings.HighSpeedSeek)
if ((IPPU.FrameSkip >= Settings.TurboSkipFrames) && !Settings.HighSpeedSeek)
{
IPPU.FrameSkip = 0;
IPPU.SkippedFrames = 0;
@ -597,94 +587,12 @@ void S9xExit ()
S9xDeinitInputDevices();
S9xDeinitDisplay();
gtk_main_quit ();
delete top_level;
delete gui_config;
exit(0);
}
void
S9xPostRomInit ()
{
if (!strncmp ((const char *) Memory.NSRTHeader + 24, "NSRT", 4))
{
switch (Memory.NSRTHeader[29])
{
case 0: //Everything goes
break;
case 0x10: //Mouse in Port 0
S9xSetController (0, CTL_MOUSE, 0, 0, 0, 0);
top_level->set_menu_item_selected ("mouse1");
break;
case 0x01: //Mouse in Port 1
S9xSetController (1, CTL_MOUSE, 1, 0, 0, 0);
top_level->set_menu_item_selected ("mouse2");
break;
case 0x03: //Super Scope in Port 1
S9xSetController (1, CTL_SUPERSCOPE, 0, 0, 0, 0);
top_level->set_menu_item_selected ("superscope1");
break;
case 0x06: //Multitap in Port 1
S9xSetController (1, CTL_MP5, 1, 2, 3, 4);
top_level->set_menu_item_selected ("multitap1");
break;
case 0x66: //Multitap in Ports 0 and 1
S9xSetController (0, CTL_MP5, 0, 1, 2, 3);
S9xSetController (1, CTL_MP5, 4, 5, 6, 7);
top_level->set_menu_item_selected ("multitap1");
top_level->set_menu_item_selected ("multitap2");
break;
case 0x08: //Multitap in Port 1, Mouse in new Port 1
S9xSetController (1, CTL_MOUSE, 1, 0, 0, 0);
//There should be a toggle here for putting in Multitap instead
top_level->set_menu_item_selected ("mouse2");
break;
case 0x04: //Pad or Super Scope in Port 1
S9xSetController (1, CTL_SUPERSCOPE, 0, 0, 0, 0);
top_level->set_menu_item_selected ("superscope2");
//There should be a toggle here for putting in a pad instead
break;
case 0x05: //Justifier - Must ask user...
S9xSetController (1, CTL_JUSTIFIER, 1, 0, 0, 0);
//There should be a toggle here for how many justifiers
break;
case 0x20: //Pad or Mouse in Port 0
S9xSetController (0, CTL_MOUSE, 0, 0, 0, 0);
//There should be a toggle here for putting in a pad instead
break;
case 0x22: //Pad or Mouse in Port 0 & 1
S9xSetController (0, CTL_MOUSE, 0, 0, 0, 0);
S9xSetController (1, CTL_MOUSE, 1, 0, 0, 0);
//There should be a toggles here for putting in pads instead
break;
case 0x24: //Pad or Mouse in Port 0, Pad or Super Scope in Port 1
//There should be a toggles here for what to put in, I'm leaving it at gamepad for now
break;
case 0x27: //Pad or Mouse in Port 0, Pad or Mouse or Super Scope in Port 1
//There should be a toggles here for what to put in, I'm leaving it at gamepad for now
break;
//Not Supported yet
case 0x99: break; //Lasabirdie
case 0x0A: break; //Barcode Battler
}
}
}
const char *S9xStringInput(const char *message)
{
return NULL;

View File

@ -8,12 +8,11 @@
#define __GTK_S9X_H
#include "gtk_config.h"
#include "gtk_s9xcore.h"
#include "gtk_s9xwindow.h"
#include <glib/gi18n.h>
#define SNES9X_GTK_AUTHORS "(c) 2007 - 2019 Brandon Wright (bearoso@gmail.com)"
#define SNES9X_GTK_AUTHORS "(c) 2007 - 2020 Brandon Wright (bearoso@gmail.com)"
#define SNES9X_GTK_VERSION "87"
extern Snes9xWindow *top_level;

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
#ifndef __GTK_S9XWINDOW_H
#define __GTK_S9XWINDOW_H
#include "gtk_2_3_compat.h"
#include "gtk_compat.h"
#include "port.h"
#include "gtk_builder_window.h"
@ -18,6 +18,13 @@ class Snes9xWindow : public GtkBuilderWindow
public:
Snes9xWindow(Snes9xConfig *config);
struct AcceleratorEntry
{
std::string name;
unsigned int key;
Gdk::ModifierType modifiers;
};
/* Pause related functions */
void pause_from_focus_change();
void unpause_from_focus_change();
@ -40,13 +47,13 @@ class Snes9xWindow : public GtkBuilderWindow
void center_mouse();
/* Rom-related functions */
void open_rom_dialog ();
std::string open_rom_dialog(bool run = true);
void save_state_dialog();
void load_state_dialog();
void configure_widgets();
void save_spc_dialog();
bool try_open_rom (const char *filename);
const char *open_movie_dialog (bool readonly);
bool try_open_rom(std::string filename);
std::string open_movie_dialog(bool readonly);
void movie_seek_dialog();
void open_multicart_dialog();
void show_rom_info();
@ -55,17 +62,23 @@ class Snes9xWindow : public GtkBuilderWindow
void show();
void set_menu_item_selected(const char *name);
void set_mouseable_area(int x, int y, int width, int height);
void set_menu_item_accel_to_binding (const char *name,
void set_accelerator_to_binding(const char *name,
const char *binding);
void reset_screensaver();
void update_accels ();
void update_accelerators();
void toggle_ui();
void resize_to_multiple(int factor);
void resize_viewport(int width, int height);
void expose ();
bool draw(const Cairo::RefPtr<Cairo::Context> &cr);
void setup_splash();
double get_refresh_rate();
int get_auto_input_rate();
void connect_signals();
bool event_key(GdkEventKey *event);
void port_activate(const char *name);
bool button_press(GdkEventButton *event);
bool button_release(GdkEventButton *event);
bool motion_notify(GdkEventMotion *event);
cairo_t *get_cairo();
void release_cairo();
@ -84,18 +97,20 @@ class Snes9xWindow : public GtkBuilderWindow
double gdk_mouse_x, gdk_mouse_y;
bool mouse_grabbed;
GdkPixbuf *icon, *splash;
GdkCursor *default_cursor, *empty_cursor;
GtkDrawingArea *drawing_area;
GtkWidget *recent_menu;
Gtk::DrawingArea *drawing_area;
Gtk::RecentChooserMenu *recent_menu;
cairo_t *cr;
bool cairo_owned;
#if GTK_MAJOR_VERSION >= 3
GdkDrawingContext *gdk_drawing_context;
cairo_region_t *cairo_region;
#endif
Glib::RefPtr<Gdk::DrawingContext> gdk_drawing_context;
Glib::RefPtr<Gtk::AccelGroup> accel_group;
std::vector<AcceleratorEntry> accelerators;
unsigned int last_key_pressed_keyval;
GdkEventType last_key_pressed_type;
};
typedef struct gtk_splash_t {
typedef struct gtk_splash_t
{
unsigned int width;
unsigned int height;
unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */

View File

@ -4,7 +4,7 @@
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
#include "gtk_2_3_compat.h"
#include "gtk_compat.h"
#include <vector>
#include <math.h>
@ -13,59 +13,27 @@
#include "gtk_shader_parameters.h"
#include "shaders/glsl.h"
static GtkWidget *dialog = NULL;
static std::vector<GLSLParam> *params = NULL;
#include "gfx.h"
static Gtk::Dialog *dialog = nullptr;
static std::vector<GLSLParam> *params = nullptr;
static std::vector<GLSLParam> saved_params;
static inline double snap_to_interval(double value, double interval)
{
if (interval == 0.0)
return value;
return round(value / interval) * interval;
}
static void value_changed(GtkRange *range, gpointer user_data)
static void dialog_response(int response_id)
{
GLSLParam *p = (GLSLParam *)user_data;
GtkAdjustment *adj = gtk_range_get_adjustment(range);
double interval = gtk_adjustment_get_step_increment(adj);
double value = gtk_range_get_value(range);
value = snap_to_interval(value, interval);
gtk_range_set_value(range, value);
if (p->val != value)
{
p->val = value;
if (Settings.Paused)
S9xDeinitUpdate(top_level->last_width, top_level->last_height);
}
}
static void toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
GLSLParam *p = (GLSLParam *)user_data;
double value = (double)gtk_toggle_button_get_active(togglebutton);
if (p->val != value)
{
p->val = value;
if (Settings.Paused)
S9xDeinitUpdate(top_level->last_width, top_level->last_height);
}
}
static void dialog_response(GtkDialog *pdialog, gint response_id, gpointer user_data)
{
std::vector<GLSLParam> *params = (std::vector<GLSLParam> *)user_data;
int width, height;
gtk_window_get_size(GTK_WINDOW(pdialog), &width, &height);
gui_config->shader_parameters_width = width;
gui_config->shader_parameters_height = height;
gui_config->shader_parameters_width = dialog->get_width();
gui_config->shader_parameters_height = dialog->get_height();
switch (response_id)
{
case GTK_RESPONSE_OK:
case Gtk::RESPONSE_OK:
{
char path[PATH_MAX];
std::string config_file = get_config_dir();
@ -78,17 +46,17 @@ static void dialog_response(GtkDialog *pdialog, gint response_id, gpointer user_
gui_config->shader_filename = path;
if (dialog)
gtk_widget_destroy(GTK_WIDGET(dialog));
dialog = NULL;
delete dialog;
dialog = nullptr;
break;
}
case GTK_RESPONSE_CANCEL:
case GTK_RESPONSE_DELETE_EVENT:
case GTK_RESPONSE_NONE:
case Gtk::RESPONSE_CANCEL:
case Gtk::RESPONSE_DELETE_EVENT:
case Gtk::RESPONSE_NONE:
if (dialog)
gtk_widget_destroy(GTK_WIDGET(dialog));
dialog = NULL;
delete dialog;
dialog = nullptr;
*params = saved_params;
if (Settings.Paused)
S9xDeinitUpdate(top_level->last_width, top_level->last_height);
@ -96,17 +64,14 @@ static void dialog_response(GtkDialog *pdialog, gint response_id, gpointer user_
case 15: // Save As
{
auto dialog = gtk_file_chooser_dialog_new(_("Export Shader Preset to:"),
top_level->get_window(),
GTK_FILE_CHOOSER_ACTION_SAVE,
"gtk-cancel", GTK_RESPONSE_CANCEL,
"gtk-save", GTK_RESPONSE_ACCEPT,
NULL);
Gtk::FileChooserDialog dialog(_("Export Shader Preset to:"), Gtk::FILE_CHOOSER_ACTION_SAVE);
dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL);
dialog.add_button(Gtk::StockID("gtk-save"), Gtk::RESPONSE_ACCEPT);
dialog.set_current_folder(gui_config->last_shader_directory);
std::string name;
std::string extension;
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
gui_config->last_shader_directory.c_str());
const char *name;
const char *extension;
if (gui_config->shader_filename.find(".slang") != std::string::npos)
{
name = "new.slangp";
@ -117,26 +82,23 @@ static void dialog_response(GtkDialog *pdialog, gint response_id, gpointer user_
name = "new.glslp";
extension = "*.glslp";
}
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), name);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), true);
auto filter = gtk_file_filter_new();
gtk_file_filter_set_name(filter, _("Shader Preset"));
gtk_file_filter_add_pattern(filter, extension);
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
dialog.set_current_name(name);
dialog.set_do_overwrite_confirmation();
auto result = gtk_dialog_run(GTK_DIALOG(dialog));
auto filter = Gtk::FileFilter::create();
filter->set_name(_("Shader Preset"));
filter->add_pattern(extension);
dialog.add_filter(filter);
auto result = dialog.run();
if (result == GTK_RESPONSE_ACCEPT)
{
auto filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
S9xDisplayGetDriver()->save(filename);
g_free(filename);
}
S9xDisplayGetDriver()->save(dialog.get_filename().c_str());
gtk_widget_destroy(dialog);
break;
}
default:
break;
}
@ -147,8 +109,8 @@ void gtk_shader_parameters_dialog_close()
if (dialog)
{
*params = saved_params;
gtk_widget_destroy(GTK_WIDGET(dialog));
dialog = NULL;
delete dialog;
dialog = nullptr;
}
}
@ -156,7 +118,7 @@ bool gtk_shader_parameters_dialog(GtkWindow *parent)
{
if (dialog)
{
gtk_window_present(GTK_WINDOW(dialog));
dialog->present();
return false;
}
@ -166,145 +128,85 @@ bool gtk_shader_parameters_dialog(GtkWindow *parent)
if (!params || params->size() == 0)
return false;
dialog = gtk_dialog_new_with_buttons(_("Shader Parameters"),
parent,
GTK_DIALOG_DESTROY_WITH_PARENT,
"gtk-cancel",
GTK_RESPONSE_CANCEL,
"gtk-save-as",
15,
"gtk-save",
GTK_RESPONSE_OK,
NULL);
dialog = new Gtk::Dialog(_("Shader Parameters"), Gtk::DIALOG_DESTROY_WITH_PARENT);
dialog->add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL);
dialog->add_button(Gtk::StockID("gtk-save-as"), 15);
dialog->add_button(Gtk::StockID("gtk-save"), GTK_RESPONSE_OK);
dialog->signal_response().connect(sigc::ptr_fun(dialog_response));
g_signal_connect_data(G_OBJECT(dialog), "response", G_CALLBACK(dialog_response), (gpointer)params, NULL, (GConnectFlags)0);
GtkWidget *scrolled_window;
gtk_widget_set_size_request(dialog, 640, 480);
dialog->set_size_request(640, 480);
if (gui_config->shader_parameters_width > 0 && gui_config->shader_parameters_height > 0)
{
gtk_window_resize(GTK_WINDOW(dialog),
gui_config->shader_parameters_width,
gui_config->shader_parameters_height);
}
dialog->resize(gui_config->shader_parameters_width, gui_config->shader_parameters_height);
scrolled_window = gtk_scrolled_window_new(NULL, NULL);
gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
scrolled_window);
auto scrolled_window = new Gtk::ScrolledWindow;
scrolled_window->set_hexpand();
scrolled_window->set_vexpand();
scrolled_window->set_margin_start(5);
scrolled_window->set_margin_end(5);
scrolled_window->set_margin_top(5);
dialog->get_content_area()->add(*scrolled_window);
GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
#if GTK_MAJOR_VERSION >= 3
gtk_widget_set_hexpand(scrolled_window, true);
gtk_widget_set_vexpand(scrolled_window, true);
gtk_widget_set_margin_start(scrolled_window, 5);
gtk_widget_set_margin_end(scrolled_window, 5);
gtk_widget_set_margin_top(scrolled_window, 5);
gtk_widget_set_margin_bottom(scrolled_window, 5);
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
GtkWidget *grid = gtk_grid_new();
gtk_widget_set_margin_end(grid, 5);
gtk_grid_set_row_homogeneous(GTK_GRID(grid), true);
gtk_grid_set_row_spacing(GTK_GRID(grid), 2);
gtk_grid_set_column_spacing(GTK_GRID(grid), 12);
gtk_container_add(GTK_CONTAINER(vbox), grid);
gtk_container_add(GTK_CONTAINER(scrolled_window), vbox);
auto grid = new Gtk::Grid;
grid->set_margin_end(5);
grid->set_row_homogeneous();
grid->set_row_spacing(2);
grid->set_column_spacing(12);
auto vbox = new Gtk::VBox;
vbox->pack_start(*grid);
scrolled_window->add(*vbox);
auto sizegroup = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL);
for (unsigned int i = 0; i < params->size(); i++)
{
GLSLParam *p = &(*params)[i];
GtkWidget *label = gtk_label_new(p->name);
gtk_label_set_xalign(GTK_LABEL(label), 0.0f);
gtk_widget_show(label);
GLSLParam &p = (*params)[i];
auto label = new Gtk::Label(p.name);
label->set_xalign(0.0f);
label->show();
grid->attach(*label, 0, i, 1, 1);
gtk_grid_attach(GTK_GRID(grid), label, 0, i, 1, 1);
if (p->min == 0.0 && p->max == 1.0 && p->step == 1.0)
if (p.min == 0.0 && p.max == 1.0 && p.step == 1.0)
{
GtkWidget *check = gtk_check_button_new();
gtk_grid_attach(GTK_GRID(grid), check, 1, i, 1, 1);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), (int)p->val);
g_signal_connect_data(G_OBJECT(check), "toggled", G_CALLBACK(toggled), (gpointer)p, NULL, (GConnectFlags)0);
auto check = new Gtk::CheckButton;
grid->attach(*check, 1, i, 1, 1);
check->set_active(p.val);
check->signal_toggled().connect([check, &param = p.val] {
double new_value = check->get_active();
if (param != new_value)
{
param = new_value;
if (Settings.Paused)
S9xDeinitUpdate(top_level->last_width, top_level->last_height);
}
});
}
else
{
GtkWidget *spin = gtk_spin_button_new_with_range(p->min, p->max, p->step);
gtk_entry_set_width_chars(GTK_ENTRY(spin), 5);
gtk_grid_attach(GTK_GRID(grid), spin, 1, i, 1, 1);
gtk_size_group_add_widget(sizegroup, spin);
int digits = gtk_spin_button_get_digits(GTK_SPIN_BUTTON(spin));
if (digits == 2)
gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 3);
auto spin = new Gtk::SpinButton(0.0, p.digits);
spin->set_range(p.min, p.max);
spin->get_adjustment()->set_step_increment(p.step);
spin->set_width_chars(6);
grid->attach(*spin, 1, i, 1, 1);
sizegroup->add_widget(*spin);
GtkAdjustment *adjustment = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(spin));
GtkWidget *scale = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, adjustment);
gtk_widget_set_hexpand(scale, true);
gtk_grid_attach(GTK_GRID(grid), scale, 2, i, 1, 1);
gtk_scale_set_draw_value(GTK_SCALE(scale), false);
gtk_range_set_value(GTK_RANGE(scale), p->val);
g_signal_connect_data(G_OBJECT(scale),
"value-changed",
G_CALLBACK(value_changed),
(gpointer)p,
NULL,
(GConnectFlags)0);
}
}
#else
GtkWidget *vbox = gtk_vbox_new(false, 5);
GtkWidget *table = gtk_table_new(params->size(), 3, false);
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
gtk_table_set_col_spacings(GTK_TABLE(table), 12);
gtk_container_add(GTK_CONTAINER(vbox), table);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), vbox);
gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 5);
for (unsigned int i = 0; i < params->size(); i++)
auto scale = new Gtk::Scale(spin->get_adjustment());
scale->set_hexpand();
grid->attach(*scale, 2, i, 1, 1);
scale->set_draw_value(false);
scale->set_value(p.val);
scale->signal_value_changed().connect([spin, &param = p.val] {
double new_value = snap_to_interval(spin->get_value(), spin->get_adjustment()->get_step_increment());
spin->set_value(new_value);
if (param != new_value)
{
GLSLParam *p = &(*params)[i];
GtkWidget *label = gtk_label_new(p->name);
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, i, i + 1, GTK_FILL, GTK_FILL, 0, 0);
if (p->min == 0.0 && p->max == 1.0 && p->step == 1.0)
{
GtkWidget *check = gtk_check_button_new();
gtk_table_attach(GTK_TABLE(table), check, 1, 2, i, i + 1, GTK_FILL, GTK_FILL, 0, 0);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), (int)p->val);
g_signal_connect_data(G_OBJECT(check), "toggled", G_CALLBACK(toggled), (gpointer)p, NULL, (GConnectFlags)0);
param = new_value;
if (Settings.Paused)
S9xDeinitUpdate(top_level->last_width, top_level->last_height);
}
else
{
GtkWidget *spin = gtk_spin_button_new_with_range(p->min, p->max, p->step);
gtk_table_attach(GTK_TABLE(table), spin, 1, 2, i, i + 1, GTK_FILL, GTK_FILL, 0, 0);
gtk_size_group_add_widget(sizegroup, spin);
int digits = gtk_spin_button_get_digits(GTK_SPIN_BUTTON(spin));
if (digits == 2)
gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 3);
GtkAdjustment *adjustment = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(spin));
GtkWidget *scale = gtk_hscale_new(adjustment);
gtk_table_attach(GTK_TABLE(table), scale, 2, 3, i, i + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 0, 0);
gtk_scale_set_draw_value(GTK_SCALE(scale), false);
gtk_range_set_value(GTK_RANGE(scale), p->val);
g_signal_connect_data(G_OBJECT(scale),
"value-changed",
G_CALLBACK(value_changed),
(gpointer)p,
NULL,
(GConnectFlags)0);
});
}
}
#endif
gtk_widget_show_all(dialog);
dialog->show_all();
return true;
}

View File

@ -7,7 +7,7 @@
#ifndef __GTK_SHADER_PARAMETERS_H
#define __GTK_SHADER_PARAMETERS_H
#include "gtk_2_3_compat.h"
#include "gtk_compat.h"
bool gtk_shader_parameters_dialog(GtkWindow *parent);
void gtk_shader_parameters_dialog_close();

View File

@ -10,6 +10,8 @@
#include "gtk_s9x.h"
#include "gtk_sound.h"
#include "gtk_sound_driver.h"
#include "snes9x.h"
#include "apu/apu.h"
#ifdef USE_PORTAUDIO
#include "gtk_sound_driver_portaudio.h"
@ -30,10 +32,9 @@ static int playback_rates[8] =
0, 8000, 11025, 16000, 22050, 32000, 44100, 48000
};
S9xSoundDriver *driver;
static S9xSoundDriver *driver;
int
S9xSoundBase2log (int num)
int S9xSoundBase2log(int num)
{
int power;
@ -48,14 +49,12 @@ S9xSoundBase2log (int num)
return power;
}
int
S9xSoundPowerof2 (int num)
int S9xSoundPowerof2(int num)
{
return (1 << num);
}
void
S9xPortSoundInit ()
void S9xPortSoundInit()
{
int pao_driver = 0;
int sdl_driver = 0;
@ -154,8 +153,7 @@ S9xPortSoundInit ()
}
}
void
S9xPortSoundReinit ()
void S9xPortSoundReinit()
{
S9xPortSoundDeinit();
@ -165,30 +163,29 @@ S9xPortSoundReinit ()
S9xPortSoundInit();
}
void
S9xPortSoundDeinit ()
void S9xPortSoundDeinit()
{
S9xSoundStop();
if (driver)
driver->terminate();
delete driver;
}
void
S9xSoundStart ()
void S9xSoundStart()
{
if (driver)
driver->start();
}
void
S9xSoundStop ()
void S9xSoundStop()
{
if (driver)
driver->stop();
}
bool8
S9xOpenSoundDevice ()
bool8 S9xOpenSoundDevice()
{
if (gui_config->mute_sound)
return false;
@ -199,8 +196,7 @@ S9xOpenSoundDevice ()
}
/* This really shouldn't be in the port layer */
void
S9xToggleSoundChannel (int c)
void S9xToggleSoundChannel(int c)
{
static int sound_switch = 255;

View File

@ -6,6 +6,8 @@
#include "gtk_sound_driver_alsa.h"
#include "gtk_s9x.h"
#include "snes9x.h"
#include "apu/apu.h"
#include <fcntl.h>
#include <sys/ioctl.h>

View File

@ -6,6 +6,8 @@
#include "gtk_sound_driver_oss.h"
#include "gtk_s9x.h"
#include "snes9x.h"
#include "apu/apu.h"
#include <fcntl.h>
#include <sys/ioctl.h>

View File

@ -6,6 +6,8 @@
#include "gtk_sound_driver_portaudio.h"
#include "gtk_s9x.h"
#include "apu/apu.h"
#include "snes9x.h"
static void port_audio_samples_available_callback(void *data)
{

View File

@ -6,6 +6,8 @@
#include "gtk_sound_driver_pulse.h"
#include "gtk_s9x.h"
#include "snes9x.h"
#include "apu/apu.h"
#include <fcntl.h>
#include <sys/ioctl.h>

View File

@ -6,6 +6,8 @@
#include "gtk_sound_driver_sdl.h"
#include "gtk_s9x.h"
#include "apu/apu.h"
#include "snes9x.h"
static void sdl_audio_callback(void *userdata, Uint8 *stream, int len)
{

View File

@ -7,11 +7,11 @@
#ifndef __GTK_WAYLAND_EGL_CONTEXT_H
#define __GTK_WAYLAND_EGL_CONTEXT_H
#include <epoxy/egl.h>
#include <epoxy/egl_generated.h>
#include <wayland-egl.h>
#include "gtk_opengl_context.h"
#include "gtk_compat.h"
#include <epoxy/egl.h>
#include <wayland-egl.h>
class WaylandEGLContext : public OpenGLContext
{

View File

@ -285,7 +285,7 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button7">
<object class="GtkButton" id="cheats_close">
<property name="label">gtk-close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
@ -351,7 +351,7 @@
<property name="border_width">5</property>
<property name="spacing">5</property>
<child>
<object class="GtkButton" id="button4">
<object class="GtkButton" id="add_code">
<property name="label">gtk-add</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
@ -369,7 +369,7 @@
</packing>
</child>
<child>
<object class="GtkButton" id="button5">
<object class="GtkButton" id="remove_code">
<property name="label">gtk-remove</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
@ -551,7 +551,7 @@
</object>
</child>
<action-widgets>
<action-widget response="0">button7</action-widget>
<action-widget response="0">cheats_close</action-widget>
</action-widgets>
</object>
<object class="GtkDialog" id="frame_advance_dialog">
@ -2274,7 +2274,7 @@
</packing>
</child>
<child>
<object class="GtkButton" id="button11">
<object class="GtkButton" id="clear_netplay">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@ -2701,7 +2701,7 @@
</packing>
</child>
<child>
<object class="GtkButton" id="button8">
<object class="GtkButton" id="about_button">
<property name="label">gtk-about</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
@ -5446,7 +5446,7 @@
</packing>
</child>
<child>
<object class="GtkButton" id="button6">
<object class="GtkButton" id="reset_current_joypad">
<property name="label" translatable="yes">_Reset</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
@ -5502,7 +5502,7 @@
</packing>
</child>
<child>
<object class="GtkButton" id="button12">
<object class="GtkButton" id="swap_with">
<property name="label" translatable="yes">_Swap</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
@ -9320,7 +9320,7 @@
<action-widget response="-6">cancel_button</action-widget>
<action-widget response="-10">ok_button</action-widget>
<action-widget response="-5">button1</action-widget>
<action-widget response="0">button8</action-widget>
<action-widget response="0">about_button</action-widget>
</action-widgets>
</object>
<object class="GtkTextBuffer" id="textbuffer1">

View File

@ -7,9 +7,7 @@
#include <stdio.h>
#include <sys/stat.h>
int
main (int argc,
char *argv[])
int main(int argc, char *argv[])
{
FILE *infile, *outfile;
unsigned char inchar;
@ -34,10 +32,7 @@ main (int argc,
outfile = fopen(argv[2], "w+");
fprintf (outfile,
"int %s_size = %d;\n\n",
argv[3],
(int) file_info.st_size);
fprintf(outfile, "int %s_size = %d;\n\n", argv[3], (int)file_info.st_size);
fprintf(outfile, "unsigned char %s [] = \n{\n ", argv[3]);
counter = 0;

View File

@ -345,6 +345,14 @@ void GLSLShader::read_shader_file_with_includes(std::string filename,
sscanf(line.c_str(), "#pragma parameter %s \"%[^\"]\" %f %f %f %f",
par.id, par.name, &par.val, &par.min, &par.max, &par.step);
unsigned int last_decimal = line.rfind(".") + 1;
unsigned int index = last_decimal;
while (isdigit(line[index]) && index < line.length())
index++;
par.digits = index - last_decimal;
if (line[index - 1] == '0' && line[index - 2] == '.')
par.digits = 0;
if (par.step == 0.0f)
par.step = 1.0f;

View File

@ -151,6 +151,7 @@ typedef struct
float max;
float val;
float step;
int digits;
GLint unif[glsl_max_passes];
} GLSLParam;