mirror of https://github.com/snes9xgit/snes9x.git
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:
parent
3c3ea985ef
commit
e17ff69533
|
@ -23,12 +23,9 @@ args += [ '-DDATADIR="' + appdatadir + '"', '-DSNES9XLOCALEDIR="' + localedir +
|
||||||
subdir('data')
|
subdir('data')
|
||||||
subdir('po')
|
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')
|
sdl2_dep = dependency('sdl2')
|
||||||
|
|
||||||
deps += [ glib_dep, gthread_dep, gobject_dep, sdl2_dep ]
|
deps += sdl2_dep
|
||||||
|
|
||||||
c_compiler = meson.get_compiler('c')
|
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'
|
args += '-Wno-format-truncation'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if get_option('gtk3') and not get_option('gtk2')
|
gtk_dep = dependency('gtkmm-3.0', version: '>= 3.22')
|
||||||
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
|
|
||||||
|
|
||||||
deps += gtk_dep
|
deps += gtk_dep
|
||||||
|
|
||||||
x11_dep = c_compiler.find_library('X11')
|
x11_dep = c_compiler.find_library('X11')
|
||||||
|
@ -125,7 +113,7 @@ if slang and opengl
|
||||||
endif
|
endif
|
||||||
|
|
||||||
wayland = get_option('wayland')
|
wayland = get_option('wayland')
|
||||||
if wayland and gtk_ver == 3
|
if wayland
|
||||||
wayland_dep = dependency('wayland-egl', required: false)
|
wayland_dep = dependency('wayland-egl', required: false)
|
||||||
|
|
||||||
if wayland_dep.found()
|
if wayland_dep.found()
|
||||||
|
@ -320,7 +308,7 @@ srcs += [
|
||||||
'../filter/snes_ntsc.h',
|
'../filter/snes_ntsc.h',
|
||||||
'../filter/snes_ntsc_impl.h',
|
'../filter/snes_ntsc_impl.h',
|
||||||
'../filter/snes_ntsc.c',
|
'../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.h',
|
||||||
'src/gtk_sound_driver_sdl.cpp',
|
'src/gtk_sound_driver_sdl.cpp',
|
||||||
'../fxinst.cpp',
|
'../fxinst.cpp',
|
||||||
|
@ -405,7 +393,7 @@ libjma_srcs = [
|
||||||
libjma = static_library('jma',
|
libjma = static_library('jma',
|
||||||
libjma_srcs,
|
libjma_srcs,
|
||||||
c_args: args,
|
c_args: args,
|
||||||
cpp_args: [args, '-fexceptions'],
|
cpp_args: args,
|
||||||
include_directories: include_directories(includes))
|
include_directories: include_directories(includes))
|
||||||
|
|
||||||
sourcify = executable('sourcify', 'src/sourcify.c', native: true)
|
sourcify = executable('sourcify', 'src/sourcify.c', native: true)
|
||||||
|
@ -418,7 +406,7 @@ snes9x_gtk = executable('snes9x-gtk',
|
||||||
srcs,
|
srcs,
|
||||||
gtk_snes9x_ui_cpp,
|
gtk_snes9x_ui_cpp,
|
||||||
c_args: args,
|
c_args: args,
|
||||||
cpp_args: [args, '-fno-exceptions', '-fno-rtti'],
|
cpp_args: args,
|
||||||
dependencies: deps,
|
dependencies: deps,
|
||||||
include_directories: include_directories(includes),
|
include_directories: include_directories(includes),
|
||||||
link_with: libjma,
|
link_with: libjma,
|
||||||
|
@ -431,7 +419,6 @@ summary = [
|
||||||
' appdatadir: ' + appdatadir,
|
' appdatadir: ' + appdatadir,
|
||||||
' localedir: ' + localedir,
|
' localedir: ' + localedir,
|
||||||
'[Options] Build type: ' + get_option('buildtype'),
|
'[Options] Build type: ' + get_option('buildtype'),
|
||||||
' GTK+ version: ' + gtk_ver.to_string(),
|
|
||||||
' Wayland: ' + wayland.to_string(),
|
' Wayland: ' + wayland.to_string(),
|
||||||
' OpenGL: ' + opengl.to_string(),
|
' OpenGL: ' + opengl.to_string(),
|
||||||
' slang shaders: ' + slang.to_string(),
|
' slang shaders: ' + slang.to_string(),
|
||||||
|
|
|
@ -11,8 +11,6 @@ option('xbrz', type: 'boolean', value: true, description: 'Enable th
|
||||||
option('zlib', type: 'boolean', value: true, description: 'Enable gzip compression')
|
option('zlib', type: 'boolean', value: true, description: 'Enable gzip compression')
|
||||||
option('system-zip', type: 'boolean', value: true, description: 'Build using system minizip library')
|
option('system-zip', type: 'boolean', value: true, description: 'Build using system minizip library')
|
||||||
option('screenshot', type: 'boolean', value: true, description: 'Enable screenshots')
|
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('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('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)')
|
option('appdatadir', type: 'string' , value: '', description: 'Snes9x-only data directory (default: datadir/snes9x)')
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#pragma once
|
#ifndef __BACKGROUND_PARTICLES_H
|
||||||
|
#define __BACKGROUND_PARTICLES_H
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -50,3 +51,4 @@ class Particles
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Background
|
} // namespace Background
|
||||||
|
#endif // __BACKGROUND_PARTICLES_H
|
|
@ -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
|
|
|
@ -10,22 +10,22 @@
|
||||||
#include "gtk_s9x.h"
|
#include "gtk_s9x.h"
|
||||||
#include "gtk_binding.h"
|
#include "gtk_binding.h"
|
||||||
|
|
||||||
Binding::Binding ()
|
Binding::Binding()
|
||||||
{
|
{
|
||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding::Binding (GdkEventKey *event)
|
Binding::Binding(GdkEventKey *event)
|
||||||
{
|
{
|
||||||
event->keyval = gdk_keyval_to_lower (event->keyval);
|
event->keyval = gdk_keyval_to_lower(event->keyval);
|
||||||
value = BINDING_KEY | (event->keyval & BINDING_KEY_MASK);
|
value = BINDING_KEY | (event->keyval & BINDING_KEY_MASK);
|
||||||
|
|
||||||
/* Strip modifiers from modifiers */
|
/* Strip modifiers from modifiers */
|
||||||
if (event->keyval == GDK_Control_L ||
|
if (event->keyval == GDK_Control_L ||
|
||||||
event->keyval == GDK_Control_R ||
|
event->keyval == GDK_Control_R ||
|
||||||
event->keyval == GDK_Shift_L ||
|
event->keyval == GDK_Shift_L ||
|
||||||
event->keyval == GDK_Shift_R ||
|
event->keyval == GDK_Shift_R ||
|
||||||
event->keyval == GDK_Alt_L ||
|
event->keyval == GDK_Alt_L ||
|
||||||
event->keyval == GDK_Alt_R)
|
event->keyval == GDK_Alt_R)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -41,7 +41,7 @@ Binding::Binding (GdkEventKey *event)
|
||||||
value |= BINDING_ALT;
|
value |= BINDING_ALT;
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding::Binding (unsigned int key, bool ctrl, bool shift, bool alt)
|
Binding::Binding(unsigned int key, bool ctrl, bool shift, bool alt)
|
||||||
{
|
{
|
||||||
value = BINDING_KEY;
|
value = BINDING_KEY;
|
||||||
|
|
||||||
|
@ -54,23 +54,21 @@ Binding::Binding (unsigned int key, bool ctrl, bool shift, bool alt)
|
||||||
value |= BINDING_ALT;
|
value |= BINDING_ALT;
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding::Binding (unsigned int device,
|
Binding::Binding(unsigned int device, unsigned int button, unsigned int threshold)
|
||||||
unsigned int button,
|
|
||||||
unsigned int threshold)
|
|
||||||
{
|
{
|
||||||
value = BINDING_JOY;
|
value = BINDING_JOY;
|
||||||
value |= JOY_DEVICE_MASK (device + 1);
|
value |= JOY_DEVICE_MASK(device + 1);
|
||||||
value |= BINDING_KEY_MASK & button;
|
value |= BINDING_KEY_MASK & button;
|
||||||
if (button >= 512)
|
if (button >= 512)
|
||||||
value |= THRESHOLD_MASK (threshold);
|
value |= THRESHOLD_MASK(threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding::Binding (unsigned int val)
|
Binding::Binding(unsigned int val)
|
||||||
{
|
{
|
||||||
value = val;
|
value = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding::Binding (const Binding& binding)
|
Binding::Binding(const Binding &binding)
|
||||||
{
|
{
|
||||||
this->value = binding.value;
|
this->value = binding.value;
|
||||||
}
|
}
|
||||||
|
@ -83,88 +81,75 @@ Binding &Binding::operator=(const Binding &binding)
|
||||||
|
|
||||||
bool Binding::operator==(const Binding &binding)
|
bool Binding::operator==(const Binding &binding)
|
||||||
{
|
{
|
||||||
if ((value & ~BINDING_THRESHOLD_MASK) ==
|
if ((value & ~BINDING_THRESHOLD_MASK) == (binding.value & ~BINDING_THRESHOLD_MASK))
|
||||||
(binding.value & ~BINDING_THRESHOLD_MASK))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Binding::clear()
|
||||||
Binding::clear ()
|
|
||||||
{
|
{
|
||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int Binding::hex()
|
||||||
Binding::hex ()
|
|
||||||
{
|
{
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int Binding::base_hex()
|
||||||
Binding::base_hex ()
|
|
||||||
{
|
{
|
||||||
return (value & ~BINDING_THRESHOLD_MASK);
|
return (value & ~BINDING_THRESHOLD_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool Binding::is_joy()
|
||||||
Binding::is_joy ()
|
|
||||||
{
|
{
|
||||||
return (value & BINDING_JOY);
|
return (value & BINDING_JOY);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool Binding::is_key()
|
||||||
Binding::is_key ()
|
|
||||||
{
|
{
|
||||||
return (value & BINDING_KEY);
|
return (value & BINDING_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int Binding::get_key()
|
||||||
Binding::get_key ()
|
|
||||||
{
|
{
|
||||||
return (value & BINDING_KEY_MASK);
|
return (value & BINDING_KEY_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int Binding::get_device()
|
||||||
Binding::get_device ()
|
|
||||||
{
|
{
|
||||||
return JOY_DEVICE_UNMASK (value);
|
return JOY_DEVICE_UNMASK(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int Binding::get_threshold()
|
||||||
Binding::get_threshold ()
|
|
||||||
{
|
{
|
||||||
return THRESHOLD_UNMASK (value);
|
return THRESHOLD_UNMASK(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int Binding::get_axis()
|
||||||
Binding::get_axis ()
|
|
||||||
{
|
{
|
||||||
return JOY_AXIS_UNMASK (value);
|
return JOY_AXIS_UNMASK(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
GdkModifierType
|
Gdk::ModifierType Binding::get_gdk_modifiers()
|
||||||
Binding::get_gdk_modifiers ()
|
|
||||||
{
|
{
|
||||||
return (GdkModifierType) (((BINDING_CTRL & value) ? GDK_CONTROL_MASK : 0) |
|
return (Gdk::ModifierType)(((BINDING_CTRL & value) ? Gdk::CONTROL_MASK : 0) |
|
||||||
((BINDING_ALT & value) ? GDK_MOD1_MASK : 0) |
|
((BINDING_ALT & value) ? Gdk::MOD1_MASK : 0) |
|
||||||
((BINDING_SHIFT & value) ? GDK_SHIFT_MASK : 0));
|
((BINDING_SHIFT & value) ? Gdk::SHIFT_MASK : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool Binding::is_positive()
|
||||||
Binding::is_positive ()
|
|
||||||
{
|
{
|
||||||
return JOY_DIRECTION_UNMASK (value) == AXIS_POS;
|
return JOY_DIRECTION_UNMASK(value) == AXIS_POS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool Binding::is_negative()
|
||||||
Binding::is_negative ()
|
|
||||||
{
|
{
|
||||||
return JOY_DIRECTION_UNMASK (value) == AXIS_NEG;
|
return JOY_DIRECTION_UNMASK(value) == AXIS_NEG;
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding::Binding (const char *raw_string)
|
Binding::Binding(const char *raw_string)
|
||||||
{
|
{
|
||||||
value = 0;
|
value = 0;
|
||||||
|
|
||||||
|
@ -172,33 +157,33 @@ Binding::Binding (const char *raw_string)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char substr[80];
|
char substr[80];
|
||||||
if (sscanf (raw_string, "Keyboard %79s", substr) == 1)
|
if (sscanf(raw_string, "Keyboard %79s", substr) == 1)
|
||||||
{
|
{
|
||||||
bool ctrl = false;
|
bool ctrl = false;
|
||||||
bool shift = false;
|
bool shift = false;
|
||||||
bool alt= false;
|
bool alt = false;
|
||||||
bool direct = false;
|
bool direct = false;
|
||||||
unsigned int keyval = 0;
|
unsigned int keyval = 0;
|
||||||
char *key;
|
char *key;
|
||||||
|
|
||||||
if (!strchr (substr, '+'))
|
if (!strchr(substr, '+'))
|
||||||
direct = true;
|
direct = true;
|
||||||
|
|
||||||
key = strtok (substr, "+");
|
key = strtok(substr, "+");
|
||||||
while (key)
|
while (key)
|
||||||
{
|
{
|
||||||
if (strstr (key, "Alt") && !direct)
|
if (strstr(key, "Alt") && !direct)
|
||||||
alt = true;
|
alt = true;
|
||||||
else if (strstr (key, "Ctrl") && !direct)
|
else if (strstr(key, "Ctrl") && !direct)
|
||||||
ctrl = true;
|
ctrl = true;
|
||||||
else if (strstr (key, "Shift") && !direct)
|
else if (strstr(key, "Shift") && !direct)
|
||||||
shift = true;
|
shift = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
keyval = gdk_keyval_from_name (key);
|
keyval = gdk_keyval_from_name(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
key = strtok (NULL, "+");
|
key = strtok(NULL, "+");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyval != GDK_KEY_VoidSymbol)
|
if (keyval != GDK_KEY_VoidSymbol)
|
||||||
|
@ -206,7 +191,7 @@ Binding::Binding (const char *raw_string)
|
||||||
else
|
else
|
||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
else if (!strncmp (raw_string, "Joystick", 8))
|
else if (!strncmp(raw_string, "Joystick", 8))
|
||||||
{
|
{
|
||||||
unsigned int axis;
|
unsigned int axis;
|
||||||
unsigned int button;
|
unsigned int button;
|
||||||
|
@ -215,15 +200,14 @@ Binding::Binding (const char *raw_string)
|
||||||
char posneg;
|
char posneg;
|
||||||
const char *substr = &raw_string[8];
|
const char *substr = &raw_string[8];
|
||||||
|
|
||||||
if (sscanf (substr, "%u Axis %u %c %u", &device, &axis, &posneg, &percent) == 4)
|
if (sscanf(substr, "%u Axis %u %c %u", &device, &axis, &posneg, &percent) == 4)
|
||||||
{
|
{
|
||||||
value = Binding(device - 1, JOY_AXIS (axis, posneg == '+' ? AXIS_POS : AXIS_NEG), percent).value;
|
value = Binding(device - 1, JOY_AXIS(axis, posneg == '+' ? AXIS_POS : AXIS_NEG), percent).value;
|
||||||
}
|
}
|
||||||
else if (sscanf (substr, "%u Button %u", &device, &button) == 2)
|
else if (sscanf(substr, "%u Button %u", &device, &button) == 2)
|
||||||
{
|
{
|
||||||
value = Binding(device - 1, button, 0).value;
|
value = Binding(device - 1, button, 0).value;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,8 +218,7 @@ std::string Binding::as_string()
|
||||||
return std::string(buf);
|
return std::string(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Binding::to_string(char *str, bool translate)
|
||||||
Binding::to_string (char *str, bool translate)
|
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
|
||||||
|
@ -244,22 +227,22 @@ Binding::to_string (char *str, bool translate)
|
||||||
|
|
||||||
str[0] = '\0';
|
str[0] = '\0';
|
||||||
|
|
||||||
if (is_key ())
|
if (is_key())
|
||||||
{
|
{
|
||||||
char *keyval_name = NULL;
|
char *keyval_name = NULL;
|
||||||
unsigned int keyval = gdk_keyval_to_lower (get_key ());
|
unsigned int keyval = gdk_keyval_to_lower(get_key());
|
||||||
keyval_name = gdk_keyval_name (keyval);
|
keyval_name = gdk_keyval_name(keyval);
|
||||||
|
|
||||||
if (keyval_name == NULL)
|
if (keyval_name == NULL)
|
||||||
{
|
{
|
||||||
sprintf (buf, _("Unknown"));
|
sprintf(buf, _("Unknown"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memset (buf, 0, 256);
|
memset(buf, 0, 256);
|
||||||
strncpy (buf,
|
strncpy(buf,
|
||||||
keyval_name,
|
keyval_name,
|
||||||
255);
|
255);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (translate)
|
if (translate)
|
||||||
|
@ -267,29 +250,29 @@ Binding::to_string (char *str, bool translate)
|
||||||
if (buf[i] == '_')
|
if (buf[i] == '_')
|
||||||
buf[i] = ' ';
|
buf[i] = ' ';
|
||||||
|
|
||||||
sprintf (str, _("Keyboard %s%s%s%s"),
|
sprintf(str, _("Keyboard %s%s%s%s"),
|
||||||
(value & BINDING_SHIFT) ? "Shift+" : "",
|
(value & BINDING_SHIFT) ? "Shift+" : "",
|
||||||
(value & BINDING_CTRL) ? "Ctrl+" : "",
|
(value & BINDING_CTRL) ? "Ctrl+" : "",
|
||||||
(value & BINDING_ALT) ? "Alt+" : "",
|
(value & BINDING_ALT) ? "Alt+" : "",
|
||||||
buf);
|
buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (is_joy ())
|
else if (is_joy())
|
||||||
{
|
{
|
||||||
if ((get_key ()) >= 512)
|
if ((get_key()) >= 512)
|
||||||
sprintf (buf,
|
sprintf(buf,
|
||||||
_("Axis %u %s %u%%"),
|
_("Axis %u %s %u%%"),
|
||||||
get_axis (),
|
get_axis(),
|
||||||
is_positive () ? "+" : "-",
|
is_positive() ? "+" : "-",
|
||||||
get_threshold ());
|
get_threshold());
|
||||||
else
|
else
|
||||||
sprintf (buf, _("Button %u"), get_key ());
|
sprintf(buf, _("Button %u"), get_key());
|
||||||
|
|
||||||
sprintf (str, _("Joystick %u %s"), get_device (), buf);
|
sprintf(str, _("Joystick %u %s"), get_device(), buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf (str, _("Unset"));
|
sprintf(str, _("Unset"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#ifndef __GTK_BINDING_H
|
#ifndef __GTK_BINDING_H
|
||||||
#define __GTK_BINDING_H
|
#define __GTK_BINDING_H
|
||||||
|
|
||||||
#include "gtk_2_3_compat.h"
|
#include "gtk_compat.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define AXIS_POS 1
|
#define AXIS_POS 1
|
||||||
|
@ -34,34 +34,34 @@
|
||||||
|
|
||||||
class Binding
|
class Binding
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Binding (unsigned int key, bool ctrl, bool shift, bool alt);
|
Binding(unsigned int key, bool ctrl, bool shift, bool alt);
|
||||||
Binding (unsigned int device, unsigned int button, unsigned int threshold);
|
Binding(unsigned int device, unsigned int button, unsigned int threshold);
|
||||||
Binding (const Binding &binding);
|
Binding(const Binding &binding);
|
||||||
Binding &operator=(const Binding &binding);
|
Binding &operator=(const Binding &binding);
|
||||||
bool operator==(const Binding &binding);
|
bool operator==(const Binding &binding);
|
||||||
Binding (GdkEventKey *event);
|
Binding(GdkEventKey *event);
|
||||||
Binding (unsigned int);
|
Binding(unsigned int);
|
||||||
Binding ();
|
Binding();
|
||||||
Binding (const char *str);
|
Binding(const char *str);
|
||||||
void to_string (char *str, bool translate = true);
|
void to_string(char *str, bool translate = true);
|
||||||
std::string as_string();
|
std::string as_string();
|
||||||
unsigned int hex ();
|
unsigned int hex();
|
||||||
unsigned int base_hex ();
|
unsigned int base_hex();
|
||||||
void clear ();
|
void clear();
|
||||||
bool is_joy ();
|
bool is_joy();
|
||||||
bool is_key ();
|
bool is_key();
|
||||||
bool is_mouse ();
|
bool is_mouse();
|
||||||
bool is_positive ();
|
bool is_positive();
|
||||||
bool is_negative ();
|
bool is_negative();
|
||||||
unsigned int get_key ();
|
unsigned int get_key();
|
||||||
unsigned int get_device ();
|
unsigned int get_device();
|
||||||
unsigned int get_threshold ();
|
unsigned int get_threshold();
|
||||||
unsigned int get_axis ();
|
unsigned int get_axis();
|
||||||
GdkModifierType get_gdk_modifiers ();
|
Gdk::ModifierType get_gdk_modifiers();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int value;
|
unsigned int value;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __GTK_BINDING_H_ */
|
#endif /* __GTK_BINDING_H_ */
|
||||||
|
|
|
@ -9,242 +9,147 @@
|
||||||
#include "gtk_builder_window.h"
|
#include "gtk_builder_window.h"
|
||||||
|
|
||||||
extern const unsigned char snes9x_ui[];
|
extern const unsigned char snes9x_ui[];
|
||||||
extern const int snes9x_ui_size;
|
extern const int snes9x_ui_size;
|
||||||
|
|
||||||
GtkBuilderWindow::GtkBuilderWindow (const char *root)
|
Glib::RefPtr<Gtk::Builder> global_builder;
|
||||||
|
bool global_builder_created = false;
|
||||||
|
|
||||||
|
GtkBuilderWindow::GtkBuilderWindow(const char *root)
|
||||||
{
|
{
|
||||||
builder = gtk_builder_new ();
|
if (!global_builder_created)
|
||||||
gtk_builder_add_from_string (builder,
|
|
||||||
(const gchar *) snes9x_ui,
|
|
||||||
snes9x_ui_size,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
window = get_widget (root);
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkBuilderWindow::~GtkBuilderWindow ()
|
|
||||||
{
|
|
||||||
gtk_widget_destroy (window);
|
|
||||||
g_object_unref (builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkWidget *
|
|
||||||
GtkBuilderWindow::get_widget (const char *name)
|
|
||||||
{
|
|
||||||
return GTK_WIDGET (gtk_builder_get_object (builder, name));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
GtkBuilderWindow::signal_connection_func (GtkBuilder *builder,
|
|
||||||
GObject *object,
|
|
||||||
const gchar *signal_name,
|
|
||||||
const char *handler_name,
|
|
||||||
GObject *connect_object,
|
|
||||||
GConnectFlags flags,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
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))
|
global_builder = Gtk::Builder::create();
|
||||||
{
|
global_builder->add_from_string((const gchar *)snes9x_ui, snes9x_ui_size);
|
||||||
function = callbacks[i].function;
|
global_builder_created = true;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (function)
|
window = get_object<Gtk::Window>(root);
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
GtkBuilderWindow::~GtkBuilderWindow()
|
||||||
GtkBuilderWindow::signal_connect (GtkBuilderWindowCallbacks *callbacks)
|
|
||||||
{
|
{
|
||||||
if (!callbacks)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this->callbacks = callbacks;
|
|
||||||
|
|
||||||
gtk_builder_connect_signals_full (builder,
|
|
||||||
signal_connection_func,
|
|
||||||
(gpointer) this);
|
|
||||||
|
|
||||||
this->callbacks = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GtkBuilderWindow::enable_widget(const char *name, bool state)
|
||||||
GtkBuilderWindow::enable_widget (const char *name, bool state)
|
|
||||||
{
|
{
|
||||||
gtk_widget_set_sensitive (get_widget (name), state);
|
auto widget = get_object<Gtk::Widget>(name);
|
||||||
|
widget->set_sensitive(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GtkBuilderWindow::show_widget(const char *name, bool state)
|
||||||
GtkBuilderWindow::resize (int width, int height)
|
|
||||||
{
|
{
|
||||||
if (width > 0 && height > 0)
|
auto widget = get_object<Gtk::Widget>(name);
|
||||||
gtk_window_resize (GTK_WINDOW (window), width, height);
|
widget->set_visible(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GtkBuilderWindow::resize(int width, int height)
|
||||||
GtkBuilderWindow::refresh ()
|
|
||||||
{
|
{
|
||||||
gtk_widget_queue_draw (GTK_WIDGET (window));
|
window->resize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void GtkBuilderWindow::refresh()
|
||||||
GtkBuilderWindow::get_width ()
|
|
||||||
{
|
{
|
||||||
int width, height;
|
window->queue_draw();
|
||||||
|
|
||||||
gtk_window_get_size (GTK_WINDOW (window), &width, &height);
|
|
||||||
|
|
||||||
return width;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int GtkBuilderWindow::get_width()
|
||||||
GtkBuilderWindow::get_height ()
|
|
||||||
{
|
{
|
||||||
int width, height;
|
return window->get_width();
|
||||||
|
|
||||||
gtk_window_get_size (GTK_WINDOW (window), &width, &height);
|
|
||||||
|
|
||||||
return height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int GtkBuilderWindow::get_height()
|
||||||
GtkBuilderWindow::set_button_label (const char *name, const char *label)
|
|
||||||
{
|
{
|
||||||
gtk_button_set_label (GTK_BUTTON (get_widget (name)), label);
|
return window->get_height();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char
|
void GtkBuilderWindow::set_button_label(const char *name, const char *label)
|
||||||
GtkBuilderWindow::get_check (const char *name)
|
|
||||||
{
|
{
|
||||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (get_widget (name))))
|
get_object<Gtk::Button>(name)->set_label(label);
|
||||||
return 1;
|
}
|
||||||
return 0;
|
|
||||||
|
bool GtkBuilderWindow::get_check(const char *name)
|
||||||
|
{
|
||||||
|
return get_object<Gtk::ToggleButton>(name)->get_active();
|
||||||
}
|
}
|
||||||
|
|
||||||
int GtkBuilderWindow::get_entry_value(const char *name)
|
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 *
|
std::string GtkBuilderWindow::get_entry_text(const char *name)
|
||||||
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
|
void GtkBuilderWindow::set_entry_value(const char *name, unsigned int value)
|
||||||
GtkBuilderWindow::get_slider (const char *name)
|
|
||||||
{
|
{
|
||||||
return (float) gtk_range_get_value (GTK_RANGE (get_widget (name)));
|
get_object<Gtk::Entry>(name)->set_text(std::to_string(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char
|
void GtkBuilderWindow::set_entry_text(const char *name, const char *text)
|
||||||
GtkBuilderWindow::get_combo (const char *name)
|
|
||||||
{
|
{
|
||||||
return gtk_combo_box_get_active (GTK_COMBO_BOX (get_widget (name)));
|
get_object<Gtk::Entry>(name)->set_text(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
float GtkBuilderWindow::get_slider(const char *name)
|
||||||
GtkBuilderWindow::set_slider (const char *name, float value)
|
|
||||||
{
|
{
|
||||||
gtk_range_set_value (GTK_RANGE (get_widget (name)), (double) value);
|
return get_object<Gtk::Range>(name)->get_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int GtkBuilderWindow::get_combo(const char *name)
|
||||||
GtkBuilderWindow::set_check (const char *name, bool value)
|
|
||||||
{
|
{
|
||||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (get_widget (name)),
|
return get_object<Gtk::ComboBox>(name)->get_active_row_number();
|
||||||
value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GtkBuilderWindow::set_slider(const char *name, float value)
|
||||||
GtkBuilderWindow::set_entry_value (const char *name, unsigned int value)
|
|
||||||
{
|
{
|
||||||
char text[80];
|
get_object<Gtk::Range>(name)->set_value(value);
|
||||||
|
|
||||||
snprintf (text, 80, "%u", value);
|
|
||||||
gtk_entry_set_text (GTK_ENTRY (get_widget (name)), text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GtkBuilderWindow::set_check(const char *name, bool value)
|
||||||
GtkBuilderWindow::set_entry_text (const char *name, const char *text)
|
|
||||||
{
|
{
|
||||||
gtk_entry_set_text (GTK_ENTRY (get_widget (name)), text);
|
get_object<Gtk::ToggleButton>(name)->set_active(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GtkBuilderWindow::set_combo(const char *name, unsigned char value)
|
||||||
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
|
void GtkBuilderWindow::set_spin(const char *name, double value)
|
||||||
GtkBuilderWindow::set_spin (const char *name, double value)
|
|
||||||
{
|
{
|
||||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (get_widget (name)),
|
get_object<Gtk::SpinButton>(name)->set_value(value);
|
||||||
(double) value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
double GtkBuilderWindow::get_spin(const char *name)
|
||||||
GtkBuilderWindow::combo_box_append (const char *name, const char *value)
|
|
||||||
{
|
{
|
||||||
combo_box_append (GTK_COMBO_BOX (get_widget (name)), value);
|
return get_object<Gtk::SpinButton>(name)->get_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void GtkBuilderWindow::combo_box_append(const char *name, const char *value)
|
||||||
GtkBuilderWindow::combo_box_append (GtkComboBox *combo, 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;
|
GtkListStore *store;
|
||||||
GtkTreeIter iter;
|
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_append(store, &iter);
|
||||||
gtk_list_store_set (store, &iter, 0, value, -1);
|
gtk_list_store_set(store, &iter, 0, value, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWindow *
|
GtkWindow *GtkBuilderWindow::get_window()
|
||||||
GtkBuilderWindow::get_window ()
|
|
||||||
{
|
{
|
||||||
return GTK_WINDOW (window);
|
return window->gobj();
|
||||||
}
|
|
||||||
|
|
||||||
double
|
|
||||||
GtkBuilderWindow::get_spin (const char *name)
|
|
||||||
{
|
|
||||||
return gtk_spin_button_get_value (GTK_SPIN_BUTTON (get_widget (name)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GtkBuilderWindow::has_focus(const char *widget)
|
bool GtkBuilderWindow::has_focus(const char *widget)
|
||||||
{
|
{
|
||||||
return gtk_widget_is_focus (get_widget (widget));
|
return get_object<Gtk::Widget>(widget)->is_focus();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,51 +7,54 @@
|
||||||
#ifndef __GTK_BUILDER_WINDOW_H
|
#ifndef __GTK_BUILDER_WINDOW_H
|
||||||
#define __GTK_BUILDER_WINDOW_H
|
#define __GTK_BUILDER_WINDOW_H
|
||||||
|
|
||||||
#include "gtk_2_3_compat.h"
|
#include "gtk_compat.h"
|
||||||
|
|
||||||
typedef struct
|
extern Glib::RefPtr<Gtk::Builder> global_builder;
|
||||||
{
|
|
||||||
const char *signal;
|
|
||||||
GCallback function;
|
|
||||||
} GtkBuilderWindowCallbacks;
|
|
||||||
|
|
||||||
class GtkBuilderWindow
|
class GtkBuilderWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GtkBuilderWindow (const char *root);
|
GtkBuilderWindow(const char *root);
|
||||||
~GtkBuilderWindow ();
|
~GtkBuilderWindow();
|
||||||
GtkWidget *get_widget (const char *name);
|
|
||||||
void resize (int width, int height);
|
|
||||||
GtkWindow *get_window ();
|
|
||||||
void refresh ();
|
|
||||||
int get_width ();
|
|
||||||
int get_height ();
|
|
||||||
|
|
||||||
void signal_connect (GtkBuilderWindowCallbacks *callbacks);
|
template <typename T>
|
||||||
void enable_widget (const char *name, bool state);
|
Glib::RefPtr<T> get_object(const char *name)
|
||||||
void set_button_label (const char *name, const char *label);
|
{
|
||||||
unsigned char get_check (const char *name);
|
auto object = global_builder->get_object(name);
|
||||||
int get_entry_value (const char *name);
|
if (!object)
|
||||||
const char *get_entry_text (const char *name);
|
{
|
||||||
unsigned char get_combo (const char *name);
|
printf("No object named %s\n", name);
|
||||||
void combo_box_append (const char *name, const char *value);
|
exit(1);
|
||||||
void combo_box_append (GtkComboBox *combo, const char *value);
|
}
|
||||||
double get_spin (const char *name);
|
return Glib::RefPtr<T>::cast_static(object);
|
||||||
float get_slider (const char *name);
|
}
|
||||||
void set_check (const char *name, bool value);
|
|
||||||
void set_entry_value (const char *name, unsigned int value);
|
|
||||||
void set_entry_text (const char *name, const char *text);
|
|
||||||
void set_combo (const char *name, unsigned char value);
|
|
||||||
void set_spin (const char *name, double value);
|
|
||||||
void set_slider (const char *name, float value);
|
|
||||||
bool has_focus (const char *widget);
|
|
||||||
|
|
||||||
protected:
|
void resize(int width, int height);
|
||||||
static void signal_connection_func (GtkBuilder *, GObject *, const gchar *, const char *, GObject *, GConnectFlags, gpointer);
|
GtkWindow *get_window();
|
||||||
|
void refresh();
|
||||||
|
int get_width();
|
||||||
|
int get_height();
|
||||||
|
|
||||||
GtkWidget *window;
|
void enable_widget(const char *name, bool state);
|
||||||
GtkBuilder *builder;
|
void show_widget(const char *name, bool state);
|
||||||
GtkBuilderWindowCallbacks *callbacks;
|
void set_button_label(const char *name, const char *label);
|
||||||
|
bool get_check(const char *name);
|
||||||
|
int get_entry_value(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(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);
|
||||||
|
void set_entry_value(const char *name, unsigned int value);
|
||||||
|
void set_entry_text(const char *name, const char *text);
|
||||||
|
void set_combo(const char *name, unsigned char value);
|
||||||
|
void set_spin(const char *name, double value);
|
||||||
|
void set_slider(const char *name, float value);
|
||||||
|
bool has_focus(const char *widget);
|
||||||
|
|
||||||
|
Glib::RefPtr<Gtk::Window> window;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __GTK_BUILDER_WINDOW_H */
|
#endif /* __GTK_BUILDER_WINDOW_H */
|
||||||
|
|
|
@ -4,13 +4,12 @@
|
||||||
For further information, consult the LICENSE file in the root directory.
|
For further information, consult the LICENSE file in the root directory.
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
#include "gtk_s9xcore.h"
|
|
||||||
|
|
||||||
#include "gtk_s9x.h"
|
#include "gtk_s9x.h"
|
||||||
#include "gtk_cheat.h"
|
#include "gtk_cheat.h"
|
||||||
|
#include "cheats.h"
|
||||||
|
#include "display.h"
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
COLUMN_ENABLED = 0,
|
COLUMN_ENABLED = 0,
|
||||||
COLUMN_DESCRIPTION = 1,
|
COLUMN_DESCRIPTION = 1,
|
||||||
COLUMN_CHEAT = 2,
|
COLUMN_CHEAT = 2,
|
||||||
|
@ -19,225 +18,128 @@ enum
|
||||||
|
|
||||||
extern SCheatData Cheat;
|
extern SCheatData Cheat;
|
||||||
|
|
||||||
static void
|
static void display_errorbox(const char *error)
|
||||||
display_errorbox (const char *error)
|
|
||||||
{
|
{
|
||||||
GtkWidget *dialog = gtk_message_dialog_new (NULL,
|
auto dialog = Gtk::MessageDialog(error, false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
|
||||||
GTK_DIALOG_MODAL,
|
dialog.set_title(_("Error"));
|
||||||
GTK_MESSAGE_ERROR,
|
dialog.run();
|
||||||
GTK_BUTTONS_OK,
|
dialog.hide();
|
||||||
"%s",
|
|
||||||
error);
|
|
||||||
gtk_window_set_title (GTK_WINDOW (dialog), _("Error"));
|
|
||||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
|
||||||
gtk_widget_destroy (dialog);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static Snes9xCheats *cheats_dialog = nullptr;
|
||||||
event_add_code (GtkButton *button, gpointer data)
|
void open_snes9x_cheats_dialog()
|
||||||
{
|
{
|
||||||
((Snes9xCheats *) data)->add_code ();
|
if (!cheats_dialog)
|
||||||
|
cheats_dialog = new Snes9xCheats;
|
||||||
|
|
||||||
|
cheats_dialog->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
Snes9xCheats::Snes9xCheats()
|
||||||
event_update_code (GtkButton *button, gpointer data)
|
: GtkBuilderWindow("cheat_window")
|
||||||
{
|
{
|
||||||
((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 ();
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
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 ();
|
auto text_renderer = new Gtk::CellRendererText();
|
||||||
gtk_cell_renderer_toggle_set_activatable (GTK_CELL_RENDERER_TOGGLE (renderer), true);
|
view->insert_column(_("Description"), *text_renderer, COLUMN_DESCRIPTION);
|
||||||
gtk_tree_view_insert_column_with_attributes (view,
|
column = view->get_column(COLUMN_DESCRIPTION);
|
||||||
-1,
|
column->set_resizable();
|
||||||
"\xe2\x86\x91",
|
column->set_min_width(40);
|
||||||
renderer,
|
column->add_attribute(*text_renderer, "text", COLUMN_DESCRIPTION);
|
||||||
"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);
|
|
||||||
|
|
||||||
g_signal_connect (renderer,
|
view->insert_column(_("Cheat"), *text_renderer, COLUMN_CHEAT);
|
||||||
"toggled",
|
column = view->get_column(COLUMN_CHEAT);
|
||||||
G_CALLBACK (event_code_toggled),
|
column->set_resizable();
|
||||||
(gpointer) this);
|
column->set_min_width(40);
|
||||||
|
column->add_attribute(*text_renderer, "text", COLUMN_CHEAT);
|
||||||
|
|
||||||
renderer = gtk_cell_renderer_text_new ();
|
Gtk::TreeModelColumn<bool> column1;
|
||||||
gtk_tree_view_insert_column_with_attributes (view,
|
Gtk::TreeModelColumn<Glib::ustring> column2;
|
||||||
-1,
|
Gtk::TreeModelColumn<Glib::ustring> column3;
|
||||||
_("Description"),
|
Gtk::TreeModelColumnRecord record;
|
||||||
renderer,
|
record.add(column1);
|
||||||
"text", COLUMN_DESCRIPTION,
|
record.add(column2);
|
||||||
NULL);
|
record.add(column3);
|
||||||
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);
|
|
||||||
|
|
||||||
renderer = gtk_cell_renderer_text_new ();
|
store = Gtk::ListStore::create(record);
|
||||||
gtk_tree_view_insert_column_with_attributes (view,
|
view->set_model(store);
|
||||||
-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_list_store_new (NUM_COLS,
|
delete_id = store->signal_row_deleted().connect([&](const Gtk::TreeModel::Path &path) {
|
||||||
G_TYPE_BOOLEAN,
|
row_deleted(get_index_from_path(path));
|
||||||
G_TYPE_STRING,
|
});
|
||||||
G_TYPE_STRING);
|
|
||||||
|
|
||||||
gtk_tree_view_set_model (view, GTK_TREE_MODEL (store));
|
insert_id = store->signal_row_inserted().connect([&](const Gtk::TreeModel::Path &path, const Gtk::TreeModel::iterator &iter) {
|
||||||
delete_id = g_signal_connect (store, "row-deleted", G_CALLBACK (event_row_deleted), (gpointer) this);
|
row_inserted(get_index_from_path(path));
|
||||||
insert_id = g_signal_connect (store, "row-inserted", G_CALLBACK (event_row_inserted), (gpointer) this);
|
});
|
||||||
|
|
||||||
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 ()
|
Snes9xCheats::~Snes9xCheats()
|
||||||
{
|
{
|
||||||
gtk_widget_destroy (window);
|
|
||||||
|
|
||||||
g_object_unref (store);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Snes9xCheats::enable_dnd(bool enable)
|
||||||
Snes9xCheats::enable_dnd (bool enable)
|
|
||||||
{
|
{
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
g_signal_handler_unblock (G_OBJECT (store), delete_id);
|
delete_id.unblock();
|
||||||
g_signal_handler_unblock (G_OBJECT (store), insert_id);
|
insert_id.unblock();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_signal_handler_block (G_OBJECT (store), delete_id);
|
delete_id.block();
|
||||||
g_signal_handler_block (G_OBJECT (store), insert_id);
|
insert_id.unblock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Snes9xCheats::show()
|
||||||
Snes9xCheats::show ()
|
|
||||||
{
|
{
|
||||||
top_level->pause_from_focus_change ();
|
top_level->pause_from_focus_change();
|
||||||
|
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (window),
|
window->set_transient_for(*top_level->window.get());
|
||||||
top_level->get_window ());
|
|
||||||
|
|
||||||
refresh_tree_view ();
|
refresh_tree_view();
|
||||||
|
Glib::RefPtr<Gtk::Dialog>::cast_static(window)->run();
|
||||||
|
window->hide();
|
||||||
|
|
||||||
gtk_dialog_run (GTK_DIALOG (window));
|
top_level->unpause_from_focus_change();
|
||||||
|
|
||||||
top_level->unpause_from_focus_change ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cheat_move (int src, int dst)
|
static void cheat_move(int src, int dst)
|
||||||
{
|
{
|
||||||
Cheat.g.insert (Cheat.g.begin() + dst, Cheat.g[src]);
|
Cheat.g.insert(Cheat.g.begin() + dst, Cheat.g[src]);
|
||||||
|
|
||||||
if (dst < src)
|
if (dst < src)
|
||||||
src++;
|
src++;
|
||||||
Cheat.g.erase (Cheat.g.begin() + src);
|
Cheat.g.erase(Cheat.g.begin() + src);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cheat_gather_enabled ()
|
static void cheat_gather_enabled()
|
||||||
{
|
{
|
||||||
unsigned int enabled = 0;
|
unsigned int enabled = 0;
|
||||||
|
|
||||||
|
@ -251,311 +153,259 @@ static void cheat_gather_enabled ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Snes9xCheats::row_deleted(int src_row)
|
||||||
Snes9xCheats::row_deleted (int src_row)
|
|
||||||
{
|
{
|
||||||
if (dst_row >= 0)
|
if (dst_row >= 0)
|
||||||
{
|
{
|
||||||
if (src_row >= dst_row)
|
if (src_row >= dst_row)
|
||||||
src_row--;
|
src_row--;
|
||||||
cheat_move (src_row, dst_row);
|
cheat_move(src_row, dst_row);
|
||||||
|
|
||||||
dst_row = -1;
|
dst_row = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Snes9xCheats::row_inserted(int new_row)
|
||||||
Snes9xCheats::row_inserted (int new_row)
|
|
||||||
{
|
{
|
||||||
dst_row = new_row;
|
dst_row = new_row;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int Snes9xCheats::get_selected_index()
|
||||||
Snes9xCheats::get_selected_index ()
|
|
||||||
{
|
{
|
||||||
GtkTreeSelection *selection;
|
auto selection = get_object<Gtk::TreeView>("cheat_treeview")->get_selection();
|
||||||
GList *rows;
|
auto rows = selection->get_selected_rows();
|
||||||
gint *indices;
|
if (rows.empty())
|
||||||
int index;
|
return -1;
|
||||||
GtkTreeModel *model = GTK_TREE_MODEL (store);
|
auto indices = gtk_tree_path_get_indices(rows[0].gobj());
|
||||||
|
return indices[0];
|
||||||
|
}
|
||||||
|
|
||||||
selection =
|
int Snes9xCheats::get_index_from_path(Gtk::TreeModel::Path path)
|
||||||
gtk_tree_view_get_selection (
|
{
|
||||||
GTK_TREE_VIEW (get_widget ("cheat_treeview")));
|
gint *indices = gtk_tree_path_get_indices(path.gobj());
|
||||||
|
int index = indices[0];
|
||||||
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;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int Snes9xCheats::get_index_from_path(const Glib::ustring &path)
|
||||||
Snes9xCheats::get_index_from_path (const gchar *path)
|
|
||||||
{
|
{
|
||||||
GtkTreePath *tree_path = gtk_tree_path_new_from_string (path);
|
return get_index_from_path(Gtk::TreeModel::Path(path));
|
||||||
gint *indices = gtk_tree_path_get_indices (tree_path);
|
|
||||||
int index = indices[0];
|
|
||||||
gtk_tree_path_free (tree_path);
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Snes9xCheats::refresh_tree_view()
|
||||||
Snes9xCheats::refresh_tree_view ()
|
|
||||||
{
|
{
|
||||||
GtkTreeIter iter;
|
enable_dnd(false);
|
||||||
unsigned int list_size;
|
|
||||||
|
|
||||||
enable_dnd (false);
|
auto list_size = store->children().size();
|
||||||
list_size = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL);
|
|
||||||
|
|
||||||
if (Cheat.g.size () == 0)
|
if (Cheat.g.size() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < Cheat.g.size() - list_size; i++)
|
for (unsigned int i = 0; i < Cheat.g.size() - list_size; i++)
|
||||||
gtk_list_store_append (store, &iter);
|
store->append();
|
||||||
|
|
||||||
gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
|
|
||||||
|
|
||||||
|
auto iter = store->children().begin();
|
||||||
for (unsigned int i = 0; i < Cheat.g.size (); i++)
|
for (unsigned int i = 0; i < Cheat.g.size (); i++)
|
||||||
{
|
{
|
||||||
char *str = S9xCheatGroupToText (i);
|
char *str = S9xCheatGroupToText(i);
|
||||||
|
Glib::ustring description = Cheat.g[i].name[0] == '\0' ? "" :Cheat.g[i].name;
|
||||||
if (i > 0)
|
iter->set_value(COLUMN_ENABLED, Cheat.g[i].enabled);
|
||||||
gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
|
iter->set_value(COLUMN_DESCRIPTION, description);
|
||||||
|
iter->set_value(COLUMN_CHEAT, Glib::ustring(str));
|
||||||
gtk_list_store_set (store, &iter,
|
iter++;
|
||||||
COLUMN_DESCRIPTION,
|
|
||||||
!strcmp (Cheat.g [i].name, "") ? _("No description")
|
|
||||||
: Cheat.g [i].name,
|
|
||||||
COLUMN_CHEAT, str,
|
|
||||||
COLUMN_ENABLED, Cheat.g [i].enabled,
|
|
||||||
-1);
|
|
||||||
delete[] str;
|
delete[] str;
|
||||||
}
|
}
|
||||||
|
|
||||||
enable_dnd (true);
|
enable_dnd(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Snes9xCheats::add_code()
|
||||||
Snes9xCheats::add_code ()
|
|
||||||
{
|
{
|
||||||
const char *description;
|
std::string code = get_entry_text("code_entry");
|
||||||
const gchar *code = get_entry_text ("code_entry");
|
std::string description = get_entry_text("description_entry");
|
||||||
|
|
||||||
description = get_entry_text ("description_entry");
|
if (description.empty())
|
||||||
if (description[0] == '\0')
|
|
||||||
description = _("No description");
|
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."));
|
display_errorbox(_("Couldn't find any cheat codes in input."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
code = (const gchar *) S9xCheatGroupToText (Cheat.g.size () - 1);
|
auto parsed_code = S9xCheatGroupToText(Cheat.g.size() - 1);
|
||||||
set_entry_text ("code_entry", code);
|
set_entry_text("code_entry", parsed_code);
|
||||||
delete[] code;
|
delete[] parsed_code;
|
||||||
|
|
||||||
gtk_widget_grab_focus (get_widget ("code_entry"));
|
get_object<Gtk::Entry>("code_entry")->grab_focus();
|
||||||
|
|
||||||
refresh_tree_view ();
|
refresh_tree_view();
|
||||||
|
|
||||||
while (gtk_events_pending ())
|
while (Gtk::Main::events_pending())
|
||||||
gtk_main_iteration ();
|
Gtk::Main::iteration(false);
|
||||||
|
|
||||||
GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (get_widget ("cheat_treeview")));
|
auto selection = get_object<Gtk::TreeView>("cheat_treeview")->get_selection();
|
||||||
GtkTreePath *path = gtk_tree_path_new_from_indices (Cheat.g.size () - 1, -1);
|
Gtk::TreePath path;
|
||||||
gtk_tree_selection_select_path (selection, path);
|
path.push_back(Cheat.g.size() - 1);
|
||||||
gtk_tree_path_free (path);
|
selection->select(path);
|
||||||
|
|
||||||
GtkScrolledWindow *scroll = GTK_SCROLLED_WINDOW (get_widget ("cheat_scrolledwindow"));
|
auto adj = get_object<Gtk::ScrolledWindow>("cheat_scrolledwindow")->get_vadjustment();
|
||||||
GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment (scroll);
|
adj->set_value(adj->get_upper());
|
||||||
gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Snes9xCheats::remove_code()
|
||||||
Snes9xCheats::remove_code ()
|
|
||||||
{
|
{
|
||||||
int index = get_selected_index ();
|
int index = get_selected_index();
|
||||||
GtkTreeIter iter;
|
|
||||||
|
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
enable_dnd (false);
|
enable_dnd(false);
|
||||||
gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, NULL, index);
|
|
||||||
gtk_list_store_remove (store, &iter);
|
|
||||||
enable_dnd (true);
|
|
||||||
|
|
||||||
S9xDeleteCheatGroup (index);
|
Gtk::TreePath path;
|
||||||
|
path.push_back(index);
|
||||||
|
|
||||||
|
auto iter = store->get_iter(path);
|
||||||
|
store->erase(iter);
|
||||||
|
|
||||||
|
enable_dnd(true);
|
||||||
|
|
||||||
|
S9xDeleteCheatGroup(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Snes9xCheats::delete_all_cheats()
|
||||||
Snes9xCheats::delete_all_cheats ()
|
|
||||||
{
|
{
|
||||||
enable_dnd (false);
|
enable_dnd(false);
|
||||||
S9xDeleteCheats ();
|
S9xDeleteCheats();
|
||||||
gtk_list_store_clear (store);
|
store->clear();
|
||||||
enable_dnd (true);
|
enable_dnd(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Snes9xCheats::search_database()
|
||||||
Snes9xCheats::search_database ()
|
|
||||||
{
|
{
|
||||||
std::string filename;
|
std::string filename;
|
||||||
int result;
|
int result;
|
||||||
int reason = 0;
|
int reason = 0;
|
||||||
|
|
||||||
filename = S9xGetDirectory (CHEAT_DIR);
|
filename = S9xGetDirectory(CHEAT_DIR);
|
||||||
filename += "/cheats.bml";
|
filename += "/cheats.bml";
|
||||||
if (!(result = S9xImportCheatsFromDatabase (filename.c_str ())))
|
if (!(result = S9xImportCheatsFromDatabase(filename.c_str())))
|
||||||
{
|
{
|
||||||
refresh_tree_view ();
|
refresh_tree_view();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result < reason)
|
if (result < reason)
|
||||||
reason = result;
|
reason = result;
|
||||||
|
|
||||||
filename = get_config_dir () + "/cheats.bml";
|
filename = get_config_dir() + "/cheats.bml";
|
||||||
if (!(result = S9xImportCheatsFromDatabase (filename.c_str ())))
|
if (!(result = S9xImportCheatsFromDatabase(filename.c_str())))
|
||||||
{
|
{
|
||||||
refresh_tree_view ();
|
refresh_tree_view();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result < reason)
|
if (result < reason)
|
||||||
reason = result;
|
reason = result;
|
||||||
|
|
||||||
filename = std::string (DATADIR) + "/cheats.bml";
|
filename = std::string(DATADIR) + "/cheats.bml";
|
||||||
if (!(result = S9xImportCheatsFromDatabase (filename.c_str ())))
|
if (!(result = S9xImportCheatsFromDatabase(filename.c_str())))
|
||||||
{
|
{
|
||||||
refresh_tree_view ();
|
refresh_tree_view();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result < reason)
|
if (result < reason)
|
||||||
reason = result;
|
reason = result;
|
||||||
|
|
||||||
filename = S9xGetDirectory (ROM_DIR);
|
filename = S9xGetDirectory(ROM_DIR);
|
||||||
filename += "/cheats.bml";
|
filename += "/cheats.bml";
|
||||||
if (!(result = S9xImportCheatsFromDatabase (filename.c_str ())))
|
if (!(result = S9xImportCheatsFromDatabase(filename.c_str())))
|
||||||
{
|
{
|
||||||
refresh_tree_view ();
|
refresh_tree_view();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result < reason)
|
if (result < reason)
|
||||||
reason = result;
|
reason = result;
|
||||||
|
|
||||||
GtkMessageDialog *dialog;
|
auto dialog = Gtk::MessageDialog(*window.get(), reason == -1 ? _("Couldn't Find Cheats Database") : _("No Matching Game Found"), true);
|
||||||
GtkDialogFlags flags = GTK_DIALOG_DESTROY_WITH_PARENT;
|
dialog.set_secondary_text(reason == -1 ? _("The database file <b>cheats.bml</b> was not found. It is normally installed with "
|
||||||
dialog = GTK_MESSAGE_DIALOG (gtk_message_dialog_new (get_window (),
|
"Snes9x, but you may also place a custom copy in your configuration or cheats directory.")
|
||||||
flags,
|
: _("No matching game was found in the databases. If you are using a non-official "
|
||||||
GTK_MESSAGE_INFO,
|
"translation or modified copy, you may be able to find and manually enter the codes."));
|
||||||
GTK_BUTTONS_CLOSE,
|
dialog.run();
|
||||||
reason == -1 ? _("Couldn't Find Cheats Database") :
|
dialog.hide();
|
||||||
_("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 "
|
|
||||||
"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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Snes9xCheats::sort_cheats()
|
||||||
Snes9xCheats::sort_cheats ()
|
|
||||||
{
|
{
|
||||||
cheat_gather_enabled ();
|
cheat_gather_enabled();
|
||||||
refresh_tree_view ();
|
refresh_tree_view();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Snes9xCheats::row_activated(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column)
|
||||||
Snes9xCheats::row_activated (GtkTreePath *path)
|
|
||||||
{
|
{
|
||||||
gint *indices = gtk_tree_path_get_indices (path);
|
int index = get_index_from_path(path);
|
||||||
char *cheat_text;
|
char *cheat_text;
|
||||||
|
|
||||||
cheat_text = S9xCheatGroupToText (indices[0]);
|
cheat_text = S9xCheatGroupToText(index);
|
||||||
set_entry_text ("code_entry", cheat_text);
|
set_entry_text("code_entry", cheat_text);
|
||||||
delete[] 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
|
void Snes9xCheats::toggle_code(const Glib::ustring &path)
|
||||||
Snes9xCheats::toggle_code (const gchar *path, int enabled)
|
|
||||||
{
|
{
|
||||||
GtkTreeIter iter;
|
int index = get_index_from_path(path);
|
||||||
int index = get_index_from_path (path);
|
auto iter = store->get_iter(path);
|
||||||
|
bool enabled;
|
||||||
GtkTreePath *treepath = gtk_tree_path_new_from_string (path);
|
iter->get_value(COLUMN_ENABLED, enabled);
|
||||||
gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, treepath);
|
enabled = !enabled;
|
||||||
gtk_list_store_set (store, &iter, COLUMN_ENABLED, enabled, -1);
|
iter->set_value(COLUMN_ENABLED, enabled);
|
||||||
|
|
||||||
if (enabled)
|
if (enabled)
|
||||||
S9xEnableCheatGroup (index);
|
S9xEnableCheatGroup(index);
|
||||||
else
|
else
|
||||||
S9xDisableCheatGroup (index);
|
S9xDisableCheatGroup(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Snes9xCheats::update_code()
|
||||||
Snes9xCheats::update_code ()
|
|
||||||
{
|
{
|
||||||
int index = get_selected_index ();
|
int index = get_selected_index();
|
||||||
|
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const char *description;
|
std::string code = get_entry_text("code_entry");
|
||||||
char *code = (char *) get_entry_text ("code_entry");
|
std::string description = get_entry_text("description_entry");
|
||||||
|
if (description.empty())
|
||||||
description = get_entry_text ("description_entry");
|
|
||||||
if (description[0] == '\0')
|
|
||||||
description = _("No description");
|
description = _("No description");
|
||||||
|
|
||||||
code = S9xCheatValidate (code);
|
auto parsed_code = S9xCheatValidate(code.c_str());
|
||||||
if (!code)
|
if (!parsed_code)
|
||||||
{
|
{
|
||||||
display_errorbox (_("Couldn't find any cheat codes in input."));
|
display_errorbox(_("Couldn't find any cheat codes in input."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xModifyCheatGroup (index, description, code);
|
S9xModifyCheatGroup(index, description.c_str(), parsed_code);
|
||||||
set_entry_text ("code_entry", code);
|
set_entry_text("code_entry", parsed_code);
|
||||||
delete[] code;
|
delete[] parsed_code;
|
||||||
|
|
||||||
gtk_widget_grab_focus (get_widget ("code_entry"));
|
get_object<Gtk::Entry>("code_entry")->grab_focus();
|
||||||
|
|
||||||
refresh_tree_view ();
|
refresh_tree_view();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Snes9xCheats::disable_all()
|
||||||
Snes9xCheats::disable_all ()
|
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < Cheat.g.size(); i++)
|
for (unsigned int i = 0; i < Cheat.g.size(); i++)
|
||||||
{
|
{
|
||||||
if (Cheat.g[i].enabled)
|
if (Cheat.g[i].enabled)
|
||||||
S9xDisableCheatGroup (i);
|
S9xDisableCheatGroup(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh_tree_view ();
|
refresh_tree_view();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,41 +9,43 @@
|
||||||
|
|
||||||
#include "gtk_builder_window.h"
|
#include "gtk_builder_window.h"
|
||||||
|
|
||||||
enum
|
void open_snes9x_cheats_dialog();
|
||||||
{
|
|
||||||
TYPE_GAME_GENIE = 0,
|
enum {
|
||||||
|
TYPE_GAME_GENIE = 0,
|
||||||
TYPE_ACTION_REPLAY = 1,
|
TYPE_ACTION_REPLAY = 1,
|
||||||
TYPE_GOLDFINGER = 2
|
TYPE_GOLDFINGER = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
class Snes9xCheats : public GtkBuilderWindow
|
class Snes9xCheats : public GtkBuilderWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Snes9xCheats ();
|
Snes9xCheats();
|
||||||
~Snes9xCheats ();
|
~Snes9xCheats();
|
||||||
void show ();
|
void show();
|
||||||
void add_code ();
|
void add_code();
|
||||||
void remove_code ();
|
void remove_code();
|
||||||
void search_database ();
|
void search_database();
|
||||||
void delete_all_cheats ();
|
void delete_all_cheats();
|
||||||
void toggle_code (const gchar *path, int enabled);
|
void toggle_code(const Glib::ustring &path);
|
||||||
void row_activated (GtkTreePath *path);
|
void row_activated(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column);
|
||||||
void row_deleted (int src_row);
|
void row_deleted(int src_row);
|
||||||
void row_inserted (int row);
|
void row_inserted(int row);
|
||||||
void enable_dnd (bool);
|
void enable_dnd(bool);
|
||||||
void sort_cheats ();
|
void sort_cheats();
|
||||||
void update_code ();
|
void update_code();
|
||||||
void disable_all ();
|
void disable_all();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void refresh_tree_view ();
|
void refresh_tree_view();
|
||||||
int get_selected_index ();
|
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;
|
sigc::connection insert_id;
|
||||||
unsigned long delete_id;
|
sigc::connection delete_id;
|
||||||
int dst_row;
|
int dst_row;
|
||||||
GtkListStore *store;
|
Glib::RefPtr<Gtk::ListStore> store;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __GTK_CHEAT_H */
|
#endif /* __GTK_CHEAT_H */
|
||||||
|
|
|
@ -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
|
|
@ -14,6 +14,10 @@
|
||||||
#include "gtk_sound.h"
|
#include "gtk_sound.h"
|
||||||
#include "gtk_display.h"
|
#include "gtk_display.h"
|
||||||
#include "conffile.h"
|
#include "conffile.h"
|
||||||
|
#include "cheats.h"
|
||||||
|
#include "apu/apu.h"
|
||||||
|
#include "netplay.h"
|
||||||
|
#include "controls.h"
|
||||||
|
|
||||||
static bool directory_exists(std::string str)
|
static bool directory_exists(std::string str)
|
||||||
{
|
{
|
||||||
|
@ -38,7 +42,7 @@ std::string get_config_dir()
|
||||||
|
|
||||||
if (!env_home && !env_xdg_config_home)
|
if (!env_home && !env_xdg_config_home)
|
||||||
{
|
{
|
||||||
return std::string(".snes9x");
|
return std::string{".snes9x"};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string config;
|
std::string config;
|
||||||
|
@ -70,7 +74,6 @@ void S9xParsePortConfig(ConfigFile &conf, int pass)
|
||||||
|
|
||||||
Snes9xConfig::Snes9xConfig()
|
Snes9xConfig::Snes9xConfig()
|
||||||
{
|
{
|
||||||
joystick = NULL;
|
|
||||||
joystick_threshold = 40;
|
joystick_threshold = 40;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,8 +106,8 @@ int Snes9xConfig::load_defaults()
|
||||||
default_esc_behavior = 1;
|
default_esc_behavior = 1;
|
||||||
prevent_screensaver = false;
|
prevent_screensaver = false;
|
||||||
sound_driver = 0;
|
sound_driver = 0;
|
||||||
sound_buffer_size = 32;
|
sound_buffer_size = 48;
|
||||||
sound_playback_rate = 5;
|
sound_playback_rate = 7;
|
||||||
sound_input_rate = 31950;
|
sound_input_rate = 31950;
|
||||||
auto_input_rate = true;
|
auto_input_rate = true;
|
||||||
last_directory.clear();
|
last_directory.clear();
|
||||||
|
@ -149,7 +152,7 @@ int Snes9xConfig::load_defaults()
|
||||||
sync_to_vblank = true;
|
sync_to_vblank = true;
|
||||||
use_pbos = true;
|
use_pbos = true;
|
||||||
pbo_format = 0;
|
pbo_format = 0;
|
||||||
npot_textures = false;
|
npot_textures = true;
|
||||||
use_shaders = false;
|
use_shaders = false;
|
||||||
shader_filename.clear();
|
shader_filename.clear();
|
||||||
use_glfinish = false;
|
use_glfinish = false;
|
||||||
|
@ -206,26 +209,26 @@ int Snes9xConfig::load_defaults()
|
||||||
|
|
||||||
void Snes9xConfig::joystick_register_centers()
|
void Snes9xConfig::joystick_register_centers()
|
||||||
{
|
{
|
||||||
for (int i = 0; joystick[i] != NULL; i++)
|
for (auto &j : joystick)
|
||||||
joystick[i]->register_centers();
|
j.register_centers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Snes9xConfig::flush_joysticks()
|
void Snes9xConfig::flush_joysticks()
|
||||||
{
|
{
|
||||||
for (int i = 0; joystick[i] != NULL; i++)
|
for (auto &j : joystick)
|
||||||
joystick[i]->flush();
|
j.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Snes9xConfig::set_joystick_mode(int mode)
|
void Snes9xConfig::set_joystick_mode(int mode)
|
||||||
{
|
{
|
||||||
for (int i = 0; joystick[i] != NULL; i++)
|
for (auto &j : joystick)
|
||||||
joystick[i]->mode = mode;
|
j.mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Snes9xConfig::save_config_file()
|
int Snes9xConfig::save_config_file()
|
||||||
{
|
{
|
||||||
ConfigFile cf;
|
ConfigFile cf;
|
||||||
std::string section = "";
|
std::string section;
|
||||||
|
|
||||||
auto outbool = [&](std::string name, bool b, std::string comment = "") {
|
auto outbool = [&](std::string name, bool b, std::string comment = "") {
|
||||||
cf.SetBool((section + "::" + name).c_str(), b, "true", "false", comment.c_str());
|
cf.SetBool((section + "::" + name).c_str(), b, "true", "false", comment.c_str());
|
||||||
|
|
|
@ -7,14 +7,14 @@
|
||||||
#ifndef __GTK_CONFIG_H
|
#ifndef __GTK_CONFIG_H
|
||||||
#define __GTK_CONFIG_H
|
#define __GTK_CONFIG_H
|
||||||
|
|
||||||
|
#include "gtk_control.h"
|
||||||
|
#include "filter/snes_ntsc.h"
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/extensions/Xrandr.h>
|
#include <X11/extensions/Xrandr.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "gtk_control.h"
|
|
||||||
#include "filter/snes_ntsc.h"
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
HWA_NONE = 0,
|
HWA_NONE = 0,
|
||||||
HWA_OPENGL = 1,
|
HWA_OPENGL = 1,
|
||||||
|
@ -53,14 +53,14 @@ enum {
|
||||||
class Snes9xConfig
|
class Snes9xConfig
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Snes9xConfig ();
|
Snes9xConfig();
|
||||||
int load_config_file ();
|
int load_config_file();
|
||||||
int save_config_file ();
|
int save_config_file();
|
||||||
int load_defaults ();
|
int load_defaults();
|
||||||
void rebind_keys ();
|
void rebind_keys();
|
||||||
void flush_joysticks ();
|
void flush_joysticks();
|
||||||
void set_joystick_mode (int mode);
|
void set_joystick_mode(int mode);
|
||||||
void joystick_register_centers ();
|
void joystick_register_centers();
|
||||||
|
|
||||||
/* Screen options */
|
/* Screen options */
|
||||||
bool full_screen_on_open;
|
bool full_screen_on_open;
|
||||||
|
@ -167,11 +167,11 @@ class Snes9xConfig
|
||||||
bool use_sync_control;
|
bool use_sync_control;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JoyDevice **joystick;
|
std::vector<JoyDevice> joystick;
|
||||||
int joystick_threshold;
|
int joystick_threshold;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string get_config_dir ();
|
std::string get_config_dir();
|
||||||
std::string get_config_file_name ();
|
std::string get_config_file_name();
|
||||||
|
|
||||||
#endif /* __GTK_CONFIG_H */
|
#endif /* __GTK_CONFIG_H */
|
||||||
|
|
|
@ -6,12 +6,17 @@
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include "gtk_s9xcore.h"
|
#include "SDL_joystick.h"
|
||||||
#include "gtk_s9x.h"
|
#include "gtk_s9x.h"
|
||||||
#include "gtk_config.h"
|
#include "gtk_config.h"
|
||||||
#include "gtk_control.h"
|
#include "gtk_control.h"
|
||||||
#include "gtk_file.h"
|
#include "gtk_file.h"
|
||||||
|
|
||||||
|
#include "snes9x.h"
|
||||||
|
#include "controls.h"
|
||||||
|
#include "display.h"
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
const BindingLink b_links[] =
|
const BindingLink b_links[] =
|
||||||
{
|
{
|
||||||
/* Joypad-specific bindings. "Joypad# " will be prepended */
|
/* Joypad-specific bindings. "Joypad# " will be prepended */
|
||||||
|
@ -122,17 +127,17 @@ const int b_breaks[] =
|
||||||
|
|
||||||
static int joystick_lock = 0;
|
static int joystick_lock = 0;
|
||||||
|
|
||||||
bool S9xPollButton (uint32 id, bool *pressed)
|
bool S9xPollButton(uint32 id, bool *pressed)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool S9xPollAxis (uint32 id, int16 *value)
|
bool S9xPollAxis(uint32 id, int16 *value)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool S9xPollPointer (uint32 id, int16 *x, int16 *y)
|
bool S9xPollPointer(uint32 id, int16 *x, int16 *y)
|
||||||
{
|
{
|
||||||
*x = top_level->snes_mouse_x;
|
*x = top_level->snes_mouse_x;
|
||||||
*y = top_level->snes_mouse_y;
|
*y = top_level->snes_mouse_y;
|
||||||
|
@ -140,14 +145,14 @@ bool S9xPollPointer (uint32 id, int16 *x, int16 *y)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool S9xIsMousePluggedIn ()
|
bool S9xIsMousePluggedIn()
|
||||||
{
|
{
|
||||||
enum controllers ctl;
|
enum controllers ctl;
|
||||||
int8 id1, id2, id3, id4;
|
int8 id1, id2, id3, id4;
|
||||||
|
|
||||||
for (int i = 0; i <= 1; i++)
|
for (int i = 0; i <= 1; i++)
|
||||||
{
|
{
|
||||||
S9xGetController (i, &ctl, &id1, &id2, &id3, &id4);
|
S9xGetController(i, &ctl, &id1, &id2, &id3, &id4);
|
||||||
if (ctl == CTL_MOUSE || ctl == CTL_SUPERSCOPE)
|
if (ctl == CTL_MOUSE || ctl == CTL_SUPERSCOPE)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -155,7 +160,7 @@ bool S9xIsMousePluggedIn ()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool S9xGrabJoysticks ()
|
bool S9xGrabJoysticks()
|
||||||
{
|
{
|
||||||
if (joystick_lock)
|
if (joystick_lock)
|
||||||
return false;
|
return false;
|
||||||
|
@ -165,12 +170,12 @@ bool S9xGrabJoysticks ()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xReleaseJoysticks ()
|
void S9xReleaseJoysticks()
|
||||||
{
|
{
|
||||||
joystick_lock--;
|
joystick_lock--;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void swap_controllers_1_2 ()
|
static void swap_controllers_1_2()
|
||||||
{
|
{
|
||||||
JoypadBinding interrim;
|
JoypadBinding interrim;
|
||||||
|
|
||||||
|
@ -178,10 +183,10 @@ static void swap_controllers_1_2 ()
|
||||||
gui_config->pad[0] = gui_config->pad[1];
|
gui_config->pad[0] = gui_config->pad[1];
|
||||||
gui_config->pad[1] = interrim;
|
gui_config->pad[1] = interrim;
|
||||||
|
|
||||||
gui_config->rebind_keys ();
|
gui_config->rebind_keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void change_slot (int difference)
|
static void change_slot(int difference)
|
||||||
{
|
{
|
||||||
static char buf[256];
|
static char buf[256];
|
||||||
|
|
||||||
|
@ -192,12 +197,12 @@ static void change_slot (int difference)
|
||||||
if (!gui_config->rom_loaded)
|
if (!gui_config->rom_loaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
snprintf (buf, 256, "State Slot: %d", gui_config->current_save_slot);
|
snprintf(buf, 256, "State Slot: %d", gui_config->current_save_slot);
|
||||||
S9xSetInfoString (buf);
|
S9xSetInfoString(buf);
|
||||||
GFX.InfoStringTimeout = 60;
|
GFX.InfoStringTimeout = 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xHandlePortCommand (s9xcommand_t cmd, int16 data1, int16 data2)
|
void S9xHandlePortCommand(s9xcommand_t cmd, int16 data1, int16 data2)
|
||||||
{
|
{
|
||||||
static bool quit_binding_down = false;
|
static bool quit_binding_down = false;
|
||||||
|
|
||||||
|
@ -215,109 +220,93 @@ void S9xHandlePortCommand (s9xcommand_t cmd, int16 data1, int16 data2)
|
||||||
{
|
{
|
||||||
quit_binding_down = false;
|
quit_binding_down = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd.port[0] == PORT_COMMAND_FULLSCREEN)
|
if (cmd.port[0] == PORT_COMMAND_FULLSCREEN)
|
||||||
{
|
{
|
||||||
top_level->toggle_fullscreen_mode ();
|
top_level->toggle_fullscreen_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd.port[0] == PORT_COMMAND_SAVE_SPC)
|
else if (cmd.port[0] == PORT_COMMAND_SAVE_SPC)
|
||||||
{
|
{
|
||||||
top_level->save_spc_dialog ();
|
top_level->save_spc_dialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd.port[0] == PORT_OPEN_ROM)
|
else if (cmd.port[0] == PORT_OPEN_ROM)
|
||||||
{
|
{
|
||||||
top_level->open_rom_dialog ();
|
top_level->open_rom_dialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd.port[0] == PORT_PAUSE)
|
else if (cmd.port[0] == PORT_PAUSE)
|
||||||
{
|
{
|
||||||
if (!(top_level->user_pause))
|
if (!(top_level->user_pause))
|
||||||
top_level->pause_from_user ();
|
top_level->pause_from_user();
|
||||||
else
|
else
|
||||||
top_level->unpause_from_user ();
|
top_level->unpause_from_user();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd.port[0] == PORT_REWIND)
|
else if (cmd.port[0] == PORT_REWIND)
|
||||||
{
|
{
|
||||||
Settings.Rewinding = false;
|
Settings.Rewinding = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd.port[0] == PORT_SEEK_TO_FRAME)
|
else if (cmd.port[0] == PORT_SEEK_TO_FRAME)
|
||||||
{
|
{
|
||||||
top_level->movie_seek_dialog ();
|
top_level->movie_seek_dialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd.port[0] == PORT_SWAP_CONTROLLERS)
|
else if (cmd.port[0] == PORT_SWAP_CONTROLLERS)
|
||||||
{
|
{
|
||||||
swap_controllers_1_2 ();
|
swap_controllers_1_2();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd.port[0] == PORT_QUIT)
|
else if (cmd.port[0] == PORT_QUIT)
|
||||||
{
|
{
|
||||||
if (quit_binding_down)
|
if (quit_binding_down)
|
||||||
S9xExit ();
|
S9xExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd.port[0] >= PORT_QUICKLOAD0 && cmd.port[0] <= PORT_QUICKLOAD9)
|
else if (cmd.port[0] >= PORT_QUICKLOAD0 && cmd.port[0] <= PORT_QUICKLOAD9)
|
||||||
{
|
{
|
||||||
S9xQuickLoadSlot (cmd.port[0] - PORT_QUICKLOAD0);
|
S9xQuickLoadSlot(cmd.port[0] - PORT_QUICKLOAD0);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd.port[0] == PORT_SAVESLOT)
|
else if (cmd.port[0] == PORT_SAVESLOT)
|
||||||
{
|
{
|
||||||
S9xQuickSaveSlot (gui_config->current_save_slot);
|
S9xQuickSaveSlot(gui_config->current_save_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd.port[0] == PORT_LOADSLOT)
|
else if (cmd.port[0] == PORT_LOADSLOT)
|
||||||
{
|
{
|
||||||
S9xQuickLoadSlot (gui_config->current_save_slot);
|
S9xQuickLoadSlot(gui_config->current_save_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd.port[0] == PORT_INCREMENTSAVESLOT)
|
else if (cmd.port[0] == PORT_INCREMENTSAVESLOT)
|
||||||
{
|
{
|
||||||
change_slot (1);
|
change_slot(1);
|
||||||
S9xQuickSaveSlot (gui_config->current_save_slot);
|
S9xQuickSaveSlot(gui_config->current_save_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd.port[0] == PORT_DECREMENTLOADSLOT)
|
else if (cmd.port[0] == PORT_DECREMENTLOADSLOT)
|
||||||
{
|
{
|
||||||
change_slot (-1);
|
change_slot(-1);
|
||||||
S9xQuickLoadSlot (gui_config->current_save_slot);
|
S9xQuickLoadSlot(gui_config->current_save_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd.port[0] == PORT_INCREMENTSLOT)
|
else if (cmd.port[0] == PORT_INCREMENTSLOT)
|
||||||
{
|
{
|
||||||
change_slot (1);
|
change_slot(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd.port[0] == PORT_DECREMENTSLOT)
|
else if (cmd.port[0] == PORT_DECREMENTSLOT)
|
||||||
{
|
{
|
||||||
change_slot (-1);
|
change_slot(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd.port[0] == PORT_GRABMOUSE)
|
else if (cmd.port[0] == PORT_GRABMOUSE)
|
||||||
{
|
{
|
||||||
top_level->toggle_grab_mouse ();
|
top_level->toggle_grab_mouse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding S9xGetBindingByName (const char *name)
|
Binding S9xGetBindingByName(const char *name)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_EMU_LINKS; i++)
|
for (int i = 0; i < NUM_EMU_LINKS; i++)
|
||||||
{
|
{
|
||||||
if (!strcasecmp (b_links[i + NUM_JOYPAD_LINKS].snes9x_name, name))
|
if (!strcasecmp(b_links[i + NUM_JOYPAD_LINKS].snes9x_name, name))
|
||||||
{
|
{
|
||||||
return gui_config->shortcut[i];
|
return gui_config->shortcut[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Binding ();
|
return Binding();
|
||||||
}
|
}
|
||||||
|
|
||||||
s9xcommand_t S9xGetPortCommandT (const char *name)
|
s9xcommand_t S9xGetPortCommandT(const char *name)
|
||||||
{
|
{
|
||||||
s9xcommand_t cmd;
|
s9xcommand_t cmd;
|
||||||
|
|
||||||
|
@ -329,248 +318,214 @@ s9xcommand_t S9xGetPortCommandT (const char *name)
|
||||||
cmd.port[2] = 0;
|
cmd.port[2] = 0;
|
||||||
cmd.port[3] = 0;
|
cmd.port[3] = 0;
|
||||||
|
|
||||||
if (!strcasecmp (name, "GTK_fullscreen"))
|
if (!strcasecmp(name, "GTK_fullscreen"))
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_COMMAND_FULLSCREEN;
|
cmd.port[0] = PORT_COMMAND_FULLSCREEN;
|
||||||
}
|
}
|
||||||
|
else if (!strcasecmp(name, "GTK_save_spc"))
|
||||||
else if (!strcasecmp (name, "GTK_save_spc"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_COMMAND_SAVE_SPC;
|
cmd.port[0] = PORT_COMMAND_SAVE_SPC;
|
||||||
}
|
}
|
||||||
|
else if (!strcasecmp(name, "GTK_open_rom"))
|
||||||
else if (!strcasecmp (name, "GTK_open_rom"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_OPEN_ROM;
|
cmd.port[0] = PORT_OPEN_ROM;
|
||||||
}
|
}
|
||||||
|
else if (!strcasecmp(name, "GTK_pause"))
|
||||||
else if (!strcasecmp (name, "GTK_pause"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_PAUSE;
|
cmd.port[0] = PORT_PAUSE;
|
||||||
}
|
}
|
||||||
|
else if (!strcasecmp(name, "GTK_seek_to_frame"))
|
||||||
else if (!strcasecmp (name, "GTK_seek_to_frame"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_SEEK_TO_FRAME;
|
cmd.port[0] = PORT_SEEK_TO_FRAME;
|
||||||
}
|
}
|
||||||
|
else if (!strcasecmp(name, "GTK_quit"))
|
||||||
else if (!strcasecmp (name, "GTK_quit"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_QUIT;
|
cmd.port[0] = PORT_QUIT;
|
||||||
}
|
}
|
||||||
|
else if (!strcasecmp(name, "GTK_swap_controllers"))
|
||||||
else if (!strcasecmp (name, "GTK_swap_controllers"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_SWAP_CONTROLLERS;
|
cmd.port[0] = PORT_SWAP_CONTROLLERS;
|
||||||
}
|
}
|
||||||
|
else if (!strcasecmp(name, "GTK_rewind"))
|
||||||
else if (!strcasecmp (name, "GTK_rewind"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_REWIND;
|
cmd.port[0] = PORT_REWIND;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "QuickLoad000"))
|
||||||
else if (strstr (name, "QuickLoad000"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_QUICKLOAD0;
|
cmd.port[0] = PORT_QUICKLOAD0;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "QuickLoad001"))
|
||||||
else if (strstr (name, "QuickLoad001"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_QUICKLOAD1;
|
cmd.port[0] = PORT_QUICKLOAD1;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "QuickLoad002"))
|
||||||
else if (strstr (name, "QuickLoad002"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_QUICKLOAD2;
|
cmd.port[0] = PORT_QUICKLOAD2;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "QuickLoad003"))
|
||||||
else if (strstr (name, "QuickLoad003"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_QUICKLOAD3;
|
cmd.port[0] = PORT_QUICKLOAD3;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "QuickLoad004"))
|
||||||
else if (strstr (name, "QuickLoad004"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_QUICKLOAD4;
|
cmd.port[0] = PORT_QUICKLOAD4;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "QuickLoad005"))
|
||||||
else if (strstr (name, "QuickLoad005"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_QUICKLOAD5;
|
cmd.port[0] = PORT_QUICKLOAD5;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "QuickLoad006"))
|
||||||
else if (strstr (name, "QuickLoad006"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_QUICKLOAD6;
|
cmd.port[0] = PORT_QUICKLOAD6;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "QuickLoad007"))
|
||||||
else if (strstr (name, "QuickLoad007"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_QUICKLOAD7;
|
cmd.port[0] = PORT_QUICKLOAD7;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "QuickLoad008"))
|
||||||
else if (strstr (name, "QuickLoad008"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_QUICKLOAD8;
|
cmd.port[0] = PORT_QUICKLOAD8;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "QuickLoad009"))
|
||||||
else if (strstr (name, "QuickLoad009"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_QUICKLOAD9;
|
cmd.port[0] = PORT_QUICKLOAD9;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "GTK_state_save_current"))
|
||||||
else if (strstr (name, "GTK_state_save_current"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_SAVESLOT;
|
cmd.port[0] = PORT_SAVESLOT;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "GTK_state_load_current"))
|
||||||
else if (strstr (name, "GTK_state_load_current"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_LOADSLOT;
|
cmd.port[0] = PORT_LOADSLOT;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "GTK_state_increment_save"))
|
||||||
else if (strstr (name, "GTK_state_increment_save"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_INCREMENTSAVESLOT;
|
cmd.port[0] = PORT_INCREMENTSAVESLOT;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "GTK_state_decrement_load"))
|
||||||
else if (strstr (name, "GTK_state_decrement_load"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_DECREMENTLOADSLOT;
|
cmd.port[0] = PORT_DECREMENTLOADSLOT;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "GTK_state_increment"))
|
||||||
else if (strstr (name, "GTK_state_increment"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_INCREMENTSLOT;
|
cmd.port[0] = PORT_INCREMENTSLOT;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "GTK_state_decrement"))
|
||||||
else if (strstr (name, "GTK_state_decrement"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_DECREMENTSLOT;
|
cmd.port[0] = PORT_DECREMENTSLOT;
|
||||||
}
|
}
|
||||||
|
else if (strstr(name, "GTK_grab_mouse"))
|
||||||
else if (strstr (name, "GTK_grab_mouse"))
|
|
||||||
{
|
{
|
||||||
cmd.port[0] = PORT_GRABMOUSE;
|
cmd.port[0] = PORT_GRABMOUSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cmd = S9xGetCommandT (name);
|
cmd = S9xGetCommandT(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xProcessEvents (bool8 block)
|
void S9xProcessEvents(bool8 block)
|
||||||
{
|
{
|
||||||
JoyEvent event;
|
JoyEvent event;
|
||||||
Binding binding;
|
Binding binding;
|
||||||
|
|
||||||
if (S9xGrabJoysticks ())
|
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);
|
binding = Binding(i, event.parameter, 0);
|
||||||
S9xReportButton (binding.hex (), event.state == JOY_PRESSED ? 1 : 0);
|
S9xReportButton(binding.hex(), event.state == JOY_PRESSED ? 1 : 0);
|
||||||
gui_config->screensaver_needs_reset = true;
|
gui_config->screensaver_needs_reset = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xReleaseJoysticks ();
|
S9xReleaseJoysticks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void poll_joystick_events ()
|
static void poll_joystick_events()
|
||||||
{
|
{
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
|
||||||
while (SDL_PollEvent (&event))
|
while (SDL_PollEvent(&event))
|
||||||
{
|
{
|
||||||
if (event.type == SDL_JOYAXISMOTION)
|
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)
|
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 ||
|
else if (event.type == SDL_JOYBUTTONUP ||
|
||||||
event.type == SDL_JOYBUTTONDOWN)
|
event.type == SDL_JOYBUTTONDOWN)
|
||||||
{
|
{
|
||||||
gui_config->joystick[event.jbutton.which]->handle_event (&event);
|
gui_config->joystick[event.jbutton.which].handle_event(&event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xInitInputDevices ()
|
void S9xInitInputDevices()
|
||||||
{
|
{
|
||||||
SDL_Init (SDL_INIT_JOYSTICK);
|
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 **)
|
gui_config->joystick[i].set_sdl_joystick_num(i);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//First plug in both, they'll change later as needed
|
//First plug in both, they'll change later as needed
|
||||||
S9xSetController (0, CTL_JOYPAD, 0, 0, 0, 0);
|
S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);
|
||||||
S9xSetController (1, CTL_JOYPAD, 1, 0, 0, 0);
|
S9xSetController(1, CTL_JOYPAD, 1, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xDeinitInputDevices ()
|
void S9xDeinitInputDevices()
|
||||||
{
|
{
|
||||||
for (int i = 0; gui_config->joystick[i] != NULL; i++)
|
gui_config->joystick.clear();
|
||||||
{
|
SDL_Quit();
|
||||||
delete gui_config->joystick[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
free (gui_config->joystick);
|
|
||||||
|
|
||||||
SDL_Quit ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JoyDevice::JoyDevice (unsigned int device_num)
|
JoyDevice::JoyDevice()
|
||||||
{
|
{
|
||||||
enabled = false;
|
enabled = false;
|
||||||
axis = NULL;
|
|
||||||
filedes = NULL;
|
filedes = NULL;
|
||||||
mode = JOY_MODE_INDIVIDUAL;
|
mode = JOY_MODE_INDIVIDUAL;
|
||||||
|
}
|
||||||
|
|
||||||
if ((int) device_num >= SDL_NumJoysticks ())
|
JoyDevice::~JoyDevice()
|
||||||
return;
|
{
|
||||||
|
if (enabled)
|
||||||
|
{
|
||||||
|
SDL_JoystickClose(filedes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
filedes = SDL_JoystickOpen (device_num);
|
bool JoyDevice::set_sdl_joystick_num(unsigned int device_num)
|
||||||
|
{
|
||||||
|
if ((int)device_num >= SDL_NumJoysticks())
|
||||||
|
{
|
||||||
|
enabled = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
filedes = SDL_JoystickOpen(device_num);
|
||||||
|
|
||||||
if (!filedes)
|
if (!filedes)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
enabled = true;
|
enabled = true;
|
||||||
|
|
||||||
num_axes = SDL_JoystickNumAxes (filedes);
|
int num_axes = SDL_JoystickNumAxes(filedes);
|
||||||
num_hats = SDL_JoystickNumHats (filedes);
|
int num_hats = SDL_JoystickNumHats(filedes);
|
||||||
axis = new int[num_axes];
|
axis.resize(num_axes);
|
||||||
hat = new int[num_hats];
|
hat.resize(num_hats);
|
||||||
calibration = new Calibration[num_axes];
|
calibration.resize(num_axes);
|
||||||
|
|
||||||
for (int i = 0; i < num_axes; i++)
|
for (int i = 0; i < num_axes; i++)
|
||||||
{
|
{
|
||||||
|
@ -579,41 +534,31 @@ JoyDevice::JoyDevice (unsigned int device_num)
|
||||||
calibration[i].center = 0;
|
calibration[i].center = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Joystick %d, %s:\n %d axes, %d buttons, %d hats\n",
|
printf("Joystick %d, %s:\n %d axes, %d buttons, %d hats\n",
|
||||||
device_num + 1,
|
device_num + 1,
|
||||||
SDL_JoystickName (filedes),
|
SDL_JoystickName(filedes),
|
||||||
SDL_JoystickNumButtons (filedes),
|
SDL_JoystickNumButtons(filedes),
|
||||||
num_axes,
|
num_axes,
|
||||||
num_hats);
|
num_hats);
|
||||||
|
|
||||||
memset (axis, 0, sizeof (int) * num_axes);
|
for (auto &i : axis)
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
JoyDevice::~JoyDevice ()
|
void JoyDevice::add_event(unsigned int parameter, unsigned int state)
|
||||||
{
|
|
||||||
if (enabled)
|
|
||||||
{
|
|
||||||
SDL_JoystickClose (filedes);
|
|
||||||
delete[] axis;
|
|
||||||
delete[] hat;
|
|
||||||
delete[] calibration;
|
|
||||||
}
|
|
||||||
|
|
||||||
enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JoyDevice::add_event (unsigned int parameter, unsigned int state)
|
|
||||||
{
|
{
|
||||||
JoyEvent event = { parameter, state };
|
JoyEvent event = { parameter, state };
|
||||||
|
|
||||||
queue.push (event);
|
queue.push(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JoyDevice::register_centers ()
|
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);
|
calibration[i].center = SDL_JoystickGetAxis(filedes, i);
|
||||||
|
|
||||||
/* Snap centers to specific target points */
|
/* Snap centers to specific target points */
|
||||||
if (calibration[i].center < -24576)
|
if (calibration[i].center < -24576)
|
||||||
|
@ -629,7 +574,7 @@ void JoyDevice::register_centers ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JoyDevice::handle_event (SDL_Event *event)
|
void JoyDevice::handle_event(SDL_Event *event)
|
||||||
{
|
{
|
||||||
if (event->type == SDL_JOYAXISMOTION)
|
if (event->type == SDL_JOYAXISMOTION)
|
||||||
{
|
{
|
||||||
|
@ -644,20 +589,20 @@ void JoyDevice::handle_event (SDL_Event *event)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_JOYPADS; i++)
|
for (int i = 0; i < NUM_JOYPADS; i++)
|
||||||
{
|
{
|
||||||
Binding *pad = (Binding *) &(gui_config->pad[i]);
|
Binding *pad = (Binding *)&(gui_config->pad[i]);
|
||||||
|
|
||||||
for (int j = 0; j < NUM_JOYPAD_LINKS; j++)
|
for (int j = 0; j < NUM_JOYPAD_LINKS; j++)
|
||||||
{
|
{
|
||||||
if (pad[j].get_axis () == event->jaxis.axis &&
|
if (pad[j].get_axis() == event->jaxis.axis &&
|
||||||
pad[j].get_device () == (unsigned int) (joynum + 1))
|
pad[j].get_device() == (unsigned int)(joynum + 1))
|
||||||
{
|
{
|
||||||
t = pad[j].get_threshold ();
|
t = pad[j].get_threshold();
|
||||||
|
|
||||||
if (pad[j].is_positive ())
|
if (pad[j].is_positive())
|
||||||
{
|
{
|
||||||
ax_max = (cal_max - cal_cen) * t / 100 + cal_cen;
|
ax_max = (cal_max - cal_cen) * t / 100 + cal_cen;
|
||||||
}
|
}
|
||||||
else if (pad[j].is_negative ())
|
else if (pad[j].is_negative())
|
||||||
{
|
{
|
||||||
ax_min = (cal_min - cal_cen) * t / 100 + cal_cen;
|
ax_min = (cal_min - cal_cen) * t / 100 + cal_cen;
|
||||||
}
|
}
|
||||||
|
@ -667,16 +612,16 @@ void JoyDevice::handle_event (SDL_Event *event)
|
||||||
|
|
||||||
for (int i = 0; i < NUM_EMU_LINKS; i++)
|
for (int i = 0; i < NUM_EMU_LINKS; i++)
|
||||||
{
|
{
|
||||||
if (gui_config->shortcut[i].get_axis () == event->jaxis.axis &&
|
if (gui_config->shortcut[i].get_axis() == event->jaxis.axis &&
|
||||||
gui_config->shortcut[i].get_device () ==
|
gui_config->shortcut[i].get_device() ==
|
||||||
(unsigned int) (joynum + 1))
|
(unsigned int)(joynum + 1))
|
||||||
{
|
{
|
||||||
t = gui_config->shortcut[i].get_threshold ();
|
t = gui_config->shortcut[i].get_threshold();
|
||||||
if (gui_config->shortcut[i].is_positive ())
|
if (gui_config->shortcut[i].is_positive())
|
||||||
{
|
{
|
||||||
ax_max = (cal_max - cal_cen) * t / 100 + cal_cen;
|
ax_max = (cal_max - cal_cen) * t / 100 + cal_cen;
|
||||||
}
|
}
|
||||||
else if (gui_config->shortcut[i].is_negative ())
|
else if (gui_config->shortcut[i].is_negative())
|
||||||
{
|
{
|
||||||
ax_min = (cal_min - cal_cen) * t / 100 + cal_cen;
|
ax_min = (cal_min - cal_cen) * t / 100 + cal_cen;
|
||||||
}
|
}
|
||||||
|
@ -698,38 +643,37 @@ void JoyDevice::handle_event (SDL_Event *event)
|
||||||
ax_max = cal_cen + 1;
|
ax_max = cal_cen + 1;
|
||||||
|
|
||||||
if (event->jaxis.value <= ax_min &&
|
if (event->jaxis.value <= ax_min &&
|
||||||
axis[event->jaxis.axis] > ax_min)
|
axis[event->jaxis.axis] > ax_min)
|
||||||
{
|
{
|
||||||
add_event (JOY_AXIS (event->jaxis.axis, AXIS_NEG), 1);
|
add_event(JOY_AXIS(event->jaxis.axis, AXIS_NEG), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->jaxis.value > ax_min &&
|
if (event->jaxis.value > ax_min &&
|
||||||
axis[event->jaxis.axis] <= ax_min)
|
axis[event->jaxis.axis] <= ax_min)
|
||||||
{
|
{
|
||||||
add_event (JOY_AXIS (event->jaxis.axis, AXIS_NEG), 0);
|
add_event(JOY_AXIS(event->jaxis.axis, AXIS_NEG), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->jaxis.value >= ax_max &&
|
if (event->jaxis.value >= ax_max &&
|
||||||
axis[event->jaxis.axis] < ax_max)
|
axis[event->jaxis.axis] < ax_max)
|
||||||
{
|
{
|
||||||
add_event (JOY_AXIS (event->jaxis.axis, AXIS_POS), 1);
|
add_event(JOY_AXIS(event->jaxis.axis, AXIS_POS), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->jaxis.value < ax_max &&
|
if (event->jaxis.value < ax_max &&
|
||||||
axis[event->jaxis.axis] >= ax_max)
|
axis[event->jaxis.axis] >= ax_max)
|
||||||
{
|
{
|
||||||
add_event (JOY_AXIS (event->jaxis.axis, AXIS_POS), 0);
|
add_event(JOY_AXIS(event->jaxis.axis, AXIS_POS), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
axis[event->jaxis.axis] = event->jaxis.value;
|
axis[event->jaxis.axis] = event->jaxis.value;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (event->type == SDL_JOYBUTTONUP ||
|
else if (event->type == SDL_JOYBUTTONUP ||
|
||||||
event->type == SDL_JOYBUTTONDOWN)
|
event->type == SDL_JOYBUTTONDOWN)
|
||||||
{
|
{
|
||||||
add_event (event->jbutton.button,
|
add_event(event->jbutton.button,
|
||||||
event->jbutton.state == SDL_PRESSED ? 1 : 0);
|
event->jbutton.state == SDL_PRESSED ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (event->type == SDL_JOYHATMOTION)
|
else if (event->type == SDL_JOYHATMOTION)
|
||||||
|
@ -737,83 +681,83 @@ void JoyDevice::handle_event (SDL_Event *event)
|
||||||
if ((event->jhat.value & SDL_HAT_UP) &&
|
if ((event->jhat.value & SDL_HAT_UP) &&
|
||||||
!(hat[event->jhat.hat] & 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) &&
|
if (!(event->jhat.value & SDL_HAT_UP) &&
|
||||||
(hat[event->jhat.hat] & 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) &&
|
if ((event->jhat.value & SDL_HAT_DOWN) &&
|
||||||
!(hat[event->jhat.hat] & 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) &&
|
if (!(event->jhat.value & SDL_HAT_DOWN) &&
|
||||||
(hat[event->jhat.hat] & 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) &&
|
if ((event->jhat.value & SDL_HAT_LEFT) &&
|
||||||
!(hat[event->jhat.hat] & 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) &&
|
if (!(event->jhat.value & SDL_HAT_LEFT) &&
|
||||||
(hat[event->jhat.hat] & 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) &&
|
if ((event->jhat.value & SDL_HAT_RIGHT) &&
|
||||||
!(hat[event->jhat.hat] & 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) &&
|
if (!(event->jhat.value & SDL_HAT_RIGHT) &&
|
||||||
(hat[event->jhat.hat] & 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;
|
hat[event->jhat.hat] = event->jhat.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int JoyDevice::get_event (JoyEvent *event)
|
int JoyDevice::get_event(JoyEvent *event)
|
||||||
{
|
{
|
||||||
poll_events ();
|
poll_events();
|
||||||
|
|
||||||
if (queue.empty ())
|
if (queue.empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
event->parameter = queue.front ().parameter;
|
event->parameter = queue.front().parameter;
|
||||||
event->state = queue.front ().state;
|
event->state = queue.front().state;
|
||||||
|
|
||||||
queue.pop ();
|
queue.pop();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JoyDevice::poll_events ()
|
void JoyDevice::poll_events()
|
||||||
{
|
{
|
||||||
poll_joystick_events ();
|
poll_joystick_events();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JoyDevice::flush ()
|
void JoyDevice::flush()
|
||||||
{
|
{
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
|
||||||
while (SDL_PollEvent (&event))
|
while (SDL_PollEvent(&event))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!queue.empty ())
|
while (!queue.empty())
|
||||||
queue.pop ();
|
queue.pop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,21 +18,18 @@
|
||||||
|
|
||||||
const int NUM_JOYPADS = 10;
|
const int NUM_JOYPADS = 10;
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
JOY_MODE_GLOBAL = 0,
|
JOY_MODE_GLOBAL = 0,
|
||||||
JOY_MODE_INDIVIDUAL = 1,
|
JOY_MODE_INDIVIDUAL = 1,
|
||||||
JOY_MODE_CALIBRATE = 2
|
JOY_MODE_CALIBRATE = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
JOY_RELEASED = 0,
|
JOY_RELEASED = 0,
|
||||||
JOY_PRESSED = 1
|
JOY_PRESSED = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
PORT_COMMAND_FULLSCREEN = 1,
|
PORT_COMMAND_FULLSCREEN = 1,
|
||||||
PORT_COMMAND_SAVE_SPC = 2,
|
PORT_COMMAND_SAVE_SPC = 2,
|
||||||
PORT_OPEN_ROM = 3,
|
PORT_OPEN_ROM = 3,
|
||||||
|
@ -70,15 +67,15 @@ typedef struct BindingLink
|
||||||
extern const BindingLink b_links[];
|
extern const BindingLink b_links[];
|
||||||
extern const int b_breaks[];
|
extern const int b_breaks[];
|
||||||
const int NUM_JOYPAD_LINKS = 24;
|
const int NUM_JOYPAD_LINKS = 24;
|
||||||
const int NUM_EMU_LINKS = 62;
|
const int NUM_EMU_LINKS = 62;
|
||||||
|
|
||||||
typedef struct JoypadBinding
|
typedef struct JoypadBinding
|
||||||
{
|
{
|
||||||
std::array<Binding, NUM_JOYPAD_LINKS> data;
|
std::array<Binding, NUM_JOYPAD_LINKS> data;
|
||||||
} JoypadBinding;
|
} JoypadBinding;
|
||||||
|
|
||||||
bool S9xGrabJoysticks ();
|
bool S9xGrabJoysticks();
|
||||||
void S9xReleaseJoysticks ();
|
void S9xReleaseJoysticks();
|
||||||
|
|
||||||
typedef struct JoyEvent
|
typedef struct JoyEvent
|
||||||
{
|
{
|
||||||
|
@ -97,31 +94,30 @@ typedef struct Calibration
|
||||||
class JoyDevice
|
class JoyDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
JoyDevice (unsigned int device_num);
|
JoyDevice();
|
||||||
~JoyDevice ();
|
~JoyDevice();
|
||||||
int get_event (JoyEvent *event);
|
int get_event(JoyEvent *event);
|
||||||
void flush ();
|
void flush();
|
||||||
void handle_event (SDL_Event *event);
|
void handle_event(SDL_Event *event);
|
||||||
void register_centers ();
|
void register_centers();
|
||||||
|
bool set_sdl_joystick_num(unsigned int device_num);
|
||||||
|
|
||||||
SDL_Joystick *filedes;
|
SDL_Joystick *filedes;
|
||||||
Calibration *calibration;
|
|
||||||
std::queue<JoyEvent> queue;
|
std::queue<JoyEvent> queue;
|
||||||
int mode;
|
int mode;
|
||||||
int joynum;
|
int joynum;
|
||||||
int num_axes;
|
std::vector<Calibration> calibration;
|
||||||
int num_hats;
|
std::vector<int> axis;
|
||||||
int *axis;
|
std::vector<int> hat;
|
||||||
int *hat;
|
bool enabled;
|
||||||
bool enabled;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void poll_events ();
|
void poll_events();
|
||||||
void add_event (unsigned int parameter, unsigned int state);
|
void add_event(unsigned int parameter, unsigned int state);
|
||||||
};
|
};
|
||||||
|
|
||||||
void S9xDeinitInputDevices ();
|
void S9xDeinitInputDevices();
|
||||||
Binding S9xGetBindingByName (const char *name);
|
Binding S9xGetBindingByName(const char *name);
|
||||||
bool S9xIsMousePluggedIn ();
|
bool S9xIsMousePluggedIn();
|
||||||
|
|
||||||
#endif /* __GTK_CONTROL_H*/
|
#endif /* __GTK_CONTROL_H*/
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
For further information, consult the LICENSE file in the root directory.
|
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 <sched.h>
|
||||||
|
|
||||||
#include "gtk_s9x.h"
|
#include "gtk_s9x.h"
|
||||||
|
@ -12,6 +12,13 @@
|
||||||
#include "gtk_display_driver.h"
|
#include "gtk_display_driver.h"
|
||||||
#include "gtk_display_driver_gtk.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)
|
#if defined(USE_XV) && defined(GDK_WINDOWING_X11)
|
||||||
#include "gtk_display_driver_xv.h"
|
#include "gtk_display_driver_xv.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -1284,12 +1291,12 @@ void S9xDisplayReconfigure()
|
||||||
|
|
||||||
void S9xQueryDrivers()
|
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;
|
gui_config->allow_xv = false;
|
||||||
#if defined(USE_XV) && defined(GDK_WINDOWING_X11)
|
#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 ();
|
gui_config->allow_xv = S9xXVDisplayDriver::query_availability();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_OPENGL
|
#ifdef USE_OPENGL
|
||||||
|
@ -1300,10 +1307,10 @@ void S9xQueryDrivers()
|
||||||
|
|
||||||
gui_config->allow_xrandr = false;
|
gui_config->allow_xrandr = false;
|
||||||
#ifdef GDK_WINDOWING_X11
|
#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())));
|
Display *dpy = gdk_x11_display_get_xdisplay(gdk_display);
|
||||||
Window xid = gdk_x11_window_get_xid(gtk_widget_get_window(GTK_WIDGET(top_level->get_window())));
|
Window xid = gdk_x11_window_get_xid(top_level->window->get_window()->gobj());
|
||||||
|
|
||||||
gui_config->allow_xrandr = true;
|
gui_config->allow_xrandr = true;
|
||||||
gui_config->xrr_screen_resources = XRRGetScreenResourcesCurrent(dpy, xid);
|
gui_config->xrr_screen_resources = XRRGetScreenResourcesCurrent(dpy, xid);
|
||||||
|
@ -1397,31 +1404,29 @@ bool8 S9xDeinitUpdate(int width, int height)
|
||||||
|
|
||||||
static void S9xInitDriver()
|
static void S9xInitDriver()
|
||||||
{
|
{
|
||||||
|
// Only OpenGL is supported on Wayland
|
||||||
#ifdef GDK_WINDOWING_WAYLAND
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default()))
|
if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default()))
|
||||||
{
|
{
|
||||||
gui_config->hw_accel = HWA_OPENGL;
|
gui_config->hw_accel = HWA_OPENGL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (gui_config->hw_accel)
|
switch (gui_config->hw_accel)
|
||||||
{
|
{
|
||||||
#ifdef USE_OPENGL
|
#ifdef USE_OPENGL
|
||||||
case HWA_OPENGL:
|
case HWA_OPENGL:
|
||||||
|
driver = new S9xOpenGLDisplayDriver(top_level, gui_config);
|
||||||
driver = new S9xOpenGLDisplayDriver(top_level,
|
|
||||||
gui_config);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_XV) && defined(GDK_WINDOWING_X11)
|
#if defined(USE_XV) && defined(GDK_WINDOWING_X11)
|
||||||
case HWA_XV:
|
case HWA_XV:
|
||||||
|
|
||||||
driver = new S9xXVDisplayDriver(top_level, gui_config);
|
driver = new S9xXVDisplayDriver(top_level, gui_config);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
|
||||||
|
|
||||||
|
default:
|
||||||
driver = new S9xGTKDisplayDriver(top_level, gui_config);
|
driver = new S9xGTKDisplayDriver(top_level, gui_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1430,7 +1435,6 @@ static void S9xInitDriver()
|
||||||
if (gui_config->hw_accel > 0)
|
if (gui_config->hw_accel > 0)
|
||||||
{
|
{
|
||||||
delete driver;
|
delete driver;
|
||||||
|
|
||||||
gui_config->hw_accel = HWA_NONE;
|
gui_config->hw_accel = HWA_NONE;
|
||||||
|
|
||||||
S9xInitDriver();
|
S9xInitDriver();
|
||||||
|
@ -1452,7 +1456,8 @@ S9xDisplayDriver *S9xDisplayGetDriver()
|
||||||
|
|
||||||
void S9xDeinitDisplay()
|
void S9xDeinitDisplay()
|
||||||
{
|
{
|
||||||
driver->deinit();
|
if (driver)
|
||||||
|
driver->deinit();
|
||||||
delete driver;
|
delete driver;
|
||||||
|
|
||||||
if (pool)
|
if (pool)
|
||||||
|
|
|
@ -20,8 +20,7 @@
|
||||||
#include "filter_epx_unsafe.h"
|
#include "filter_epx_unsafe.h"
|
||||||
#include "filter/snes_ntsc.h"
|
#include "filter/snes_ntsc.h"
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
FILTER_NONE = 0,
|
FILTER_NONE = 0,
|
||||||
FILTER_SUPEREAGLE = 1,
|
FILTER_SUPEREAGLE = 1,
|
||||||
FILTER_2XSAI = 2,
|
FILTER_2XSAI = 2,
|
||||||
|
@ -42,21 +41,18 @@ enum
|
||||||
NUM_FILTERS = 17
|
NUM_FILTERS = 17
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
NTSC_COMPOSITE = 0,
|
NTSC_COMPOSITE = 0,
|
||||||
NTSC_SVIDEO = 1,
|
NTSC_SVIDEO = 1,
|
||||||
NTSC_RGB = 2
|
NTSC_RGB = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
ENDIAN_NORMAL = 0,
|
ENDIAN_NORMAL = 0,
|
||||||
ENDIAN_SWAPPED = 1
|
ENDIAN_SWAPPED = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
JOB_FILTER = 0,
|
JOB_FILTER = 0,
|
||||||
JOB_CONVERT = 1,
|
JOB_CONVERT = 1,
|
||||||
JOB_SCALE_AND_CONVERT = 2,
|
JOB_SCALE_AND_CONVERT = 2,
|
||||||
|
@ -81,52 +77,53 @@ typedef struct thread_job_t
|
||||||
volatile bool complete;
|
volatile bool complete;
|
||||||
} thread_job_t;
|
} thread_job_t;
|
||||||
|
|
||||||
struct S9xRect {
|
struct S9xRect
|
||||||
|
{
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
int w;
|
int w;
|
||||||
int h;
|
int h;
|
||||||
};
|
};
|
||||||
|
|
||||||
void S9xRegisterYUVTables (uint8 *y, uint8 *u, uint8 *v);
|
void S9xRegisterYUVTables(uint8 *y, uint8 *u, uint8 *v);
|
||||||
void S9xSetEndianess (int type);
|
void S9xSetEndianess(int type);
|
||||||
double S9xGetAspect ();
|
double S9xGetAspect();
|
||||||
S9xRect S9xApplyAspect (int, int, int, int);
|
S9xRect S9xApplyAspect(int, int, int, int);
|
||||||
void S9xConvertYUV (void *src_buffer,
|
void S9xConvertYUV(void *src_buffer,
|
||||||
void *dst_buffer,
|
void *dst_buffer,
|
||||||
|
int src_pitch,
|
||||||
|
int dst_pitch,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
void S9xConvert(void *src,
|
||||||
|
void *dst,
|
||||||
|
int src_pitch,
|
||||||
|
int dst_pitch,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int bpp);
|
||||||
|
void S9xConvertMask(void *src,
|
||||||
|
void *dst,
|
||||||
int src_pitch,
|
int src_pitch,
|
||||||
int dst_pitch,
|
int dst_pitch,
|
||||||
int width,
|
int width,
|
||||||
int height);
|
int height,
|
||||||
void S9xConvert (void *src,
|
int rshift,
|
||||||
void *dst,
|
int gshift,
|
||||||
int src_pitch,
|
int bshift,
|
||||||
int dst_pitch,
|
int bpp);
|
||||||
int width,
|
void S9xFilter(uint8 *src_buffer,
|
||||||
int height,
|
int src_pitch,
|
||||||
int bpp);
|
uint8 *dst_buffer,
|
||||||
void S9xConvertMask (void *src,
|
int dst_pitch,
|
||||||
void *dst,
|
int &width,
|
||||||
int src_pitch,
|
int &height);
|
||||||
int dst_pitch,
|
void get_filter_scale(int &width, int &height);
|
||||||
int width,
|
void S9xDisplayRefresh(int width, int height);
|
||||||
int height,
|
void S9xReinitDisplay();
|
||||||
int rshift,
|
void S9xDisplayReconfigure();
|
||||||
int gshift,
|
void S9xQueryDrivers();
|
||||||
int bshift,
|
S9xDisplayDriver *S9xDisplayGetDriver();
|
||||||
int bpp);
|
bool S9xDisplayDriverIsReady();
|
||||||
void S9xFilter (uint8 *src_buffer,
|
|
||||||
int src_pitch,
|
|
||||||
uint8 *dst_buffer,
|
|
||||||
int dst_pitch,
|
|
||||||
int& width,
|
|
||||||
int& height);
|
|
||||||
void get_filter_scale (int& width, int& height);
|
|
||||||
void S9xDisplayRefresh (int width, int height);
|
|
||||||
void S9xReinitDisplay ();
|
|
||||||
void S9xDisplayReconfigure ();
|
|
||||||
void S9xQueryDrivers ();
|
|
||||||
S9xDisplayDriver *S9xDisplayGetDriver ();
|
|
||||||
bool S9xDisplayDriverIsReady ();
|
|
||||||
|
|
||||||
#endif /* __GTK_DISPLAY_H */
|
#endif /* __GTK_DISPLAY_H */
|
||||||
|
|
|
@ -26,7 +26,7 @@ class S9xDisplayDriver
|
||||||
protected:
|
protected:
|
||||||
Snes9xWindow *window;
|
Snes9xWindow *window;
|
||||||
Snes9xConfig *config;
|
Snes9xConfig *config;
|
||||||
GtkWidget *drawing_area;
|
Gtk::DrawingArea *drawing_area;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __GTK_DISPLAY_DRIVER_H*/
|
#endif /* __GTK_DISPLAY_DRIVER_H*/
|
||||||
|
|
|
@ -4,29 +4,25 @@
|
||||||
For further information, consult the LICENSE file in the root directory.
|
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 <cairo.h>
|
||||||
#include "gtk_display.h"
|
#include "gtk_display.h"
|
||||||
#include "gtk_display_driver_gtk.h"
|
#include "gtk_display_driver_gtk.h"
|
||||||
|
#include "snes9x.h"
|
||||||
|
|
||||||
S9xGTKDisplayDriver::S9xGTKDisplayDriver(Snes9xWindow *window,
|
S9xGTKDisplayDriver::S9xGTKDisplayDriver(Snes9xWindow *window,
|
||||||
Snes9xConfig *config)
|
Snes9xConfig *config)
|
||||||
{
|
{
|
||||||
this->window = window;
|
this->window = window;
|
||||||
this->config = config;
|
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)
|
void S9xGTKDisplayDriver::update(uint16_t *buffer, int width, int height, int stride_in_pixels)
|
||||||
{
|
{
|
||||||
GtkAllocation allocation;
|
|
||||||
|
|
||||||
if (width <= 0)
|
if (width <= 0)
|
||||||
return;
|
return;
|
||||||
|
S9xRect dst = S9xApplyAspect(width, height, drawing_area->get_width(), drawing_area->get_height());
|
||||||
gtk_widget_get_allocation(drawing_area, &allocation);
|
|
||||||
|
|
||||||
S9xRect dst = S9xApplyAspect(width, height, allocation.width, allocation.height);
|
|
||||||
output(buffer, stride_in_pixels * 2, dst.x, dst.y, width, height, dst.w, dst.h);
|
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_t *cr = window->get_cairo();
|
||||||
|
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
|
|
||||||
surface = cairo_image_surface_create_for_data((unsigned char *)src, CAIRO_FORMAT_RGB16_565, width, height, src_pitch);
|
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()
|
void S9xGTKDisplayDriver::clear()
|
||||||
{
|
{
|
||||||
int width, height;
|
int width = drawing_area->get_width();
|
||||||
GtkAllocation allocation;
|
int height = drawing_area->get_height();
|
||||||
|
|
||||||
gtk_widget_get_allocation(drawing_area, &allocation);
|
|
||||||
width = allocation.width;
|
|
||||||
height = allocation.height;
|
|
||||||
|
|
||||||
cairo_t *cr = window->get_cairo();
|
cairo_t *cr = window->get_cairo();
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
For further information, consult the LICENSE file in the root directory.
|
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 <dlfcn.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -85,26 +85,23 @@ S9xOpenGLDisplayDriver::S9xOpenGLDisplayDriver(Snes9xWindow *window, Snes9xConfi
|
||||||
{
|
{
|
||||||
this->window = window;
|
this->window = window;
|
||||||
this->config = config;
|
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)
|
void S9xOpenGLDisplayDriver::update(uint16_t *buffer, int width, int height, int stride_in_pixels)
|
||||||
{
|
{
|
||||||
GtkAllocation allocation;
|
Gtk::Allocation allocation = drawing_area->get_allocation();
|
||||||
gtk_widget_get_allocation(drawing_area, &allocation);
|
|
||||||
|
|
||||||
if (output_window_width != allocation.width ||
|
if (output_window_width != allocation.get_width() ||
|
||||||
output_window_height != allocation.height)
|
output_window_height != allocation.get_height())
|
||||||
{
|
{
|
||||||
resize();
|
resize();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTK_CHECK_VERSION(3, 10, 0)
|
int scale_factor = drawing_area->get_scale_factor();
|
||||||
int gdk_scale_factor = gdk_window_get_scale_factor(gdk_window);
|
|
||||||
|
|
||||||
allocation.width *= gdk_scale_factor;
|
allocation.set_width(allocation.get_width() * scale_factor);
|
||||||
allocation.height *= gdk_scale_factor;
|
allocation.set_height(allocation.get_height() * scale_factor);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!legacy)
|
if (!legacy)
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
@ -118,8 +115,8 @@ void S9xOpenGLDisplayDriver::update(uint16_t *buffer, int width, int height, int
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
S9xRect content = S9xApplyAspect(width, height, allocation.width, allocation.height);
|
S9xRect content = S9xApplyAspect(width, height, allocation.get_width(), allocation.get_height());
|
||||||
glViewport(content.x, allocation.height - content.y - content.h, content.w, content.h);
|
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);
|
window->set_mouseable_area(content.x, content.y, content.w, content.h);
|
||||||
|
|
||||||
update_texture_size(width, height);
|
update_texture_size(width, height);
|
||||||
|
@ -183,7 +180,7 @@ void S9xOpenGLDisplayDriver::update(uint16_t *buffer, int width, int height, int
|
||||||
|
|
||||||
if (using_glsl_shaders)
|
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();
|
swap_buffers();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -468,24 +465,26 @@ void S9xOpenGLDisplayDriver::resize()
|
||||||
|
|
||||||
bool S9xOpenGLDisplayDriver::create_context()
|
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
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
if (GDK_IS_WAYLAND_WINDOW(gdk_window))
|
if (GDK_IS_WAYLAND_WINDOW(gdk_window))
|
||||||
{
|
{
|
||||||
|
if (!wl.attach(GTK_WIDGET(drawing_area->gobj())))
|
||||||
|
return false;
|
||||||
context = &wl;
|
context = &wl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef GDK_WINDOWING_X11
|
#ifdef GDK_WINDOWING_X11
|
||||||
if (GDK_IS_X11_WINDOW(gdk_window))
|
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;
|
context = &glx;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!context->attach(drawing_area))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!context->create_context())
|
if (!context->create_context())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#include "gtk_opengl_context.h"
|
#include "gtk_opengl_context.h"
|
||||||
|
|
||||||
#include "gtk_2_3_compat.h"
|
#include "gtk_compat.h"
|
||||||
#ifdef GDK_WINDOWING_X11
|
#ifdef GDK_WINDOWING_X11
|
||||||
#include "gtk_glx_context.h"
|
#include "gtk_glx_context.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
For further information, consult the LICENSE file in the root directory.
|
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/XShm.h>
|
||||||
#include <X11/extensions/Xv.h>
|
#include <X11/extensions/Xv.h>
|
||||||
#include <X11/extensions/Xvlib.h>
|
#include <X11/extensions/Xvlib.h>
|
||||||
|
@ -31,15 +31,14 @@ static int get_inv_shift(uint32 mask, int bpp)
|
||||||
return (bpp - i);
|
return (bpp - i);
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xXVDisplayDriver::S9xXVDisplayDriver(Snes9xWindow *window,
|
S9xXVDisplayDriver::S9xXVDisplayDriver(Snes9xWindow *window, Snes9xConfig *config)
|
||||||
Snes9xConfig *config)
|
|
||||||
{
|
{
|
||||||
this->window = window;
|
this->window = window;
|
||||||
this->config = config;
|
this->config = config;
|
||||||
this->drawing_area = GTK_WIDGET(window->drawing_area);
|
this->drawing_area = window->drawing_area;
|
||||||
display =
|
display = gdk_x11_display_get_xdisplay(drawing_area->get_display()->gobj());
|
||||||
gdk_x11_display_get_xdisplay(gtk_widget_get_display(drawing_area));
|
last_known_width = -1;
|
||||||
last_known_width = last_known_height = -1;
|
last_known_height = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xXVDisplayDriver::resize_window(int width, int height)
|
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.y = 0;
|
||||||
window_attr.wclass = GDK_INPUT_OUTPUT;
|
window_attr.wclass = GDK_INPUT_OUTPUT;
|
||||||
window_attr.window_type = GDK_WINDOW_CHILD;
|
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,
|
&window_attr,
|
||||||
GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL);
|
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);
|
gdk_window_show(gdk_window);
|
||||||
xwindow = gdk_x11_window_get_xid(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)
|
void S9xXVDisplayDriver::update(uint16_t *buffer, int width, int height, int stride_in_pixels)
|
||||||
{
|
{
|
||||||
int current_width, current_height;
|
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 ||
|
if (output_window_width != allocation.get_width() ||
|
||||||
output_window_height != allocation.height)
|
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 scale_factor = drawing_area->get_scale_factor();
|
||||||
int gdk_scale_factor = gdk_window_get_scale_factor(gdk_window);
|
|
||||||
|
|
||||||
allocation.width *= gdk_scale_factor;
|
allocation.set_width(allocation.get_width() * scale_factor);
|
||||||
allocation.height *= gdk_scale_factor;
|
allocation.set_height(allocation.get_height() * scale_factor);
|
||||||
|
|
||||||
#endif
|
current_width = allocation.get_width();
|
||||||
|
current_height = allocation.get_height();
|
||||||
current_width = allocation.width;
|
|
||||||
current_height = allocation.height;
|
|
||||||
|
|
||||||
update_image_size(width, height);
|
update_image_size(width, height);
|
||||||
|
|
||||||
|
@ -178,7 +174,7 @@ void S9xXVDisplayDriver::update_image_size(int width, int height)
|
||||||
{
|
{
|
||||||
/* Can't recover, send exit. */
|
/* Can't recover, send exit. */
|
||||||
fprintf(stderr, "Couldn't reallocate shared memory.\n");
|
fprintf(stderr, "Couldn't reallocate shared memory.\n");
|
||||||
S9xExit();
|
exit(1);
|
||||||
}
|
}
|
||||||
else if (shm.shmaddr != (void *)-1)
|
else if (shm.shmaddr != (void *)-1)
|
||||||
{
|
{
|
||||||
|
@ -209,10 +205,10 @@ int S9xXVDisplayDriver::init()
|
||||||
GdkWindow *root;
|
GdkWindow *root;
|
||||||
|
|
||||||
/* Setup XV */
|
/* 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));
|
display = gdk_x11_display_get_xdisplay(drawing_area->get_display()->gobj());
|
||||||
screen = gtk_widget_get_screen(drawing_area);
|
screen = drawing_area->get_screen()->gobj();
|
||||||
root = gdk_screen_get_root_window(screen);
|
root = gdk_screen_get_root_window(screen);
|
||||||
|
|
||||||
xv_portid = -1;
|
xv_portid = -1;
|
||||||
|
@ -391,7 +387,7 @@ int S9xXVDisplayDriver::init()
|
||||||
}
|
}
|
||||||
|
|
||||||
xcolormap = XCreateColormap(display,
|
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,
|
vi->visual,
|
||||||
AllocNone);
|
AllocNone);
|
||||||
|
|
||||||
|
@ -443,20 +439,10 @@ void S9xXVDisplayDriver::deinit()
|
||||||
|
|
||||||
void S9xXVDisplayDriver::clear()
|
void S9xXVDisplayDriver::clear()
|
||||||
{
|
{
|
||||||
int width, height;
|
|
||||||
GtkAllocation allocation;
|
|
||||||
GC xgc = XDefaultGC(display, XDefaultScreen(display));
|
GC xgc = XDefaultGC(display, XDefaultScreen(display));
|
||||||
|
|
||||||
gtk_widget_get_allocation(drawing_area, &allocation);
|
int width = drawing_area->get_width() * drawing_area->get_scale_factor();
|
||||||
#if GTK_CHECK_VERSION(3, 10, 0)
|
int height = drawing_area->get_height() * drawing_area->get_scale_factor();
|
||||||
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;
|
|
||||||
|
|
||||||
if (window->last_width <= 0 || window->last_height <= 0)
|
if (window->last_width <= 0 || window->last_height <= 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,14 +7,14 @@
|
||||||
#ifndef __GTK_DISPLAY_DRIVER_XV_H
|
#ifndef __GTK_DISPLAY_DRIVER_XV_H
|
||||||
#define __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/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <X11/extensions/XShm.h>
|
#include <X11/extensions/XShm.h>
|
||||||
#include <X11/extensions/Xvlib.h>
|
#include <X11/extensions/Xvlib.h>
|
||||||
|
|
||||||
#include "gtk_s9x.h"
|
|
||||||
#include "gtk_display_driver.h"
|
|
||||||
|
|
||||||
const uint32 FOURCC_YUY2 = 0x32595559;
|
const uint32 FOURCC_YUY2 = 0x32595559;
|
||||||
|
|
||||||
class S9xXVDisplayDriver : public S9xDisplayDriver
|
class S9xXVDisplayDriver : public S9xDisplayDriver
|
||||||
|
|
|
@ -7,27 +7,29 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "gtk_2_3_compat.h"
|
#include "gtk_compat.h"
|
||||||
#include "gtk_s9x.h"
|
#include "gtk_s9x.h"
|
||||||
|
#include "display.h"
|
||||||
|
#include "memmap.h"
|
||||||
|
#include "snapshot.h"
|
||||||
|
#include "cheats.h"
|
||||||
|
|
||||||
static char buf[PATH_MAX];
|
static char buf[PATH_MAX];
|
||||||
|
|
||||||
const char *
|
const char *S9xChooseMovieFilename(bool8 read_only)
|
||||||
S9xChooseMovieFilename (bool8 read_only)
|
|
||||||
{
|
{
|
||||||
static char path[PATH_MAX];
|
static char path[PATH_MAX];
|
||||||
|
|
||||||
if (!gui_config->rom_loaded)
|
if (!gui_config->rom_loaded)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
const char *str = top_level->open_movie_dialog (read_only);
|
auto filename = top_level->open_movie_dialog(read_only);
|
||||||
strcpy (path, str);
|
strcpy(path, filename.c_str());
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *S9xChooseFilename(bool8 read_only)
|
||||||
S9xChooseFilename (bool8 read_only)
|
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -37,11 +39,10 @@ S9xChooseFilename (bool8 read_only)
|
||||||
#define SLASH_CHAR '/'
|
#define SLASH_CHAR '/'
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void _splitpath(const char *path, char *drive, char *dir, char *fname, char *ext)
|
||||||
_splitpath (const char *path, char *drive, char *dir, char *fname, char *ext)
|
|
||||||
{
|
{
|
||||||
char *slash = strrchr ((char *) path, SLASH_CHAR);
|
char *slash = strrchr((char *)path, SLASH_CHAR);
|
||||||
char *dot = strrchr ((char *) path, '.');
|
char *dot = strrchr((char *)path, '.');
|
||||||
|
|
||||||
*drive = '\0';
|
*drive = '\0';
|
||||||
|
|
||||||
|
@ -53,12 +54,12 @@ _splitpath (const char *path, char *drive, char *dir, char *fname, char *ext)
|
||||||
if (!slash)
|
if (!slash)
|
||||||
{
|
{
|
||||||
*dir = '\0';
|
*dir = '\0';
|
||||||
strcpy (fname, path);
|
strcpy(fname, path);
|
||||||
|
|
||||||
if (dot)
|
if (dot)
|
||||||
{
|
{
|
||||||
fname[dot - path] = '\0';
|
fname[dot - path] = '\0';
|
||||||
strcpy (ext, dot + 1);
|
strcpy(ext, dot + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -67,14 +68,14 @@ _splitpath (const char *path, char *drive, char *dir, char *fname, char *ext)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strcpy (dir, path);
|
strcpy(dir, path);
|
||||||
dir[slash - path] = '\0';
|
dir[slash - path] = '\0';
|
||||||
strcpy (fname, slash + 1);
|
strcpy(fname, slash + 1);
|
||||||
|
|
||||||
if (dot)
|
if (dot)
|
||||||
{
|
{
|
||||||
fname[(dot - slash) - 1] = '\0';
|
fname[(dot - slash) - 1] = '\0';
|
||||||
strcpy (ext, dot + 1);
|
strcpy(ext, dot + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -83,57 +84,49 @@ _splitpath (const char *path, char *drive, char *dir, char *fname, char *ext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void _makepath(char *path, const char *drive, const char *dir, const char *fname, const char *ext)
|
||||||
_makepath (char *path,
|
|
||||||
const char *drive,
|
|
||||||
const char *dir,
|
|
||||||
const char *fname,
|
|
||||||
const char *ext)
|
|
||||||
{
|
{
|
||||||
if (dir && *dir)
|
if (dir && *dir)
|
||||||
{
|
{
|
||||||
strcpy (path, dir);
|
strcpy(path, dir);
|
||||||
strcat (path, "/");
|
strcat(path, "/");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*path = '\0';
|
*path = '\0';
|
||||||
|
|
||||||
strcat (path, fname);
|
strcat(path, fname);
|
||||||
|
|
||||||
if (ext && *ext)
|
if (ext && *ext)
|
||||||
{
|
{
|
||||||
strcat (path, ".");
|
strcat(path, ".");
|
||||||
strcat (path, ext);
|
strcat(path, ext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *S9xGetFilenameInc(const char *e, enum s9x_getdirtype dirtype)
|
||||||
S9xGetFilenameInc (const char *e, enum s9x_getdirtype dirtype)
|
|
||||||
{
|
{
|
||||||
static char filename[PATH_MAX + 1];
|
static char filename[PATH_MAX + 1];
|
||||||
char dir[_MAX_DIR + 1];
|
char dir[_MAX_DIR + 1];
|
||||||
char drive[_MAX_DRIVE + 1];
|
char drive[_MAX_DRIVE + 1];
|
||||||
char fname[_MAX_FNAME + 1];
|
char fname[_MAX_FNAME + 1];
|
||||||
char ext[_MAX_EXT + 1];
|
char ext[_MAX_EXT + 1];
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
const char *d;
|
const char *d;
|
||||||
|
|
||||||
_splitpath (Memory.ROMFilename, drive, dir, fname, ext);
|
_splitpath(Memory.ROMFilename, drive, dir, fname, ext);
|
||||||
d = S9xGetDirectory (dirtype);
|
d = S9xGetDirectory(dirtype);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
snprintf (filename, PATH_MAX, "%s" SLASH_STR "%s%03d%s", d, fname, i, e);
|
snprintf(filename, PATH_MAX, "%s" SLASH_STR "%s%03d%s", d, fname, i, e);
|
||||||
i++;
|
i++;
|
||||||
}
|
} while (stat(filename, &buf) == 0 && i != 0); /* Overflow? ...riiight :-) */
|
||||||
while (stat (filename, &buf) == 0 && i != 0); /* Overflow? ...riiight :-) */
|
|
||||||
|
|
||||||
return (filename);
|
return (filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *S9xGetDirectory(enum s9x_getdirtype dirtype)
|
||||||
S9xGetDirectory (enum s9x_getdirtype dirtype)
|
|
||||||
{
|
{
|
||||||
static char path[PATH_MAX + 1];
|
static char path[PATH_MAX + 1];
|
||||||
|
|
||||||
|
@ -187,15 +180,15 @@ S9xGetDirectory (enum s9x_getdirtype dirtype)
|
||||||
{
|
{
|
||||||
char *loc;
|
char *loc;
|
||||||
|
|
||||||
strcpy (path, Memory.ROMFilename);
|
strcpy(path, Memory.ROMFilename);
|
||||||
|
|
||||||
loc = strrchr (path, SLASH_CHAR);
|
loc = strrchr(path, SLASH_CHAR);
|
||||||
|
|
||||||
if (loc == NULL)
|
if (loc == NULL)
|
||||||
{
|
{
|
||||||
if (getcwd (path, PATH_MAX + 1) == NULL)
|
if (getcwd(path, PATH_MAX + 1) == NULL)
|
||||||
{
|
{
|
||||||
strcpy (path, getenv ("HOME"));
|
strcpy(path, getenv("HOME"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -207,279 +200,197 @@ S9xGetDirectory (enum s9x_getdirtype dirtype)
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *S9xGetFilename(const char *ex, enum s9x_getdirtype dirtype)
|
||||||
S9xGetFilename (const char *ex, enum s9x_getdirtype dirtype)
|
|
||||||
{
|
{
|
||||||
static char filename[PATH_MAX + 1];
|
static char filename[PATH_MAX + 1];
|
||||||
char dir[_MAX_DIR + 1];
|
char dir[_MAX_DIR + 1];
|
||||||
char drive[_MAX_DRIVE + 1];
|
char drive[_MAX_DRIVE + 1];
|
||||||
char fname[_MAX_FNAME + 1];
|
char fname[_MAX_FNAME + 1];
|
||||||
char ext[_MAX_EXT + 1];
|
char ext[_MAX_EXT + 1];
|
||||||
|
|
||||||
_splitpath (Memory.ROMFilename, drive, dir, fname, ext);
|
_splitpath(Memory.ROMFilename, drive, dir, fname, ext);
|
||||||
|
|
||||||
snprintf (filename, sizeof (filename), "%s" SLASH_STR "%s%s",
|
snprintf(filename, sizeof(filename), "%s" SLASH_STR "%s%s",
|
||||||
S9xGetDirectory (dirtype), fname, ex);
|
S9xGetDirectory(dirtype), fname, ex);
|
||||||
|
|
||||||
return (filename);
|
return (filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *S9xBasename(const char *f)
|
||||||
S9xBasename (const char *f)
|
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
if ((p = strrchr (f, '/')) != NULL || (p = strrchr (f, '\\')) != NULL)
|
if ((p = strrchr(f, '/')) != NULL || (p = strrchr(f, '\\')) != NULL)
|
||||||
return (p + 1);
|
return (p + 1);
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *S9xBasenameNoExt(const char *f)
|
||||||
S9xBasenameNoExt (const char *f)
|
|
||||||
{
|
{
|
||||||
static char filename[PATH_MAX];
|
static char filename[PATH_MAX];
|
||||||
const char *base, *ext;
|
const char *base, *ext;
|
||||||
|
|
||||||
if (!(base = strrchr (f, SLASH_CHAR)))
|
if (!(base = strrchr(f, SLASH_CHAR)))
|
||||||
base = f;
|
base = f;
|
||||||
else
|
else
|
||||||
base += 1;
|
base += 1;
|
||||||
|
|
||||||
ext = strrchr (f, '.');
|
ext = strrchr(f, '.');
|
||||||
|
|
||||||
if (!ext)
|
if (!ext)
|
||||||
snprintf (filename, PATH_MAX, "%s", base);
|
snprintf(filename, PATH_MAX, "%s", base);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int len = ext - base;
|
int len = ext - base;
|
||||||
strncpy (filename, base, len);
|
strncpy(filename, base, len);
|
||||||
filename[len] = '\0';
|
filename[len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int file_exists(const char *name)
|
||||||
file_exists (const char *name)
|
|
||||||
{
|
{
|
||||||
FILE *f = NULL;
|
FILE *f = NULL;
|
||||||
|
|
||||||
f = fopen (name, "r");
|
f = fopen(name, "r");
|
||||||
|
|
||||||
if (!f)
|
if (!f)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fclose (f);
|
fclose(f);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool8
|
bool8 S9xOpenSnapshotFile(const char *fname, bool8 read_only, STREAM *file)
|
||||||
S9xOpenSnapshotFile (const char *fname, bool8 read_only, STREAM *file)
|
|
||||||
{
|
{
|
||||||
char filename [PATH_MAX + 1];
|
char filename[PATH_MAX + 1];
|
||||||
char drive [_MAX_DRIVE + 1];
|
char drive[_MAX_DRIVE + 1];
|
||||||
char dir [_MAX_DIR + 1];
|
char dir[_MAX_DIR + 1];
|
||||||
char ext [_MAX_EXT + 1];
|
char ext[_MAX_EXT + 1];
|
||||||
|
|
||||||
_splitpath (fname, drive, dir, filename, ext);
|
_splitpath(fname, drive, dir, filename, ext);
|
||||||
|
|
||||||
if (*drive || *dir == '/' || (*dir == '.' && (*(dir + 1) == '/')))
|
if (*drive || *dir == '/' || (*dir == '.' && (*(dir + 1) == '/')))
|
||||||
{
|
{
|
||||||
snprintf (filename, PATH_MAX + 1, "%s", fname);
|
snprintf(filename, PATH_MAX + 1, "%s", fname);
|
||||||
|
|
||||||
if (!file_exists (filename))
|
if (!file_exists(filename))
|
||||||
{
|
{
|
||||||
if (!*ext)
|
if (!*ext)
|
||||||
strcat (filename, ".s9x");
|
strcat(filename, ".s9x");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strcpy (filename, S9xGetDirectory (SNAPSHOT_DIR));
|
strcpy(filename, S9xGetDirectory(SNAPSHOT_DIR));
|
||||||
strcat (filename, SLASH_STR);
|
strcat(filename, SLASH_STR);
|
||||||
strcat (filename, fname);
|
strcat(filename, fname);
|
||||||
|
|
||||||
if (!file_exists (filename))
|
if (!file_exists(filename))
|
||||||
{
|
{
|
||||||
if (!*ext)
|
if (!*ext)
|
||||||
strcat (filename, ".s9x");
|
strcat(filename, ".s9x");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ZLIB
|
#ifdef ZLIB
|
||||||
if (read_only)
|
if (read_only)
|
||||||
{
|
{
|
||||||
if ((*file = OPEN_STREAM (filename, "rb")))
|
if ((*file = OPEN_STREAM(filename, "rb")))
|
||||||
return (true);
|
return (true);
|
||||||
else
|
else
|
||||||
fprintf (stderr,
|
fprintf(stderr,
|
||||||
"Failed to open file stream for reading. (%s)\n",
|
"Failed to open file stream for reading. (%s)\n",
|
||||||
zError (errno));
|
zError(errno));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((*file = OPEN_STREAM (filename, "wb")))
|
if ((*file = OPEN_STREAM(filename, "wb")))
|
||||||
{
|
{
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf (stderr,
|
fprintf(stderr,
|
||||||
"Couldn't open stream with zlib. (%s)\n",
|
"Couldn't open stream with zlib. (%s)\n",
|
||||||
zError (errno));
|
zError(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (stderr, "zlib: Couldn't open snapshot file:\n%s\n", filename);
|
fprintf(stderr, "zlib: Couldn't open snapshot file:\n%s\n", filename);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
char command [PATH_MAX];
|
char command[PATH_MAX];
|
||||||
|
|
||||||
if (read_only)
|
if (read_only)
|
||||||
{
|
{
|
||||||
sprintf (command, "gzip -d <\"%s\"", filename);
|
sprintf(command, "gzip -d <\"%s\"", filename);
|
||||||
if (*file = popen (command, "r"))
|
if (*file = popen(command, "r"))
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf (command, "gzip --best >\"%s\"", filename);
|
sprintf(command, "gzip --best >\"%s\"", filename);
|
||||||
if (*file = popen (command, "wb"))
|
if (*file = popen(command, "wb"))
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (stderr, "gzip: Couldn't open snapshot file:\n%s\n", filename);
|
fprintf(stderr, "gzip: Couldn't open snapshot file:\n%s\n", filename);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xCloseSnapshotFile (STREAM file)
|
void S9xCloseSnapshotFile(STREAM file)
|
||||||
{
|
{
|
||||||
#ifdef ZLIB
|
#ifdef ZLIB
|
||||||
CLOSE_STREAM (file);
|
CLOSE_STREAM(file);
|
||||||
#else
|
#else
|
||||||
pclose (file);
|
pclose(file);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void S9xAutoSaveSRAM()
|
||||||
S9xAutoSaveSRAM ()
|
|
||||||
{
|
{
|
||||||
Memory.SaveSRAM (S9xGetFilename (".srm", SRAM_DIR));
|
Memory.SaveSRAM(S9xGetFilename(".srm", SRAM_DIR));
|
||||||
S9xSaveCheatFile (S9xGetFilename (".cht", CHEAT_DIR));
|
S9xSaveCheatFile(S9xGetFilename(".cht", CHEAT_DIR));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void S9xLoadState(const char *filename)
|
||||||
S9xLoadState (const char *filename)
|
|
||||||
{
|
{
|
||||||
S9xFreezeGame (S9xGetFilename (".undo", SNAPSHOT_DIR));
|
S9xFreezeGame(S9xGetFilename(".undo", SNAPSHOT_DIR));
|
||||||
|
|
||||||
if (S9xUnfreezeGame (filename))
|
if (S9xUnfreezeGame(filename))
|
||||||
{
|
{
|
||||||
sprintf (buf, "%s loaded", filename);
|
sprintf(buf, "%s loaded", filename);
|
||||||
S9xSetInfoString (buf);
|
S9xSetInfoString(buf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Failed to load state file: %s\n", filename);
|
fprintf(stderr, "Failed to load state file: %s\n", filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void S9xSaveState(const char *filename)
|
||||||
S9xSaveState (const char *filename)
|
|
||||||
{
|
{
|
||||||
if (S9xFreezeGame (filename))
|
if (S9xFreezeGame(filename))
|
||||||
{
|
{
|
||||||
sprintf (buf, "%s saved", filename);
|
sprintf(buf, "%s saved", filename);
|
||||||
S9xSetInfoString (buf);
|
S9xSetInfoString(buf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Couldn't save state file: %s\n", filename);
|
fprintf(stderr, "Couldn't save state file: %s\n", 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 */
|
/* QuickSave/Load from S9x base controls.cpp */
|
||||||
void
|
void S9xQuickSaveSlot(int slot)
|
||||||
S9xQuickSaveSlot (int slot)
|
|
||||||
{
|
{
|
||||||
char def[PATH_MAX];
|
char def[PATH_MAX];
|
||||||
char filename[PATH_MAX];
|
char filename[PATH_MAX];
|
||||||
|
@ -490,21 +401,21 @@ S9xQuickSaveSlot (int slot)
|
||||||
if (!gui_config->rom_loaded)
|
if (!gui_config->rom_loaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_splitpath (Memory.ROMFilename, drive, dir, def, ext);
|
_splitpath(Memory.ROMFilename, drive, dir, def, ext);
|
||||||
|
|
||||||
snprintf (filename, PATH_MAX, "%s%s%s.%03d",
|
snprintf(filename, PATH_MAX, "%s%s%s.%03d",
|
||||||
S9xGetDirectory (SNAPSHOT_DIR), SLASH_STR, def,
|
S9xGetDirectory(SNAPSHOT_DIR), SLASH_STR, def,
|
||||||
slot);
|
slot);
|
||||||
|
|
||||||
if (S9xFreezeGame (filename))
|
if (S9xFreezeGame(filename))
|
||||||
{
|
{
|
||||||
snprintf (buf, PATH_MAX, "%s.%03d saved", def, slot);
|
snprintf(buf, PATH_MAX, "%s.%03d saved", def, slot);
|
||||||
|
|
||||||
S9xSetInfoString (buf);
|
S9xSetInfoString(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xQuickLoadSlot (int slot)
|
void S9xQuickLoadSlot(int slot)
|
||||||
{
|
{
|
||||||
char def[PATH_MAX];
|
char def[PATH_MAX];
|
||||||
char filename[PATH_MAX];
|
char filename[PATH_MAX];
|
||||||
|
@ -515,44 +426,43 @@ void S9xQuickLoadSlot (int slot)
|
||||||
if (!gui_config->rom_loaded)
|
if (!gui_config->rom_loaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_splitpath (Memory.ROMFilename, drive, dir, def, ext);
|
_splitpath(Memory.ROMFilename, drive, dir, def, ext);
|
||||||
|
|
||||||
snprintf (filename, PATH_MAX, "%s%s%s.%03d",
|
snprintf(filename, PATH_MAX, "%s%s%s.%03d",
|
||||||
S9xGetDirectory (SNAPSHOT_DIR), SLASH_STR, def,
|
S9xGetDirectory(SNAPSHOT_DIR), SLASH_STR, def,
|
||||||
slot);
|
slot);
|
||||||
|
|
||||||
if (file_exists (filename))
|
if (file_exists(filename))
|
||||||
S9xFreezeGame (S9xGetFilename (".undo", SNAPSHOT_DIR));
|
S9xFreezeGame(S9xGetFilename(".undo", SNAPSHOT_DIR));
|
||||||
|
|
||||||
if (S9xUnfreezeGame (filename))
|
if (S9xUnfreezeGame(filename))
|
||||||
{
|
{
|
||||||
snprintf (buf, PATH_MAX, "%s.%03d loaded", def, slot);
|
snprintf(buf, PATH_MAX, "%s.%03d loaded", def, slot);
|
||||||
S9xSetInfoString (buf);
|
S9xSetInfoString(buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *digits = "t123456789";
|
static const char *digits = "t123456789";
|
||||||
|
|
||||||
_splitpath (Memory.ROMFilename, drive, dir, def, ext);
|
_splitpath(Memory.ROMFilename, drive, dir, def, ext);
|
||||||
|
|
||||||
snprintf (filename, PATH_MAX, "%s%s%s.zs%c",
|
snprintf(filename, PATH_MAX, "%s%s%s.zs%c",
|
||||||
S9xGetDirectory (SNAPSHOT_DIR), SLASH_STR,
|
S9xGetDirectory(SNAPSHOT_DIR), SLASH_STR,
|
||||||
def, digits[slot]);
|
def, digits[slot]);
|
||||||
|
|
||||||
if (file_exists (filename))
|
if (file_exists(filename))
|
||||||
S9xFreezeGame (S9xGetFilename (".undo", SNAPSHOT_DIR));
|
S9xFreezeGame(S9xGetFilename(".undo", SNAPSHOT_DIR));
|
||||||
|
|
||||||
if (S9xUnfreezeGame (filename))
|
if (S9xUnfreezeGame(filename))
|
||||||
{
|
{
|
||||||
snprintf (buf, PATH_MAX,
|
snprintf(buf, PATH_MAX,
|
||||||
"Loaded ZSNES freeze file %s.zs%c",
|
"Loaded ZSNES freeze file %s.zs%c",
|
||||||
def, digits [slot]);
|
def, digits[slot]);
|
||||||
S9xSetInfoString (buf);
|
S9xSetInfoString(buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xMessage (S9X_ERROR,
|
S9xMessage(S9X_ERROR,
|
||||||
S9X_FREEZE_FILE_NOT_FOUND,
|
S9X_FREEZE_FILE_NOT_FOUND,
|
||||||
"Freeze file not found");
|
"Freeze file not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,12 @@
|
||||||
#ifndef __GTK_FILE_H
|
#ifndef __GTK_FILE_H
|
||||||
#define __GTK_FILE_H
|
#define __GTK_FILE_H
|
||||||
|
|
||||||
char *S9xOpenROMDialog ();
|
const char *S9xBasenameNoExt(const char *);
|
||||||
const char *S9xBasenameNoExt (const char *);
|
|
||||||
|
|
||||||
void S9xLoadState (const char *filename);
|
void S9xLoadState(const char *filename);
|
||||||
void S9xSaveState (const char *filename);
|
void S9xSaveState(const char *filename);
|
||||||
|
|
||||||
void S9xQuickSaveSlot (int slot);
|
void S9xQuickSaveSlot(int slot);
|
||||||
void S9xQuickLoadSlot (int slot);
|
void S9xQuickLoadSlot(int slot);
|
||||||
|
|
||||||
#endif /* __GTK_FILE_H */
|
#endif /* __GTK_FILE_H */
|
||||||
|
|
|
@ -6,99 +6,61 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "gtk_s9x.h"
|
#include "gtk_s9x.h"
|
||||||
#include "gtk_glx_context.h"
|
#include "gtk_glx_context.h"
|
||||||
#include "gtk_2_3_compat.h"
|
|
||||||
|
|
||||||
GTKGLXContext::GTKGLXContext ()
|
GTKGLXContext::GTKGLXContext()
|
||||||
{
|
{
|
||||||
gdk_display = NULL;
|
display = NULL;
|
||||||
parent_gdk_window = NULL;
|
context = NULL;
|
||||||
gdk_window = NULL;
|
|
||||||
display = NULL;
|
|
||||||
vi = NULL;
|
|
||||||
context = NULL;
|
|
||||||
|
|
||||||
version_major = -1;
|
version_major = -1;
|
||||||
version_minor = -1;
|
version_minor = -1;
|
||||||
use_oml_sync_control = false;
|
use_oml_sync_control = false;
|
||||||
ust = msc = sbc = 0;
|
ust = msc = sbc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GTKGLXContext::~GTKGLXContext ()
|
GTKGLXContext::~GTKGLXContext()
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
glXDestroyContext (display, 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;
|
GLXFBConfig *fbconfigs;
|
||||||
int num_fbconfigs;
|
int num_fbconfigs;
|
||||||
|
|
||||||
int attribs[] = {
|
int attribs[] = {
|
||||||
GLX_DOUBLEBUFFER, True,
|
GLX_DOUBLEBUFFER, True,
|
||||||
GLX_X_RENDERABLE, True,
|
GLX_X_RENDERABLE, True,
|
||||||
GLX_RED_SIZE, 8,
|
GLX_RED_SIZE, 8,
|
||||||
GLX_GREEN_SIZE, 8,
|
GLX_GREEN_SIZE, 8,
|
||||||
GLX_BLUE_SIZE, 8,
|
GLX_BLUE_SIZE, 8,
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
window = gtk_widget_get_window (widget);
|
this->xid = xid;
|
||||||
this->widget = widget;
|
display = dpy;
|
||||||
|
|
||||||
if (!GDK_IS_X11_WINDOW (window))
|
glXQueryVersion(display, &version_major, &version_minor);
|
||||||
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);
|
|
||||||
|
|
||||||
glXQueryVersion (display, &version_major, &version_minor);
|
|
||||||
if (version_major < 2 && version_minor < 3)
|
if (version_major < 2 && version_minor < 3)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fbconfigs = glXChooseFBConfig (display, screen, attribs, &num_fbconfigs);
|
fbconfigs = glXChooseFBConfig(display, screen, attribs, &num_fbconfigs);
|
||||||
if (!fbconfigs || num_fbconfigs < 1)
|
if (!fbconfigs || num_fbconfigs < 1)
|
||||||
{
|
{
|
||||||
printf ("Couldn't match a GLX framebuffer config.\n");
|
printf("Couldn't match a GLX framebuffer config.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fbconfig = fbconfigs[0];
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GTKGLXContext::create_context ()
|
bool GTKGLXContext::create_context()
|
||||||
{
|
{
|
||||||
int context_attribs[] = {
|
int context_attribs[] = {
|
||||||
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||||
|
@ -107,18 +69,21 @@ bool GTKGLXContext::create_context ()
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *extensions = glXQueryExtensionsString (display, screen);
|
const char *extensions = glXQueryExtensionsString(display, screen);
|
||||||
|
|
||||||
gdk_x11_display_error_trap_push(gdk_display);
|
XSetErrorHandler([](Display *dpy, XErrorEvent *event) -> int {
|
||||||
if (strstr (extensions, "GLX_ARB_create_context"))
|
printf("XError: type: %d code: %d\n", event->type, event->error_code);
|
||||||
context = glXCreateContextAttribsARB (display, fbconfig, NULL, True, context_attribs);
|
return X_OK;
|
||||||
|
});
|
||||||
|
if (strstr(extensions, "GLX_ARB_create_context"))
|
||||||
|
context = glXCreateContextAttribsARB(display, fbconfig, NULL, True, context_attribs);
|
||||||
if (!context)
|
if (!context)
|
||||||
context = glXCreateNewContext (display, fbconfig, GLX_RGBA_TYPE, NULL, True);
|
context = glXCreateNewContext(display, fbconfig, GLX_RGBA_TYPE, NULL, True);
|
||||||
gdk_x11_display_error_trap_pop_ignored(gdk_display);
|
XSetErrorHandler(nullptr);
|
||||||
|
|
||||||
if (!context)
|
if (!context)
|
||||||
{
|
{
|
||||||
printf ("Couldn't create GLX context.\n");
|
printf("Couldn't create GLX context.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,31 +93,27 @@ bool GTKGLXContext::create_context ()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GTKGLXContext::resize ()
|
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)
|
unsigned int width;
|
||||||
return;
|
unsigned int height;
|
||||||
|
glXQueryDrawable(display, xid, GLX_WIDTH, &width);
|
||||||
|
glXQueryDrawable(display, xid, GLX_HEIGHT, &height);
|
||||||
|
|
||||||
window_attr.width = width;
|
this->width = width;
|
||||||
window_attr.height = height;
|
this->height = height;
|
||||||
|
make_current();
|
||||||
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);
|
|
||||||
|
|
||||||
make_current ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GTKGLXContext::swap_buffers ()
|
void GTKGLXContext::swap_buffers()
|
||||||
{
|
{
|
||||||
if (use_oml_sync_control)
|
if (use_oml_sync_control)
|
||||||
glXGetSyncValuesOML(display, xid, &ust, &msc, &sbc);
|
glXGetSyncValuesOML(display, xid, &ust, &msc, &sbc);
|
||||||
|
|
||||||
glXSwapBuffers (display, xid);
|
glXSwapBuffers(display, xid);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GTKGLXContext::ready()
|
bool GTKGLXContext::ready()
|
||||||
|
@ -170,21 +131,19 @@ bool GTKGLXContext::ready()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GTKGLXContext::make_current ()
|
void GTKGLXContext::make_current()
|
||||||
{
|
{
|
||||||
glXMakeCurrent (display, xid, context);
|
glXMakeCurrent(display, xid, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GTKGLXContext::swap_interval (int frames)
|
void GTKGLXContext::swap_interval(int frames)
|
||||||
{
|
{
|
||||||
if (epoxy_has_glx_extension (display, screen, "GLX_EXT_swap_control"))
|
if (epoxy_has_glx_extension(display, screen, "GLX_EXT_swap_control"))
|
||||||
glXSwapIntervalEXT (display, xid, frames);
|
glXSwapIntervalEXT(display, xid, frames);
|
||||||
else if (epoxy_has_glx_extension (display, screen, "GLX_SGI_swap_control"))
|
else if (epoxy_has_glx_extension(display, screen, "GLX_SGI_swap_control"))
|
||||||
glXSwapIntervalSGI (frames);
|
glXSwapIntervalSGI(frames);
|
||||||
#ifdef GLX_MESA_swap_control
|
#ifdef GLX_MESA_swap_control
|
||||||
else if (epoxy_has_glx_extension (display, screen, "GLX_MESA_swap_control"))
|
else if (epoxy_has_glx_extension(display, screen, "GLX_MESA_swap_control"))
|
||||||
glXSwapIntervalMESA (frames);
|
glXSwapIntervalMESA(frames);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,36 +7,27 @@
|
||||||
#ifndef __GTK_GLX_CONTEXT_H
|
#ifndef __GTK_GLX_CONTEXT_H
|
||||||
#define __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 "gtk_opengl_context.h"
|
||||||
|
|
||||||
|
#include <epoxy/glx.h>
|
||||||
|
|
||||||
class GTKGLXContext : public OpenGLContext
|
class GTKGLXContext : public OpenGLContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GTKGLXContext ();
|
GTKGLXContext();
|
||||||
~GTKGLXContext ();
|
~GTKGLXContext();
|
||||||
bool attach (GtkWidget *widget);
|
bool attach(Display *dpy, Window xid);
|
||||||
bool create_context ();
|
bool create_context();
|
||||||
void resize ();
|
void resize();
|
||||||
void swap_buffers ();
|
void swap_buffers();
|
||||||
void swap_interval (int frames);
|
void swap_interval(int frames);
|
||||||
void make_current ();
|
void make_current();
|
||||||
bool ready();
|
bool ready();
|
||||||
|
|
||||||
GtkWidget *widget;
|
|
||||||
|
|
||||||
GdkDisplay *gdk_display;
|
|
||||||
GdkWindow *parent_gdk_window;
|
|
||||||
GdkWindow *gdk_window;
|
|
||||||
GdkWindowAttr window_attr;
|
|
||||||
|
|
||||||
GLXContext context;
|
GLXContext context;
|
||||||
GLXFBConfig fbconfig;
|
GLXFBConfig fbconfig;
|
||||||
Display *display;
|
Display *display;
|
||||||
int screen;
|
int screen;
|
||||||
XVisualInfo *vi;
|
|
||||||
Window xid;
|
Window xid;
|
||||||
|
|
||||||
int version_major;
|
int version_major;
|
||||||
|
|
|
@ -10,133 +10,132 @@
|
||||||
#include "gtk_netplay_dialog.h"
|
#include "gtk_netplay_dialog.h"
|
||||||
#include "gtk_netplay.h"
|
#include "gtk_netplay.h"
|
||||||
#include "gtk_sound.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);
|
uint16 MovieGetJoypad(int i);
|
||||||
void MovieSetJoypad (int i, uint16 buttons);
|
void MovieSetJoypad(int i, uint16 buttons);
|
||||||
|
|
||||||
static uint32 local_joypads[8], joypads[8];
|
static uint32 local_joypads[8], joypads[8];
|
||||||
static GThread *npthread;
|
static GThread *npthread;
|
||||||
|
|
||||||
extern SNPServer NPServer;
|
extern SNPServer NPServer;
|
||||||
|
|
||||||
static void
|
static void S9xNetplayPreconnect()
|
||||||
S9xNetplayPreconnect ()
|
|
||||||
{
|
{
|
||||||
S9xNetplayDisconnect ();
|
S9xNetplayDisconnect();
|
||||||
|
|
||||||
if (gui_config->rom_loaded)
|
if (gui_config->rom_loaded)
|
||||||
{
|
{
|
||||||
S9xAutoSaveSRAM ();
|
S9xAutoSaveSRAM();
|
||||||
}
|
}
|
||||||
|
|
||||||
NetPlay.MaxBehindFrameCount = gui_config->netplay_max_frame_loss;
|
NetPlay.MaxBehindFrameCount = gui_config->netplay_max_frame_loss;
|
||||||
NetPlay.Waiting4EmulationThread = false;
|
NetPlay.Waiting4EmulationThread = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void S9xNetplayConnect()
|
||||||
S9xNetplayConnect ()
|
|
||||||
{
|
{
|
||||||
GtkWidget *msg;
|
GtkWidget *msg;
|
||||||
|
|
||||||
S9xNetplayPreconnect ();
|
S9xNetplayPreconnect();
|
||||||
|
|
||||||
uint32 flags = CPU.Flags;
|
uint32 flags = CPU.Flags;
|
||||||
|
|
||||||
if (!gui_config->netplay_last_rom.empty () &&
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!S9xNPConnectToServer (gui_config->netplay_last_host.c_str (),
|
if (!S9xNPConnectToServer(gui_config->netplay_last_host.c_str(),
|
||||||
gui_config->netplay_last_port,
|
gui_config->netplay_last_port,
|
||||||
Memory.ROMName))
|
Memory.ROMName))
|
||||||
{
|
{
|
||||||
msg = gtk_message_dialog_new (NULL,
|
msg = gtk_message_dialog_new(NULL,
|
||||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
GTK_MESSAGE_ERROR,
|
GTK_MESSAGE_ERROR,
|
||||||
GTK_BUTTONS_CLOSE,
|
GTK_BUTTONS_CLOSE,
|
||||||
"Couldn't connect to server: %s:%d",
|
"Couldn't connect to server: %s:%d",
|
||||||
gui_config->netplay_last_host.c_str (),
|
gui_config->netplay_last_host.c_str(),
|
||||||
gui_config->netplay_last_port);
|
gui_config->netplay_last_port);
|
||||||
gtk_window_set_title (GTK_WINDOW (msg), _("Connection Error"));
|
gtk_window_set_title(GTK_WINDOW(msg), _("Connection Error"));
|
||||||
|
|
||||||
gtk_dialog_run (GTK_DIALOG (msg));
|
gtk_dialog_run(GTK_DIALOG(msg));
|
||||||
gtk_widget_destroy (msg);
|
gtk_widget_destroy(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
gui_config->netplay_activated = true;
|
gui_config->netplay_activated = true;
|
||||||
|
|
||||||
/* If no rom is specified, assume we'll get it from the server */
|
/* If no rom is specified, assume we'll get it from the server */
|
||||||
if (gui_config->netplay_last_rom.empty ())
|
if (gui_config->netplay_last_rom.empty())
|
||||||
{
|
{
|
||||||
Settings.StopEmulation = false;
|
Settings.StopEmulation = false;
|
||||||
S9xROMLoaded ();
|
S9xROMLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xReset ();
|
S9xReset();
|
||||||
|
|
||||||
CPU.Flags = flags;
|
CPU.Flags = flags;
|
||||||
|
|
||||||
top_level->configure_widgets ();
|
top_level->configure_widgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void S9xNetplaySyncClients()
|
||||||
S9xNetplaySyncClients ()
|
|
||||||
{
|
{
|
||||||
if (Settings.NetPlay && Settings.NetPlayServer)
|
if (Settings.NetPlay && Settings.NetPlayServer)
|
||||||
S9xNPServerQueueSyncAll ();
|
S9xNPServerQueueSyncAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void S9xNetplayStopServer()
|
||||||
S9xNetplayStopServer ()
|
|
||||||
{
|
{
|
||||||
S9xNPStopServer ();
|
S9xNPStopServer();
|
||||||
|
|
||||||
g_thread_join (npthread);
|
g_thread_join(npthread);
|
||||||
Settings.NetPlayServer = false;
|
Settings.NetPlayServer = false;
|
||||||
gui_config->netplay_server_up = false;
|
gui_config->netplay_server_up = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void S9xNetplayDisconnect()
|
||||||
S9xNetplayDisconnect ()
|
|
||||||
{
|
{
|
||||||
if (Settings.NetPlay)
|
if (Settings.NetPlay)
|
||||||
{
|
{
|
||||||
if (NetPlay.Connected)
|
if (NetPlay.Connected)
|
||||||
S9xNPDisconnect ();
|
S9xNPDisconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gui_config->netplay_server_up)
|
if (gui_config->netplay_server_up)
|
||||||
{
|
{
|
||||||
S9xNetplayStopServer ();
|
S9xNetplayStopServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
gui_config->netplay_activated = false;
|
gui_config->netplay_activated = false;
|
||||||
NetPlay.Paused = false;
|
NetPlay.Paused = false;
|
||||||
|
|
||||||
top_level->configure_widgets ();
|
top_level->configure_widgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer S9xNetplayServerThread(gpointer)
|
||||||
S9xNetplayServerThread (gpointer)
|
|
||||||
{
|
{
|
||||||
S9xNPStartServer (gui_config->netplay_default_port);
|
S9xNPStartServer(gui_config->netplay_default_port);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void S9xNetplayStartServer()
|
||||||
S9xNetplayStartServer ()
|
|
||||||
{
|
{
|
||||||
uint32 flags;
|
uint32 flags;
|
||||||
|
|
||||||
S9xNetplayPreconnect ();
|
S9xNetplayPreconnect();
|
||||||
|
|
||||||
flags = CPU.Flags;
|
flags = CPU.Flags;
|
||||||
|
|
||||||
if (gui_config->netplay_last_rom.empty () ||
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -145,105 +144,103 @@ S9xNetplayStartServer ()
|
||||||
NPServer.SyncByReset = gui_config->netplay_sync_reset;
|
NPServer.SyncByReset = gui_config->netplay_sync_reset;
|
||||||
NPServer.SendROMImageOnConnect = gui_config->netplay_send_rom;
|
NPServer.SendROMImageOnConnect = gui_config->netplay_send_rom;
|
||||||
|
|
||||||
npthread = g_thread_new (NULL, S9xNetplayServerThread, NULL);
|
npthread = g_thread_new(NULL, S9xNetplayServerThread, NULL);
|
||||||
|
|
||||||
/* Sleep to let the server create itself */
|
/* Sleep to let the server create itself */
|
||||||
usleep (10000);
|
usleep(10000);
|
||||||
|
|
||||||
S9xNPConnectToServer ("127.0.0.1",
|
S9xNPConnectToServer("127.0.0.1",
|
||||||
gui_config->netplay_default_port,
|
gui_config->netplay_default_port,
|
||||||
Memory.ROMName);
|
Memory.ROMName);
|
||||||
|
|
||||||
S9xReset ();
|
S9xReset();
|
||||||
|
|
||||||
S9xROMLoaded ();
|
S9xROMLoaded();
|
||||||
|
|
||||||
gui_config->netplay_activated = true;
|
gui_config->netplay_activated = true;
|
||||||
gui_config->netplay_server_up = true;
|
gui_config->netplay_server_up = true;
|
||||||
|
|
||||||
CPU.Flags = flags;
|
CPU.Flags = flags;
|
||||||
|
|
||||||
top_level->configure_widgets ();
|
top_level->configure_widgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void S9xNetplayDialogOpen()
|
||||||
S9xNetplayDialogOpen ()
|
|
||||||
{
|
{
|
||||||
Snes9xNetplayDialog *np_dialog;
|
Snes9xNetplayDialog *np_dialog;
|
||||||
|
|
||||||
top_level->pause_from_focus_change ();
|
top_level->pause_from_focus_change();
|
||||||
|
|
||||||
np_dialog = new Snes9xNetplayDialog (gui_config);
|
np_dialog = new Snes9xNetplayDialog(gui_config);
|
||||||
|
|
||||||
gtk_window_set_transient_for (np_dialog->get_window (),
|
gtk_window_set_transient_for(np_dialog->get_window(),
|
||||||
top_level->get_window ());
|
top_level->get_window());
|
||||||
|
|
||||||
if (np_dialog->show ())
|
if (np_dialog->show())
|
||||||
{
|
{
|
||||||
if (!gui_config->netplay_is_server)
|
if (!gui_config->netplay_is_server)
|
||||||
{
|
{
|
||||||
S9xNetplayConnect ();
|
S9xNetplayConnect();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
S9xNetplayStartServer ();
|
S9xNetplayStartServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xSoundStart ();
|
S9xSoundStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
delete np_dialog;
|
delete np_dialog;
|
||||||
|
|
||||||
top_level->unpause_from_focus_change ();
|
top_level->unpause_from_focus_change();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int S9xNetplaySyncSpeed()
|
||||||
S9xNetplaySyncSpeed ()
|
|
||||||
{
|
{
|
||||||
if (!Settings.NetPlay || !NetPlay.Connected)
|
if (!Settings.NetPlay || !NetPlay.Connected)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Send 1st joypad's position update to server
|
// Send 1st joypad's position update to server
|
||||||
S9xNPSendJoypadUpdate (local_joypads[0]);
|
S9xNPSendJoypadUpdate(local_joypads[0]);
|
||||||
|
|
||||||
// set input from network
|
// set input from network
|
||||||
for (int i = 0; i < NP_MAX_CLIENTS; i++)
|
for (int i = 0; i < NP_MAX_CLIENTS; i++)
|
||||||
joypads[i] = S9xNPGetJoypad (i);
|
joypads[i] = S9xNPGetJoypad(i);
|
||||||
|
|
||||||
if (!S9xNPCheckForHeartBeat ())
|
if (!S9xNPCheckForHeartBeat())
|
||||||
{
|
{
|
||||||
// No heartbeats already arrived, have to wait for one.
|
// No heartbeats already arrived, have to wait for one.
|
||||||
NetPlay.PendingWait4Sync = !S9xNPWaitForHeartBeatDelay (100);
|
NetPlay.PendingWait4Sync = !S9xNPWaitForHeartBeatDelay(100);
|
||||||
|
|
||||||
IPPU.RenderThisFrame = true;
|
IPPU.RenderThisFrame = true;
|
||||||
IPPU.SkippedFrames = 0;
|
IPPU.SkippedFrames = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int difference = (int) (NetPlay.MySequenceNum) -
|
int difference = (int)(NetPlay.MySequenceNum) -
|
||||||
(int) (NetPlay.ServerSequenceNum);
|
(int)(NetPlay.ServerSequenceNum);
|
||||||
|
|
||||||
if (difference < 0)
|
if (difference < 0)
|
||||||
difference += 256;
|
difference += 256;
|
||||||
|
|
||||||
if (NetPlay.Waiting4EmulationThread)
|
if (NetPlay.Waiting4EmulationThread)
|
||||||
{
|
{
|
||||||
if ((unsigned int) difference <= (NetPlay.MaxBehindFrameCount / 2))
|
if ((unsigned int)difference <= (NetPlay.MaxBehindFrameCount / 2))
|
||||||
{
|
{
|
||||||
NetPlay.Waiting4EmulationThread = false;
|
NetPlay.Waiting4EmulationThread = false;
|
||||||
S9xNPSendPause (false);
|
S9xNPSendPause(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((unsigned int) difference >= (NetPlay.MaxBehindFrameCount))
|
if ((unsigned int)difference >= (NetPlay.MaxBehindFrameCount))
|
||||||
{
|
{
|
||||||
NetPlay.Waiting4EmulationThread = true;
|
NetPlay.Waiting4EmulationThread = true;
|
||||||
S9xNPSendPause (true);
|
S9xNPSendPause(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NetPlay.PendingWait4Sync = !S9xNPWaitForHeartBeatDelay (200);
|
NetPlay.PendingWait4Sync = !S9xNPWaitForHeartBeatDelay(200);
|
||||||
|
|
||||||
if (IPPU.SkippedFrames < NetPlay.MaxFrameSkip)
|
if (IPPU.SkippedFrames < NetPlay.MaxFrameSkip)
|
||||||
{
|
{
|
||||||
|
@ -260,27 +257,26 @@ S9xNetplaySyncSpeed ()
|
||||||
if (!NetPlay.PendingWait4Sync)
|
if (!NetPlay.PendingWait4Sync)
|
||||||
{
|
{
|
||||||
NetPlay.FrameCount++;
|
NetPlay.FrameCount++;
|
||||||
S9xNPStepJoypadHistory ();
|
S9xNPStepJoypadHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int S9xNetplayPush()
|
||||||
S9xNetplayPush ()
|
|
||||||
{
|
{
|
||||||
if (gui_config->netplay_activated &&
|
if (gui_config->netplay_activated &&
|
||||||
(!Settings.NetPlay || !NetPlay.Connected))
|
(!Settings.NetPlay || !NetPlay.Connected))
|
||||||
S9xNetplayDisconnect ();
|
S9xNetplayDisconnect();
|
||||||
|
|
||||||
if (!Settings.NetPlay)
|
if (!Settings.NetPlay)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (NetPlay.PendingWait4Sync && !S9xNPWaitForHeartBeatDelay (100))
|
if (NetPlay.PendingWait4Sync && !S9xNPWaitForHeartBeatDelay(100))
|
||||||
{
|
{
|
||||||
S9xProcessEvents (false);
|
S9xProcessEvents(false);
|
||||||
|
|
||||||
S9xSoundStop ();
|
S9xSoundStop();
|
||||||
NetPlay.Paused = true;
|
NetPlay.Paused = true;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -288,36 +284,31 @@ S9xNetplayPush ()
|
||||||
|
|
||||||
NetPlay.Paused = false;
|
NetPlay.Paused = false;
|
||||||
|
|
||||||
S9xSoundStart ();
|
S9xSoundStart();
|
||||||
|
|
||||||
/* Save the joypad input */
|
/* Save the joypad input */
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
local_joypads[i] = MovieGetJoypad (i);
|
local_joypads[i] = MovieGetJoypad(i);
|
||||||
|
|
||||||
MovieSetJoypad (i, joypads[i]);
|
MovieSetJoypad(i, joypads[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NetPlay.PendingWait4Sync)
|
if (NetPlay.PendingWait4Sync)
|
||||||
{
|
{
|
||||||
NetPlay.PendingWait4Sync = false;
|
NetPlay.PendingWait4Sync = false;
|
||||||
NetPlay.FrameCount++;
|
NetPlay.FrameCount++;
|
||||||
S9xNPStepJoypadHistory ();
|
S9xNPStepJoypadHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void S9xNetplayPop()
|
||||||
S9xNetplayPop ()
|
|
||||||
{
|
{
|
||||||
if (!Settings.NetPlay)
|
if (!Settings.NetPlay)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
MovieSetJoypad (i, local_joypads[i]);
|
MovieSetJoypad(i, local_joypads[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
#ifndef __GTK_NETPLAY_H
|
#ifndef __GTK_NETPLAY_H
|
||||||
#define __GTK_NETPLAY_H
|
#define __GTK_NETPLAY_H
|
||||||
|
|
||||||
void S9xNetplayDialogOpen ();
|
void S9xNetplayDialogOpen();
|
||||||
int S9xNetplayPush ();
|
int S9xNetplayPush();
|
||||||
void S9xNetplayPop ();
|
void S9xNetplayPop();
|
||||||
int S9xNetplaySyncSpeed ();
|
int S9xNetplaySyncSpeed();
|
||||||
void S9xNetplaySyncClients ();
|
void S9xNetplaySyncClients();
|
||||||
void S9xNetplayDisconnect ();
|
void S9xNetplayDisconnect();
|
||||||
|
|
||||||
#endif /* __GTK_NETPLAY_H */
|
#endif /* __GTK_NETPLAY_H */
|
||||||
|
|
|
@ -6,133 +6,91 @@
|
||||||
|
|
||||||
#include "gtk_netplay_dialog.h"
|
#include "gtk_netplay_dialog.h"
|
||||||
#include "gtk_s9x.h"
|
#include "gtk_s9x.h"
|
||||||
#include "gtk_file.h"
|
|
||||||
|
|
||||||
static void
|
Snes9xNetplayDialog::Snes9xNetplayDialog(Snes9xConfig *config)
|
||||||
event_browse_clicked (GtkButton *button, gpointer data)
|
: GtkBuilderWindow("netplay_dialog")
|
||||||
{
|
{
|
||||||
char *filename;
|
get_object<Gtk::RadioButton>("host_radio")->signal_toggled().connect([&] {
|
||||||
Snes9xNetplayDialog *np_dialog = (Snes9xNetplayDialog *) data;
|
update_state();
|
||||||
|
});
|
||||||
|
|
||||||
filename = S9xOpenROMDialog ();
|
get_object<Gtk::Button>("clear_netplay")->signal_clicked().connect([&] {
|
||||||
|
get_object<Gtk::Entry>("rom_image")->set_text("");
|
||||||
|
});
|
||||||
|
|
||||||
if (filename)
|
get_object<Gtk::Button>("browse_button")->signal_clicked().connect([&] {
|
||||||
{
|
auto filename = top_level->open_rom_dialog(false);
|
||||||
gtk_entry_set_text (GTK_ENTRY (np_dialog->get_widget ("rom_image")),
|
if (!filename.empty())
|
||||||
filename);
|
get_object<Gtk::Entry>("rom_image")->set_text(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);
|
|
||||||
|
|
||||||
this->config = config;
|
this->config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
Snes9xNetplayDialog::~Snes9xNetplayDialog()
|
||||||
Snes9xNetplayDialog::update_state ()
|
|
||||||
{
|
{
|
||||||
if (get_check ("host_radio"))
|
}
|
||||||
|
|
||||||
|
void Snes9xNetplayDialog::update_state()
|
||||||
|
{
|
||||||
|
if (get_check("host_radio"))
|
||||||
{
|
{
|
||||||
enable_widget ("connect_box", false);
|
enable_widget("connect_box", false);
|
||||||
enable_widget ("default_port_box", true);
|
enable_widget("default_port_box", true);
|
||||||
enable_widget ("sync_reset", true);
|
enable_widget("sync_reset", true);
|
||||||
enable_widget ("send_image", true);
|
enable_widget("send_image", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
enable_widget ("connect_box", true);
|
enable_widget("connect_box", true);
|
||||||
enable_widget ("default_port_box", false);
|
enable_widget("default_port_box", false);
|
||||||
enable_widget ("sync_reset", false);
|
enable_widget("sync_reset", false);
|
||||||
enable_widget ("send_image", false);
|
enable_widget("send_image", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Snes9xNetplayDialog::settings_to_dialog()
|
||||||
Snes9xNetplayDialog::settings_to_dialog ()
|
|
||||||
{
|
{
|
||||||
set_entry_text ("rom_image", config->netplay_last_rom.c_str ());
|
set_entry_text("rom_image", config->netplay_last_rom.c_str());
|
||||||
set_entry_text ("ip_entry", config->netplay_last_host.c_str ());
|
set_entry_text("ip_entry", config->netplay_last_host.c_str());
|
||||||
set_check ("sync_reset", config->netplay_sync_reset);
|
set_check("sync_reset", config->netplay_sync_reset);
|
||||||
set_check ("send_image", config->netplay_send_rom);
|
set_check("send_image", config->netplay_send_rom);
|
||||||
set_spin ("port", config->netplay_last_port);
|
set_spin("port", config->netplay_last_port);
|
||||||
set_spin ("default_port", config->netplay_default_port);
|
set_spin("default_port", config->netplay_default_port);
|
||||||
set_spin ("frames_behind", config->netplay_max_frame_loss);
|
set_spin("frames_behind", config->netplay_max_frame_loss);
|
||||||
set_check ("connect_radio", !config->netplay_is_server);
|
set_check("connect_radio", !config->netplay_is_server);
|
||||||
set_check ("host_radio", config->netplay_is_server);
|
set_check("host_radio", config->netplay_is_server);
|
||||||
|
|
||||||
update_state ();
|
update_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Snes9xNetplayDialog::settings_from_dialog()
|
||||||
Snes9xNetplayDialog::settings_from_dialog ()
|
|
||||||
{
|
{
|
||||||
config->netplay_last_rom = get_entry_text ("rom_image");
|
config->netplay_last_rom = get_entry_text("rom_image");
|
||||||
config->netplay_last_host = get_entry_text ("ip_entry");
|
config->netplay_last_host = get_entry_text("ip_entry");
|
||||||
config->netplay_sync_reset = get_check ("sync_reset");
|
config->netplay_sync_reset = get_check("sync_reset");
|
||||||
config->netplay_send_rom = get_check ("send_image");
|
config->netplay_send_rom = get_check("send_image");
|
||||||
config->netplay_last_port = get_spin ("port");
|
config->netplay_last_port = get_spin("port");
|
||||||
config->netplay_default_port = get_spin ("default_port");
|
config->netplay_default_port = get_spin("default_port");
|
||||||
config->netplay_max_frame_loss = get_spin ("frames_behind");
|
config->netplay_max_frame_loss = get_spin("frames_behind");
|
||||||
config->netplay_is_server = get_check ("host_radio");
|
config->netplay_is_server = get_check("host_radio");
|
||||||
|
|
||||||
config->save_config_file ();
|
config->save_config_file();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Snes9xNetplayDialog::show()
|
bool Snes9xNetplayDialog::show()
|
||||||
{
|
{
|
||||||
int result;
|
settings_to_dialog();
|
||||||
|
|
||||||
settings_to_dialog ();
|
auto result = Glib::RefPtr<Gtk::Dialog>::cast_static(window)->run();
|
||||||
|
window->hide();
|
||||||
|
|
||||||
result = gtk_dialog_run (GTK_DIALOG (window));
|
if (result == Gtk::RESPONSE_OK)
|
||||||
|
|
||||||
gtk_widget_hide (window);
|
|
||||||
|
|
||||||
if (result == GTK_RESPONSE_OK)
|
|
||||||
{
|
{
|
||||||
settings_from_dialog ();
|
settings_from_dialog();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
return false;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Snes9xNetplayDialog::~Snes9xNetplayDialog ()
|
|
||||||
{
|
|
||||||
gtk_widget_destroy (window);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,17 +12,16 @@
|
||||||
|
|
||||||
class Snes9xNetplayDialog : public GtkBuilderWindow
|
class Snes9xNetplayDialog : public GtkBuilderWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Snes9xNetplayDialog (Snes9xConfig *config);
|
Snes9xNetplayDialog(Snes9xConfig *config);
|
||||||
~Snes9xNetplayDialog ();
|
~Snes9xNetplayDialog();
|
||||||
bool show ();
|
bool show();
|
||||||
void update_state ();
|
void update_state();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Snes9xConfig *config;
|
Snes9xConfig *config;
|
||||||
void settings_to_dialog ();
|
void settings_to_dialog();
|
||||||
void settings_from_dialog ();
|
void settings_from_dialog();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* __GTK_NETPLAY_DIALOG_H */
|
#endif /* __GTK_NETPLAY_DIALOG_H */
|
||||||
|
|
|
@ -7,19 +7,19 @@
|
||||||
#ifndef __GTK_OPENGL_CONTEXT_H
|
#ifndef __GTK_OPENGL_CONTEXT_H
|
||||||
#define __GTK_OPENGL_CONTEXT_H
|
#define __GTK_OPENGL_CONTEXT_H
|
||||||
|
|
||||||
#include "gtk_2_3_compat.h"
|
|
||||||
|
|
||||||
class OpenGLContext
|
class OpenGLContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~OpenGLContext () {};
|
virtual ~OpenGLContext(){};
|
||||||
virtual bool attach (GtkWidget *widget) = 0;
|
virtual bool create_context() = 0;
|
||||||
virtual bool create_context () = 0;
|
virtual void resize() = 0;
|
||||||
virtual void resize () = 0;
|
virtual void swap_buffers() = 0;
|
||||||
virtual void swap_buffers () = 0;
|
virtual void swap_interval(int frames) = 0;
|
||||||
virtual void swap_interval (int frames) = 0;
|
virtual void make_current() = 0;
|
||||||
virtual void make_current () = 0;
|
virtual bool ready()
|
||||||
virtual bool ready() { return true; };
|
{
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,45 +7,47 @@
|
||||||
#ifndef __GTK_PREFERENCES_H
|
#ifndef __GTK_PREFERENCES_H
|
||||||
#define __GTK_PREFERENCES_H
|
#define __GTK_PREFERENCES_H
|
||||||
|
|
||||||
#include "gtk_2_3_compat.h"
|
#include "gtk_compat.h"
|
||||||
#include "gtk_s9x.h"
|
#include "gtk_s9x.h"
|
||||||
#include "gtk_builder_window.h"
|
#include "gtk_builder_window.h"
|
||||||
|
|
||||||
gboolean snes9x_preferences_open (GtkWidget *widget,
|
void snes9x_preferences_open(Snes9xWindow *window, Snes9xConfig *config);
|
||||||
gpointer data);
|
|
||||||
|
|
||||||
class Snes9xPreferences : public GtkBuilderWindow
|
class Snes9xPreferences : public GtkBuilderWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Snes9xPreferences (Snes9xConfig *config);
|
Snes9xPreferences(Snes9xConfig *config);
|
||||||
~Snes9xPreferences ();
|
~Snes9xPreferences();
|
||||||
void show ();
|
void show();
|
||||||
void bindings_to_dialog (int joypad);
|
void bindings_to_dialog(int joypad);
|
||||||
int get_focused_binding ();
|
int get_focused_binding();
|
||||||
void store_binding (const char *string, Binding binding);
|
void store_binding(const char *string, Binding binding);
|
||||||
void browse_folder_dialog ();
|
int hw_accel_value(int combo_value);
|
||||||
int hw_accel_value (int combo_value);
|
int combo_value(int hw_accel);
|
||||||
int combo_value (int hw_accel);
|
void focus_next();
|
||||||
void focus_next ();
|
void swap_with();
|
||||||
void swap_with ();
|
void clear_binding(const char *name);
|
||||||
void clear_binding (const char *name);
|
void reset_current_joypad();
|
||||||
void reset_current_joypad ();
|
void load_ntsc_settings();
|
||||||
void load_ntsc_settings ();
|
void store_ntsc_settings();
|
||||||
void store_ntsc_settings ();
|
void calibration_dialog();
|
||||||
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;
|
Snes9xConfig *config;
|
||||||
GtkToggleButton *last_toggled;
|
bool awaiting_key;
|
||||||
bool awaiting_key;
|
bool polling_joystick;
|
||||||
bool polling_joystick;
|
std::array<JoypadBinding, NUM_JOYPADS> pad;
|
||||||
std::array<JoypadBinding, NUM_JOYPADS> pad;
|
std::array<Binding, NUM_EMU_LINKS> shortcut;
|
||||||
std::array<Binding, NUM_EMU_LINKS> shortcut;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void get_settings_from_dialog ();
|
void get_settings_from_dialog();
|
||||||
void move_settings_to_dialog ();
|
void move_settings_to_dialog();
|
||||||
|
|
||||||
unsigned int *mode_indices;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __GTK_PREFERENCES_H */
|
#endif /* __GTK_PREFERENCES_H */
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.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_config.h"
|
||||||
#include "gtk_s9x.h"
|
#include "gtk_s9x.h"
|
||||||
#include "gtk_control.h"
|
#include "gtk_control.h"
|
||||||
|
@ -15,84 +17,85 @@
|
||||||
#include "gtk_netplay.h"
|
#include "gtk_netplay.h"
|
||||||
#include "statemanager.h"
|
#include "statemanager.h"
|
||||||
#include "background_particles.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 S9xThrottle (int);
|
static void S9xCheckPointerTimer();
|
||||||
static void S9xCheckPointerTimer ();
|
static bool S9xIdleFunc();
|
||||||
static gboolean S9xIdleFunc (gpointer data);
|
static bool S9xPauseFunc();
|
||||||
static gboolean S9xPauseFunc (gpointer data);
|
static bool S9xScreenSaverCheckFunc();
|
||||||
static gboolean S9xScreenSaverCheckFunc (gpointer data);
|
|
||||||
|
|
||||||
Snes9xWindow *top_level;
|
Snes9xWindow *top_level;
|
||||||
Snes9xConfig *gui_config;
|
Snes9xConfig *gui_config;
|
||||||
StateManager state_manager;
|
StateManager state_manager;
|
||||||
gint64 frame_clock = -1;
|
gint64 frame_clock = -1;
|
||||||
gint64 pointer_timestamp = -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 ();
|
S9xExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main (int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct sigaction sig_callback;
|
struct sigaction sig_callback;
|
||||||
|
auto app = Gtk::Application::create(argc, argv, "com.snes9x.gtk", Gio::APPLICATION_NON_UNIQUE);
|
||||||
|
|
||||||
gtk_init (&argc, &argv);
|
setlocale(LC_ALL, "");
|
||||||
|
bindtextdomain(GETTEXT_PACKAGE, SNES9XLOCALEDIR);
|
||||||
|
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
|
||||||
|
textdomain(GETTEXT_PACKAGE);
|
||||||
|
|
||||||
setlocale (LC_ALL, "");
|
memset(&Settings, 0, sizeof(Settings));
|
||||||
bindtextdomain (GETTEXT_PACKAGE, SNES9XLOCALEDIR);
|
|
||||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
|
||||||
textdomain (GETTEXT_PACKAGE);
|
|
||||||
|
|
||||||
memset (&Settings, 0, sizeof (Settings));
|
// Original config fills out values this port doesn't.
|
||||||
|
S9xLoadConfigFiles(argv, argc);
|
||||||
|
|
||||||
/* Allow original config file for backend settings */
|
gui_config = new Snes9xConfig();
|
||||||
S9xLoadConfigFiles (argv, argc);
|
|
||||||
|
|
||||||
/* Perform our config here */
|
S9xInitInputDevices();
|
||||||
gui_config = new Snes9xConfig ();
|
|
||||||
|
|
||||||
S9xInitInputDevices ();
|
gui_config->load_config_file();
|
||||||
|
|
||||||
gui_config->load_config_file ();
|
char *rom_filename = S9xParseArgs(argv, argc);
|
||||||
|
|
||||||
char *rom_filename = S9xParseArgs (argv, argc);
|
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);
|
||||||
|
|
||||||
#if GTK_MAJOR_VERSION >= 3
|
S9xReportControllers();
|
||||||
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
|
|
||||||
|
|
||||||
S9xReportControllers ();
|
if (!Memory.Init() || !S9xInitAPU())
|
||||||
|
exit(3);
|
||||||
|
|
||||||
if (!Memory.Init () || !S9xInitAPU ())
|
top_level = new Snes9xWindow(gui_config);
|
||||||
exit (3);
|
|
||||||
|
|
||||||
top_level = new Snes9xWindow (gui_config);
|
// Setting fullscreen before showing the window avoids some flicker.
|
||||||
|
|
||||||
/* If we're going to fullscreen, do it before showing window to avoid flicker. */
|
|
||||||
if ((gui_config->full_screen_on_open && rom_filename) || (gui_config->fullscreen))
|
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 ();
|
top_level->show();
|
||||||
|
|
||||||
S9xInitDisplay (argc, argv);
|
S9xInitDisplay(argc, argv);
|
||||||
|
|
||||||
Memory.PostRomInitFunc = S9xPostRomInit;
|
S9xPortSoundInit();
|
||||||
|
|
||||||
S9xPortSoundInit ();
|
|
||||||
|
|
||||||
for (int port = 0; port < 2; port++)
|
for (int port = 0; port < 2; port++)
|
||||||
{
|
{
|
||||||
enum controllers type;
|
enum controllers type;
|
||||||
int8 id;
|
int8 id;
|
||||||
S9xGetController (port, &type, &id, &id, &id, &id);
|
S9xGetController(port, &type, &id, &id, &id, &id);
|
||||||
std::string device_type;
|
std::string device_type;
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -113,96 +116,97 @@ int main (int argc, char *argv[])
|
||||||
device_type = "nothingpluggedin";
|
device_type = "nothingpluggedin";
|
||||||
}
|
}
|
||||||
|
|
||||||
device_type += std::to_string (port + 1);
|
device_type += std::to_string(port + 1);
|
||||||
top_level->set_menu_item_selected (device_type.c_str ());
|
top_level->set_menu_item_selected(device_type.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
gui_config->rebind_keys ();
|
gui_config->rebind_keys();
|
||||||
top_level->update_accels ();
|
top_level->update_accelerators();
|
||||||
|
|
||||||
Settings.Paused = true;
|
Settings.Paused = true;
|
||||||
g_timeout_add (100, S9xPauseFunc, NULL);
|
|
||||||
g_timeout_add (10000, S9xScreenSaverCheckFunc, NULL);
|
|
||||||
|
|
||||||
S9xNoROMLoaded ();
|
Glib::signal_timeout().connect(sigc::ptr_fun(S9xPauseFunc), 100);
|
||||||
|
Glib::signal_timeout().connect(sigc::ptr_fun(S9xScreenSaverCheckFunc), 10000);
|
||||||
|
|
||||||
|
S9xNoROMLoaded();
|
||||||
|
|
||||||
if (rom_filename)
|
if (rom_filename)
|
||||||
{
|
{
|
||||||
if (S9xOpenROM (rom_filename) && gui_config->full_screen_on_open)
|
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));
|
memset(&sig_callback, 0, sizeof(struct sigaction));
|
||||||
sig_callback.sa_handler = S9xTerm;
|
sig_callback.sa_handler = S9xTerm;
|
||||||
|
|
||||||
sigaction (15 /* SIGTERM */, &sig_callback, NULL);
|
sigaction(15, &sig_callback, NULL); // SIGTERM
|
||||||
sigaction (3 /* SIGQUIT */, &sig_callback, NULL);
|
sigaction(3, &sig_callback, NULL); // SIGQUIT
|
||||||
sigaction (2 /* SIGINT */, &sig_callback, NULL);
|
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)
|
if (gui_config->fullscreen)
|
||||||
{
|
top_level->enter_fullscreen_mode();
|
||||||
top_level->enter_fullscreen_mode ();
|
|
||||||
}
|
|
||||||
|
|
||||||
gui_config->flush_joysticks ();
|
gui_config->flush_joysticks();
|
||||||
|
|
||||||
if (rom_filename && *Settings.InitialSnapshotFilename)
|
if (rom_filename && *Settings.InitialSnapshotFilename)
|
||||||
S9xUnfreezeGame(Settings.InitialSnapshotFilename);
|
S9xUnfreezeGame(Settings.InitialSnapshotFilename);
|
||||||
|
|
||||||
gtk_main ();
|
app->run(*top_level->window.get());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int S9xOpenROM (const char *rom_filename)
|
int S9xOpenROM(const char *rom_filename)
|
||||||
{
|
{
|
||||||
uint32 flags;
|
uint32 flags;
|
||||||
bool loaded;
|
bool loaded;
|
||||||
|
|
||||||
if (gui_config->rom_loaded)
|
if (gui_config->rom_loaded)
|
||||||
{
|
{
|
||||||
S9xAutoSaveSRAM ();
|
S9xAutoSaveSRAM();
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xNetplayDisconnect ();
|
S9xNetplayDisconnect();
|
||||||
|
|
||||||
flags = CPU.Flags;
|
flags = CPU.Flags;
|
||||||
|
|
||||||
loaded = false;
|
loaded = false;
|
||||||
|
|
||||||
if (Settings.Multi)
|
if (Settings.Multi)
|
||||||
loaded = Memory.LoadMultiCart (Settings.CartAName, Settings.CartBName);
|
loaded = Memory.LoadMultiCart(Settings.CartAName, Settings.CartBName);
|
||||||
else if (rom_filename)
|
else if (rom_filename)
|
||||||
loaded = Memory.LoadROM (rom_filename);
|
loaded = Memory.LoadROM(rom_filename);
|
||||||
|
|
||||||
Settings.StopEmulation = !loaded;
|
Settings.StopEmulation = !loaded;
|
||||||
|
|
||||||
if (!loaded && rom_filename)
|
if (!loaded && rom_filename)
|
||||||
{
|
{
|
||||||
char dir [_MAX_DIR + 1];
|
char dir[_MAX_DIR + 1];
|
||||||
char drive [_MAX_DRIVE + 1];
|
char drive[_MAX_DRIVE + 1];
|
||||||
char name [_MAX_FNAME + 1];
|
char name[_MAX_FNAME + 1];
|
||||||
char ext [_MAX_EXT + 1];
|
char ext[_MAX_EXT + 1];
|
||||||
char fname [_MAX_PATH + 1];
|
char fname[_MAX_PATH + 1];
|
||||||
|
|
||||||
_splitpath (rom_filename, drive, dir, name, ext);
|
_splitpath(rom_filename, drive, dir, name, ext);
|
||||||
_makepath (fname, drive, dir, name, ext);
|
_makepath(fname, drive, dir, name, ext);
|
||||||
|
|
||||||
strcpy (fname, S9xGetDirectory (ROM_DIR));
|
strcpy(fname, S9xGetDirectory(ROM_DIR));
|
||||||
strcat (fname, SLASH_STR);
|
strcat(fname, SLASH_STR);
|
||||||
strcat (fname, name);
|
strcat(fname, name);
|
||||||
|
|
||||||
if (ext [0])
|
if (ext[0])
|
||||||
{
|
{
|
||||||
strcat (fname, ".");
|
strcat(fname, ".");
|
||||||
strcat (fname, ext);
|
strcat(fname, ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
_splitpath (fname, drive, dir, name, ext);
|
_splitpath(fname, drive, dir, name, ext);
|
||||||
_makepath (fname, drive, dir, name, ext);
|
_makepath(fname, drive, dir, name, ext);
|
||||||
|
|
||||||
if ((Settings.StopEmulation = !Memory.LoadROM (fname)))
|
if ((Settings.StopEmulation = !Memory.LoadROM(fname)))
|
||||||
{
|
{
|
||||||
fprintf (stderr, _("Error opening: %s\n"), rom_filename);
|
fprintf(stderr, _("Error opening: %s\n"), rom_filename);
|
||||||
|
|
||||||
loaded = false;
|
loaded = false;
|
||||||
}
|
}
|
||||||
|
@ -212,79 +216,77 @@ int S9xOpenROM (const char *rom_filename)
|
||||||
|
|
||||||
if (loaded)
|
if (loaded)
|
||||||
{
|
{
|
||||||
Memory.LoadSRAM (S9xGetFilename (".srm", SRAM_DIR));
|
Memory.LoadSRAM(S9xGetFilename(".srm", SRAM_DIR));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CPU.Flags = flags;
|
CPU.Flags = flags;
|
||||||
Settings.Paused = true;
|
Settings.Paused = true;
|
||||||
|
|
||||||
S9xNoROMLoaded ();
|
S9xNoROMLoaded();
|
||||||
top_level->refresh ();
|
top_level->refresh();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPU.Flags = flags;
|
CPU.Flags = flags;
|
||||||
|
|
||||||
if (state_manager.init (gui_config->rewind_buffer_size * 1024 * 1024))
|
if (state_manager.init(gui_config->rewind_buffer_size * 1024 * 1024))
|
||||||
{
|
{
|
||||||
printf ("Using rewind buffer of %uMB\n", gui_config->rewind_buffer_size);
|
printf("Using rewind buffer of %uMB\n", gui_config->rewind_buffer_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xROMLoaded ();
|
S9xROMLoaded();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xROMLoaded ()
|
void S9xROMLoaded()
|
||||||
{
|
{
|
||||||
gui_config->rom_loaded = true;
|
gui_config->rom_loaded = true;
|
||||||
top_level->configure_widgets ();
|
top_level->configure_widgets();
|
||||||
|
|
||||||
if (gui_config->full_screen_on_open)
|
if (gui_config->full_screen_on_open)
|
||||||
{
|
{
|
||||||
Settings.Paused = false;
|
Settings.Paused = false;
|
||||||
top_level->enter_fullscreen_mode ();
|
top_level->enter_fullscreen_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xSoundStart ();
|
S9xSoundStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xNoROMLoaded ()
|
void S9xNoROMLoaded()
|
||||||
{
|
{
|
||||||
S9xSoundStop ();
|
S9xSoundStop();
|
||||||
gui_config->rom_loaded = false;
|
gui_config->rom_loaded = false;
|
||||||
S9xDisplayRefresh(-1, -1);
|
S9xDisplayRefresh(-1, -1);
|
||||||
top_level->configure_widgets ();
|
top_level->configure_widgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean S9xPauseFunc (gpointer data)
|
static bool S9xPauseFunc()
|
||||||
{
|
{
|
||||||
S9xProcessEvents (true);
|
S9xProcessEvents(true);
|
||||||
|
|
||||||
if (!S9xNetplayPush ())
|
if (!S9xNetplayPush())
|
||||||
{
|
{
|
||||||
S9xNetplayPop ();
|
S9xNetplayPop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Settings.Paused) /* Coming out of pause */
|
if (!Settings.Paused) /* Coming out of pause */
|
||||||
{
|
{
|
||||||
/* Clear joystick queues */
|
/* Clear joystick queues */
|
||||||
gui_config->flush_joysticks ();
|
gui_config->flush_joysticks();
|
||||||
|
|
||||||
S9xSoundStart ();
|
S9xSoundStart();
|
||||||
|
|
||||||
if (Settings.NetPlay && NetPlay.Connected)
|
if (Settings.NetPlay && NetPlay.Connected)
|
||||||
{
|
{
|
||||||
S9xNPSendPause (false);
|
S9xNPSendPause(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resume high-performance callback */
|
/* Resume high-performance callback */
|
||||||
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
|
Glib::signal_idle().connect(sigc::ptr_fun(S9xIdleFunc));
|
||||||
S9xIdleFunc,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,44 +306,44 @@ static gboolean S9xPauseFunc (gpointer data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_timeout_add(8, S9xPauseFunc, NULL);
|
Glib::signal_timeout().connect(sigc::ptr_fun(S9xPauseFunc), 8);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean S9xIdleFunc (gpointer data)
|
static bool S9xIdleFunc()
|
||||||
{
|
{
|
||||||
if (Settings.Paused && gui_config->rom_loaded)
|
if (Settings.Paused && gui_config->rom_loaded)
|
||||||
{
|
{
|
||||||
S9xSoundStop ();
|
S9xSoundStop();
|
||||||
|
|
||||||
gui_config->flush_joysticks ();
|
gui_config->flush_joysticks();
|
||||||
|
|
||||||
if (Settings.NetPlay && NetPlay.Connected)
|
if (Settings.NetPlay && NetPlay.Connected)
|
||||||
{
|
{
|
||||||
S9xNPSendPause (true);
|
S9xNPSendPause(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move to a timer-based function to use less CPU */
|
/* 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xCheckPointerTimer ();
|
S9xCheckPointerTimer();
|
||||||
|
|
||||||
S9xProcessEvents (true);
|
S9xProcessEvents(true);
|
||||||
|
|
||||||
if (!S9xDisplayDriverIsReady ())
|
if (!S9xDisplayDriverIsReady())
|
||||||
{
|
{
|
||||||
usleep(100);
|
usleep(100);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xThrottle (Settings.SkipFrames);
|
S9xThrottle(Settings.SkipFrames);
|
||||||
|
|
||||||
if (!S9xNetplayPush ())
|
if (!S9xNetplayPush())
|
||||||
{
|
{
|
||||||
if(Settings.Rewinding)
|
if (Settings.Rewinding)
|
||||||
{
|
{
|
||||||
uint16 joypads[8];
|
uint16 joypads[8];
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
|
@ -350,115 +352,104 @@ gboolean S9xIdleFunc (gpointer data)
|
||||||
Settings.Rewinding = state_manager.pop();
|
Settings.Rewinding = state_manager.pop();
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
MovieSetJoypad (i, joypads[i]);
|
MovieSetJoypad(i, joypads[i]);
|
||||||
}
|
}
|
||||||
else if(IPPU.TotalEmulatedFrames % gui_config->rewind_granularity == 0)
|
else if (IPPU.TotalEmulatedFrames % gui_config->rewind_granularity == 0)
|
||||||
state_manager.push();
|
state_manager.push();
|
||||||
|
|
||||||
static int muted_from_turbo = false;
|
if ((Settings.TurboMode || Settings.Rewinding) && gui_config->mute_sound_turbo)
|
||||||
static int mute_saved_state = false;
|
Settings.Mute |= 0x80;
|
||||||
|
else
|
||||||
|
Settings.Mute &= ~0x80;
|
||||||
|
|
||||||
if ((Settings.TurboMode || Settings.Rewinding) && !muted_from_turbo && gui_config->mute_sound_turbo)
|
S9xMainLoop();
|
||||||
{
|
|
||||||
muted_from_turbo = true;
|
|
||||||
mute_saved_state = Settings.Mute;
|
|
||||||
S9xSetSoundMute (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(Settings.TurboMode || Settings.Rewinding) && muted_from_turbo)
|
S9xNetplayPop();
|
||||||
{
|
|
||||||
muted_from_turbo = false;
|
|
||||||
Settings.Mute = mute_saved_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
S9xMainLoop ();
|
|
||||||
|
|
||||||
S9xNetplayPop ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean S9xScreenSaverCheckFunc (gpointer data)
|
static bool S9xScreenSaverCheckFunc()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!Settings.Paused &&
|
if (!Settings.Paused &&
|
||||||
(gui_config->screensaver_needs_reset ||
|
(gui_config->screensaver_needs_reset ||
|
||||||
gui_config->prevent_screensaver))
|
gui_config->prevent_screensaver))
|
||||||
top_level->reset_screensaver ();
|
top_level->reset_screensaver();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Snes9x core hooks */
|
/* Snes9x core hooks */
|
||||||
void S9xMessage (int type, int number, const char *message)
|
void S9xMessage(int type, int number, const char *message)
|
||||||
{
|
{
|
||||||
switch (number)
|
switch (number)
|
||||||
{
|
{
|
||||||
case S9X_MOVIE_INFO:
|
case S9X_MOVIE_INFO:
|
||||||
S9xSetInfoString (message);
|
S9xSetInfoString(message);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Varies from ParseArgs because this one is for the OS port to handle */
|
/* Varies from ParseArgs because this one is for the OS port to handle */
|
||||||
void S9xParseArg (char **argv, int &i, int argc)
|
void S9xParseArg(char **argv, int &i, int argc)
|
||||||
{
|
{
|
||||||
if (!strcasecmp (argv[i], "-filter"))
|
if (!strcasecmp(argv[i], "-filter"))
|
||||||
{
|
{
|
||||||
if ((++i) < argc)
|
if ((++i) < argc)
|
||||||
{
|
{
|
||||||
if (!strcasecmp (argv[i], "none"))
|
if (!strcasecmp(argv[i], "none"))
|
||||||
{
|
{
|
||||||
gui_config->scale_method = FILTER_NONE;
|
gui_config->scale_method = FILTER_NONE;
|
||||||
}
|
}
|
||||||
else if (!strcasecmp (argv[i], "supereagle"))
|
else if (!strcasecmp(argv[i], "supereagle"))
|
||||||
{
|
{
|
||||||
gui_config->scale_method = FILTER_SUPEREAGLE;
|
gui_config->scale_method = FILTER_SUPEREAGLE;
|
||||||
}
|
}
|
||||||
else if (!strcasecmp (argv[i], "2xsai"))
|
else if (!strcasecmp(argv[i], "2xsai"))
|
||||||
{
|
{
|
||||||
gui_config->scale_method = FILTER_2XSAI;
|
gui_config->scale_method = FILTER_2XSAI;
|
||||||
}
|
}
|
||||||
else if (!strcasecmp (argv[i], "super2xsai"))
|
else if (!strcasecmp(argv[i], "super2xsai"))
|
||||||
{
|
{
|
||||||
gui_config->scale_method = FILTER_SUPER2XSAI;
|
gui_config->scale_method = FILTER_SUPER2XSAI;
|
||||||
}
|
}
|
||||||
#ifdef USE_HQ2X
|
#ifdef USE_HQ2X
|
||||||
else if (!strcasecmp (argv[i], "hq2x"))
|
else if (!strcasecmp(argv[i], "hq2x"))
|
||||||
{
|
{
|
||||||
gui_config->scale_method = FILTER_HQ2X;
|
gui_config->scale_method = FILTER_HQ2X;
|
||||||
}
|
}
|
||||||
else if (!strcasecmp (argv[i], "hq3x"))
|
else if (!strcasecmp(argv[i], "hq3x"))
|
||||||
{
|
{
|
||||||
gui_config->scale_method = FILTER_HQ3X;
|
gui_config->scale_method = FILTER_HQ3X;
|
||||||
}
|
}
|
||||||
else if (!strcasecmp (argv[i], "hq4x"))
|
else if (!strcasecmp(argv[i], "hq4x"))
|
||||||
{
|
{
|
||||||
gui_config->scale_method = FILTER_HQ4X;
|
gui_config->scale_method = FILTER_HQ4X;
|
||||||
}
|
}
|
||||||
#endif /* USE_HQ2X */
|
#endif /* USE_HQ2X */
|
||||||
#ifdef USE_XBRZ
|
#ifdef USE_XBRZ
|
||||||
else if (!strcasecmp (argv[i], "2xbrz"))
|
else if (!strcasecmp(argv[i], "2xbrz"))
|
||||||
{
|
{
|
||||||
gui_config->scale_method = FILTER_2XBRZ;
|
gui_config->scale_method = FILTER_2XBRZ;
|
||||||
}
|
}
|
||||||
else if (!strcasecmp (argv[i], "3xbrz"))
|
else if (!strcasecmp(argv[i], "3xbrz"))
|
||||||
{
|
{
|
||||||
gui_config->scale_method = FILTER_3XBRZ;
|
gui_config->scale_method = FILTER_3XBRZ;
|
||||||
}
|
}
|
||||||
else if (!strcasecmp (argv[i], "4xbrz"))
|
else if (!strcasecmp(argv[i], "4xbrz"))
|
||||||
{
|
{
|
||||||
gui_config->scale_method = FILTER_4XBRZ;
|
gui_config->scale_method = FILTER_4XBRZ;
|
||||||
}
|
}
|
||||||
#endif /* USE_XBRZ */
|
#endif /* USE_XBRZ */
|
||||||
else if (!strcasecmp (argv[i], "epx"))
|
else if (!strcasecmp(argv[i], "epx"))
|
||||||
{
|
{
|
||||||
gui_config->scale_method = FILTER_EPX;
|
gui_config->scale_method = FILTER_EPX;
|
||||||
}
|
}
|
||||||
else if (!strcasecmp (argv[i], "ntsc"))
|
else if (!strcasecmp(argv[i], "ntsc"))
|
||||||
{
|
{
|
||||||
gui_config->scale_method = FILTER_NTSC;
|
gui_config->scale_method = FILTER_NTSC;
|
||||||
}
|
}
|
||||||
|
@ -468,20 +459,20 @@ void S9xParseArg (char **argv, int &i, int argc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!strcasecmp (argv[i], "-mutesound"))
|
else if (!strcasecmp(argv[i], "-mutesound"))
|
||||||
{
|
{
|
||||||
gui_config->mute_sound = true;
|
gui_config->mute_sound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void S9xThrottle (int method)
|
static void S9xThrottle(int method)
|
||||||
{
|
{
|
||||||
gint64 now;
|
gint64 now;
|
||||||
|
|
||||||
if (S9xNetplaySyncSpeed ())
|
if (S9xNetplaySyncSpeed())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
now = g_get_monotonic_time ();
|
now = g_get_monotonic_time();
|
||||||
|
|
||||||
if (Settings.HighSpeedSeek > 0)
|
if (Settings.HighSpeedSeek > 0)
|
||||||
{
|
{
|
||||||
|
@ -496,8 +487,7 @@ static void S9xThrottle (int method)
|
||||||
if (Settings.TurboMode)
|
if (Settings.TurboMode)
|
||||||
{
|
{
|
||||||
IPPU.FrameSkip++;
|
IPPU.FrameSkip++;
|
||||||
if ((IPPU.FrameSkip >= Settings.TurboSkipFrames)
|
if ((IPPU.FrameSkip >= Settings.TurboSkipFrames) && !Settings.HighSpeedSeek)
|
||||||
&& !Settings.HighSpeedSeek)
|
|
||||||
{
|
{
|
||||||
IPPU.FrameSkip = 0;
|
IPPU.FrameSkip = 0;
|
||||||
IPPU.SkippedFrames = 0;
|
IPPU.SkippedFrames = 0;
|
||||||
|
@ -550,8 +540,8 @@ static void S9xThrottle (int method)
|
||||||
|
|
||||||
while (now - frame_clock < Settings.FrameTime)
|
while (now - frame_clock < Settings.FrameTime)
|
||||||
{
|
{
|
||||||
usleep (100);
|
usleep(100);
|
||||||
now = g_get_monotonic_time ();
|
now = g_get_monotonic_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_clock += Settings.FrameTime;
|
frame_clock += Settings.FrameTime;
|
||||||
|
@ -560,129 +550,47 @@ static void S9xThrottle (int method)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xSyncSpeed ()
|
void S9xSyncSpeed()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void S9xCheckPointerTimer ()
|
static void S9xCheckPointerTimer()
|
||||||
{
|
{
|
||||||
if (!gui_config->pointer_is_visible)
|
if (!gui_config->pointer_is_visible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (g_get_monotonic_time () - gui_config->pointer_timestamp > 1000000)
|
if (g_get_monotonic_time() - gui_config->pointer_timestamp > 1000000)
|
||||||
{
|
{
|
||||||
top_level->hide_mouse_cursor ();
|
top_level->hide_mouse_cursor();
|
||||||
gui_config->pointer_is_visible = false;
|
gui_config->pointer_is_visible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Final exit point, issues exit (0) */
|
/* Final exit point, issues exit (0) */
|
||||||
void S9xExit ()
|
void S9xExit()
|
||||||
{
|
{
|
||||||
gui_config->save_config_file ();
|
gui_config->save_config_file();
|
||||||
|
|
||||||
top_level->leave_fullscreen_mode ();
|
top_level->leave_fullscreen_mode();
|
||||||
|
|
||||||
S9xPortSoundDeinit ();
|
S9xPortSoundDeinit();
|
||||||
|
|
||||||
Settings.StopEmulation = true;
|
Settings.StopEmulation = true;
|
||||||
|
|
||||||
if (gui_config->rom_loaded)
|
if (gui_config->rom_loaded)
|
||||||
{
|
{
|
||||||
S9xAutoSaveSRAM ();
|
S9xAutoSaveSRAM();
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xDeinitAPU ();
|
S9xDeinitAPU();
|
||||||
|
|
||||||
S9xDeinitInputDevices ();
|
S9xDeinitInputDevices();
|
||||||
S9xDeinitDisplay ();
|
S9xDeinitDisplay();
|
||||||
|
|
||||||
gtk_main_quit ();
|
|
||||||
|
|
||||||
delete top_level;
|
delete top_level;
|
||||||
delete gui_config;
|
delete gui_config;
|
||||||
|
|
||||||
exit (0);
|
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)
|
const char *S9xStringInput(const char *message)
|
||||||
|
@ -690,12 +598,12 @@ const char *S9xStringInput(const char *message)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xExtraUsage ()
|
void S9xExtraUsage()
|
||||||
{
|
{
|
||||||
printf ("GTK port options:\n"
|
printf("GTK port options:\n"
|
||||||
"-filter [option] Use a filter to scale the image.\n"
|
"-filter [option] Use a filter to scale the image.\n"
|
||||||
" [option] is one of: none supereagle 2xsai\n"
|
" [option] is one of: none supereagle 2xsai\n"
|
||||||
" super2xsai hq2x hq3x hq4x 2xbrz 3xbrz 4xbrz epx ntsc\n"
|
" super2xsai hq2x hq3x hq4x 2xbrz 3xbrz 4xbrz epx ntsc\n"
|
||||||
"\n"
|
"\n"
|
||||||
"-mutesound Disables sound output.\n");
|
"-mutesound Disables sound output.\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,19 +8,18 @@
|
||||||
#define __GTK_S9X_H
|
#define __GTK_S9X_H
|
||||||
|
|
||||||
#include "gtk_config.h"
|
#include "gtk_config.h"
|
||||||
#include "gtk_s9xcore.h"
|
|
||||||
#include "gtk_s9xwindow.h"
|
#include "gtk_s9xwindow.h"
|
||||||
|
|
||||||
#include <glib/gi18n.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"
|
#define SNES9X_GTK_VERSION "87"
|
||||||
|
|
||||||
extern Snes9xWindow *top_level;
|
extern Snes9xWindow *top_level;
|
||||||
extern Snes9xConfig *gui_config;
|
extern Snes9xConfig *gui_config;
|
||||||
|
|
||||||
int S9xOpenROM (const char *filename);
|
int S9xOpenROM(const char *filename);
|
||||||
void S9xNoROMLoaded ();
|
void S9xNoROMLoaded();
|
||||||
void S9xROMLoaded ();
|
void S9xROMLoaded();
|
||||||
|
|
||||||
#endif /* __GTK_S9X_H */
|
#endif /* __GTK_S9X_H */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,7 +7,7 @@
|
||||||
#ifndef __GTK_S9XWINDOW_H
|
#ifndef __GTK_S9XWINDOW_H
|
||||||
#define __GTK_S9XWINDOW_H
|
#define __GTK_S9XWINDOW_H
|
||||||
|
|
||||||
#include "gtk_2_3_compat.h"
|
#include "gtk_compat.h"
|
||||||
|
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
#include "gtk_builder_window.h"
|
#include "gtk_builder_window.h"
|
||||||
|
@ -15,90 +15,105 @@
|
||||||
|
|
||||||
class Snes9xWindow : public GtkBuilderWindow
|
class Snes9xWindow : public GtkBuilderWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Snes9xWindow (Snes9xConfig *config);
|
Snes9xWindow(Snes9xConfig *config);
|
||||||
|
|
||||||
/* Pause related functions */
|
struct AcceleratorEntry
|
||||||
void pause_from_focus_change ();
|
{
|
||||||
void unpause_from_focus_change ();
|
std::string name;
|
||||||
void focus_notify (bool state);
|
unsigned int key;
|
||||||
void pause_from_user ();
|
Gdk::ModifierType modifiers;
|
||||||
void unpause_from_user ();
|
};
|
||||||
bool is_paused ();
|
|
||||||
void propagate_pause_state ();
|
|
||||||
|
|
||||||
/* Fullscreen functions */
|
/* Pause related functions */
|
||||||
void enter_fullscreen_mode ();
|
void pause_from_focus_change();
|
||||||
void leave_fullscreen_mode ();
|
void unpause_from_focus_change();
|
||||||
void toggle_fullscreen_mode ();
|
void focus_notify(bool state);
|
||||||
void finish_fullscreen ();
|
void pause_from_user();
|
||||||
|
void unpause_from_user();
|
||||||
|
bool is_paused();
|
||||||
|
void propagate_pause_state();
|
||||||
|
|
||||||
/* Cursor modifying functions */
|
/* Fullscreen functions */
|
||||||
void show_mouse_cursor ();
|
void enter_fullscreen_mode();
|
||||||
void hide_mouse_cursor ();
|
void leave_fullscreen_mode();
|
||||||
void toggle_grab_mouse ();
|
void toggle_fullscreen_mode();
|
||||||
void center_mouse ();
|
void finish_fullscreen();
|
||||||
|
|
||||||
/* Rom-related functions */
|
/* Cursor modifying functions */
|
||||||
void open_rom_dialog ();
|
void show_mouse_cursor();
|
||||||
void save_state_dialog ();
|
void hide_mouse_cursor();
|
||||||
void load_state_dialog ();
|
void toggle_grab_mouse();
|
||||||
void configure_widgets ();
|
void center_mouse();
|
||||||
void save_spc_dialog ();
|
|
||||||
bool try_open_rom (const char *filename);
|
|
||||||
const char *open_movie_dialog (bool readonly);
|
|
||||||
void movie_seek_dialog ();
|
|
||||||
void open_multicart_dialog ();
|
|
||||||
void show_rom_info ();
|
|
||||||
|
|
||||||
/* GTK-base-related functions */
|
/* Rom-related functions */
|
||||||
void show ();
|
std::string open_rom_dialog(bool run = true);
|
||||||
void set_menu_item_selected (const char *name);
|
void save_state_dialog();
|
||||||
void set_mouseable_area (int x, int y, int width, int height);
|
void load_state_dialog();
|
||||||
void set_menu_item_accel_to_binding (const char *name,
|
void configure_widgets();
|
||||||
const char *binding);
|
void save_spc_dialog();
|
||||||
void reset_screensaver ();
|
bool try_open_rom(std::string filename);
|
||||||
void update_accels ();
|
std::string open_movie_dialog(bool readonly);
|
||||||
void toggle_ui ();
|
void movie_seek_dialog();
|
||||||
void resize_to_multiple (int factor);
|
void open_multicart_dialog();
|
||||||
void resize_viewport (int width, int height);
|
void show_rom_info();
|
||||||
void expose ();
|
|
||||||
void setup_splash();
|
|
||||||
double get_refresh_rate ();
|
|
||||||
int get_auto_input_rate ();
|
|
||||||
|
|
||||||
cairo_t *get_cairo ();
|
/* GTK-base-related functions */
|
||||||
void release_cairo ();
|
void show();
|
||||||
|
void set_menu_item_selected(const char *name);
|
||||||
|
void set_mouseable_area(int x, int y, int width, int height);
|
||||||
|
void set_accelerator_to_binding(const char *name,
|
||||||
|
const char *binding);
|
||||||
|
void reset_screensaver();
|
||||||
|
void update_accelerators();
|
||||||
|
void toggle_ui();
|
||||||
|
void resize_to_multiple(int factor);
|
||||||
|
void resize_viewport(int width, int height);
|
||||||
|
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);
|
||||||
|
|
||||||
Snes9xConfig *config;
|
cairo_t *get_cairo();
|
||||||
int user_pause, sys_pause;
|
void release_cairo();
|
||||||
int last_width, last_height;
|
|
||||||
int mouse_region_x, mouse_region_y;
|
Snes9xConfig *config;
|
||||||
int mouse_region_width, mouse_region_height;
|
int user_pause, sys_pause;
|
||||||
int nfs_width, nfs_height, nfs_x, nfs_y;
|
int last_width, last_height;
|
||||||
int fullscreen_state;
|
int mouse_region_x, mouse_region_y;
|
||||||
int maximized_state;
|
int mouse_region_width, mouse_region_height;
|
||||||
bool focused;
|
int nfs_width, nfs_height, nfs_x, nfs_y;
|
||||||
bool paused_from_focus_loss;
|
int fullscreen_state;
|
||||||
double snes_mouse_x, snes_mouse_y;
|
int maximized_state;
|
||||||
double gdk_mouse_x, gdk_mouse_y;
|
bool focused;
|
||||||
bool mouse_grabbed;
|
bool paused_from_focus_loss;
|
||||||
GdkPixbuf *icon, *splash;
|
double snes_mouse_x, snes_mouse_y;
|
||||||
GdkCursor *default_cursor, *empty_cursor;
|
double gdk_mouse_x, gdk_mouse_y;
|
||||||
GtkDrawingArea *drawing_area;
|
bool mouse_grabbed;
|
||||||
GtkWidget *recent_menu;
|
GdkPixbuf *icon, *splash;
|
||||||
cairo_t *cr;
|
Gtk::DrawingArea *drawing_area;
|
||||||
bool cairo_owned;
|
Gtk::RecentChooserMenu *recent_menu;
|
||||||
#if GTK_MAJOR_VERSION >= 3
|
cairo_t *cr;
|
||||||
GdkDrawingContext *gdk_drawing_context;
|
bool cairo_owned;
|
||||||
cairo_region_t *cairo_region;
|
Glib::RefPtr<Gdk::DrawingContext> gdk_drawing_context;
|
||||||
#endif
|
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 width;
|
||||||
unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
|
unsigned int height;
|
||||||
|
unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
|
||||||
unsigned char pixel_data[256 * 224 * 3 + 1];
|
unsigned char pixel_data[256 * 224 * 3 + 1];
|
||||||
} gtk_splash_t;
|
} gtk_splash_t;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
For further information, consult the LICENSE file in the root directory.
|
For further information, consult the LICENSE file in the root directory.
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
#include "gtk_2_3_compat.h"
|
#include "gtk_compat.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
@ -13,59 +13,27 @@
|
||||||
#include "gtk_shader_parameters.h"
|
#include "gtk_shader_parameters.h"
|
||||||
#include "shaders/glsl.h"
|
#include "shaders/glsl.h"
|
||||||
|
|
||||||
static GtkWidget *dialog = NULL;
|
#include "gfx.h"
|
||||||
static std::vector<GLSLParam> *params = NULL;
|
|
||||||
|
static Gtk::Dialog *dialog = nullptr;
|
||||||
|
static std::vector<GLSLParam> *params = nullptr;
|
||||||
static std::vector<GLSLParam> saved_params;
|
static std::vector<GLSLParam> saved_params;
|
||||||
|
|
||||||
static inline double snap_to_interval(double value, double interval)
|
static inline double snap_to_interval(double value, double interval)
|
||||||
{
|
{
|
||||||
|
if (interval == 0.0)
|
||||||
|
return value;
|
||||||
return round(value / interval) * interval;
|
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;
|
gui_config->shader_parameters_width = dialog->get_width();
|
||||||
GtkAdjustment *adj = gtk_range_get_adjustment(range);
|
gui_config->shader_parameters_height = dialog->get_height();
|
||||||
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;
|
|
||||||
|
|
||||||
switch (response_id)
|
switch (response_id)
|
||||||
{
|
{
|
||||||
case GTK_RESPONSE_OK:
|
case Gtk::RESPONSE_OK:
|
||||||
{
|
{
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
std::string config_file = get_config_dir();
|
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;
|
gui_config->shader_filename = path;
|
||||||
|
|
||||||
if (dialog)
|
if (dialog)
|
||||||
gtk_widget_destroy(GTK_WIDGET(dialog));
|
delete dialog;
|
||||||
dialog = NULL;
|
dialog = nullptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GTK_RESPONSE_CANCEL:
|
case Gtk::RESPONSE_CANCEL:
|
||||||
case GTK_RESPONSE_DELETE_EVENT:
|
case Gtk::RESPONSE_DELETE_EVENT:
|
||||||
case GTK_RESPONSE_NONE:
|
case Gtk::RESPONSE_NONE:
|
||||||
if (dialog)
|
if (dialog)
|
||||||
gtk_widget_destroy(GTK_WIDGET(dialog));
|
delete dialog;
|
||||||
dialog = NULL;
|
dialog = nullptr;
|
||||||
*params = saved_params;
|
*params = saved_params;
|
||||||
if (Settings.Paused)
|
if (Settings.Paused)
|
||||||
S9xDeinitUpdate(top_level->last_width, top_level->last_height);
|
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
|
case 15: // Save As
|
||||||
{
|
{
|
||||||
auto dialog = gtk_file_chooser_dialog_new(_("Export Shader Preset to:"),
|
Gtk::FileChooserDialog dialog(_("Export Shader Preset to:"), Gtk::FILE_CHOOSER_ACTION_SAVE);
|
||||||
top_level->get_window(),
|
dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL);
|
||||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
dialog.add_button(Gtk::StockID("gtk-save"), Gtk::RESPONSE_ACCEPT);
|
||||||
"gtk-cancel", GTK_RESPONSE_CANCEL,
|
dialog.set_current_folder(gui_config->last_shader_directory);
|
||||||
"gtk-save", GTK_RESPONSE_ACCEPT,
|
|
||||||
NULL);
|
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)
|
if (gui_config->shader_filename.find(".slang") != std::string::npos)
|
||||||
{
|
{
|
||||||
name = "new.slangp";
|
name = "new.slangp";
|
||||||
|
@ -117,26 +82,23 @@ static void dialog_response(GtkDialog *pdialog, gint response_id, gpointer user_
|
||||||
name = "new.glslp";
|
name = "new.glslp";
|
||||||
extension = "*.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();
|
dialog.set_current_name(name);
|
||||||
gtk_file_filter_set_name(filter, _("Shader Preset"));
|
dialog.set_do_overwrite_confirmation();
|
||||||
gtk_file_filter_add_pattern(filter, extension);
|
|
||||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
|
|
||||||
|
|
||||||
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)
|
if (result == GTK_RESPONSE_ACCEPT)
|
||||||
{
|
S9xDisplayGetDriver()->save(dialog.get_filename().c_str());
|
||||||
auto filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
|
||||||
S9xDisplayGetDriver()->save(filename);
|
|
||||||
g_free(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_widget_destroy(dialog);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -147,8 +109,8 @@ void gtk_shader_parameters_dialog_close()
|
||||||
if (dialog)
|
if (dialog)
|
||||||
{
|
{
|
||||||
*params = saved_params;
|
*params = saved_params;
|
||||||
gtk_widget_destroy(GTK_WIDGET(dialog));
|
delete dialog;
|
||||||
dialog = NULL;
|
dialog = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +118,7 @@ bool gtk_shader_parameters_dialog(GtkWindow *parent)
|
||||||
{
|
{
|
||||||
if (dialog)
|
if (dialog)
|
||||||
{
|
{
|
||||||
gtk_window_present(GTK_WINDOW(dialog));
|
dialog->present();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,145 +128,85 @@ bool gtk_shader_parameters_dialog(GtkWindow *parent)
|
||||||
if (!params || params->size() == 0)
|
if (!params || params->size() == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
dialog = gtk_dialog_new_with_buttons(_("Shader Parameters"),
|
dialog = new Gtk::Dialog(_("Shader Parameters"), Gtk::DIALOG_DESTROY_WITH_PARENT);
|
||||||
parent,
|
dialog->add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL);
|
||||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
dialog->add_button(Gtk::StockID("gtk-save-as"), 15);
|
||||||
"gtk-cancel",
|
dialog->add_button(Gtk::StockID("gtk-save"), GTK_RESPONSE_OK);
|
||||||
GTK_RESPONSE_CANCEL,
|
dialog->signal_response().connect(sigc::ptr_fun(dialog_response));
|
||||||
"gtk-save-as",
|
|
||||||
15,
|
|
||||||
"gtk-save",
|
|
||||||
GTK_RESPONSE_OK,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
g_signal_connect_data(G_OBJECT(dialog), "response", G_CALLBACK(dialog_response), (gpointer)params, NULL, (GConnectFlags)0);
|
dialog->set_size_request(640, 480);
|
||||||
|
|
||||||
GtkWidget *scrolled_window;
|
|
||||||
gtk_widget_set_size_request(dialog, 640, 480);
|
|
||||||
if (gui_config->shader_parameters_width > 0 && gui_config->shader_parameters_height > 0)
|
if (gui_config->shader_parameters_width > 0 && gui_config->shader_parameters_height > 0)
|
||||||
{
|
dialog->resize(gui_config->shader_parameters_width, gui_config->shader_parameters_height);
|
||||||
gtk_window_resize(GTK_WINDOW(dialog),
|
|
||||||
gui_config->shader_parameters_width,
|
|
||||||
gui_config->shader_parameters_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
scrolled_window = gtk_scrolled_window_new(NULL, NULL);
|
auto scrolled_window = new Gtk::ScrolledWindow;
|
||||||
gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
|
scrolled_window->set_hexpand();
|
||||||
scrolled_window);
|
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);
|
auto grid = new Gtk::Grid;
|
||||||
|
grid->set_margin_end(5);
|
||||||
#if GTK_MAJOR_VERSION >= 3
|
grid->set_row_homogeneous();
|
||||||
|
grid->set_row_spacing(2);
|
||||||
gtk_widget_set_hexpand(scrolled_window, true);
|
grid->set_column_spacing(12);
|
||||||
gtk_widget_set_vexpand(scrolled_window, true);
|
auto vbox = new Gtk::VBox;
|
||||||
gtk_widget_set_margin_start(scrolled_window, 5);
|
vbox->pack_start(*grid);
|
||||||
gtk_widget_set_margin_end(scrolled_window, 5);
|
scrolled_window->add(*vbox);
|
||||||
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 sizegroup = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL);
|
||||||
for (unsigned int i = 0; i < params->size(); i++)
|
for (unsigned int i = 0; i < params->size(); i++)
|
||||||
{
|
{
|
||||||
GLSLParam *p = &(*params)[i];
|
GLSLParam &p = (*params)[i];
|
||||||
GtkWidget *label = gtk_label_new(p->name);
|
auto label = new Gtk::Label(p.name);
|
||||||
gtk_label_set_xalign(GTK_LABEL(label), 0.0f);
|
label->set_xalign(0.0f);
|
||||||
gtk_widget_show(label);
|
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();
|
auto check = new Gtk::CheckButton;
|
||||||
gtk_grid_attach(GTK_GRID(grid), check, 1, i, 1, 1);
|
grid->attach(*check, 1, i, 1, 1);
|
||||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), (int)p->val);
|
check->set_active(p.val);
|
||||||
g_signal_connect_data(G_OBJECT(check), "toggled", G_CALLBACK(toggled), (gpointer)p, NULL, (GConnectFlags)0);
|
check->signal_toggled().connect([check, ¶m = 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
|
else
|
||||||
{
|
{
|
||||||
GtkWidget *spin = gtk_spin_button_new_with_range(p->min, p->max, p->step);
|
auto spin = new Gtk::SpinButton(0.0, p.digits);
|
||||||
gtk_entry_set_width_chars(GTK_ENTRY(spin), 5);
|
spin->set_range(p.min, p.max);
|
||||||
gtk_grid_attach(GTK_GRID(grid), spin, 1, i, 1, 1);
|
spin->get_adjustment()->set_step_increment(p.step);
|
||||||
gtk_size_group_add_widget(sizegroup, spin);
|
spin->set_width_chars(6);
|
||||||
int digits = gtk_spin_button_get_digits(GTK_SPIN_BUTTON(spin));
|
grid->attach(*spin, 1, i, 1, 1);
|
||||||
if (digits == 2)
|
sizegroup->add_widget(*spin);
|
||||||
gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 3);
|
|
||||||
|
|
||||||
GtkAdjustment *adjustment = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(spin));
|
auto scale = new Gtk::Scale(spin->get_adjustment());
|
||||||
|
scale->set_hexpand();
|
||||||
GtkWidget *scale = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, adjustment);
|
grid->attach(*scale, 2, i, 1, 1);
|
||||||
gtk_widget_set_hexpand(scale, true);
|
scale->set_draw_value(false);
|
||||||
gtk_grid_attach(GTK_GRID(grid), scale, 2, i, 1, 1);
|
scale->set_value(p.val);
|
||||||
gtk_scale_set_draw_value(GTK_SCALE(scale), false);
|
scale->signal_value_changed().connect([spin, ¶m = p.val] {
|
||||||
gtk_range_set_value(GTK_RANGE(scale), p->val);
|
double new_value = snap_to_interval(spin->get_value(), spin->get_adjustment()->get_step_increment());
|
||||||
g_signal_connect_data(G_OBJECT(scale),
|
spin->set_value(new_value);
|
||||||
"value-changed",
|
if (param != new_value)
|
||||||
G_CALLBACK(value_changed),
|
{
|
||||||
(gpointer)p,
|
param = new_value;
|
||||||
NULL,
|
if (Settings.Paused)
|
||||||
(GConnectFlags)0);
|
S9xDeinitUpdate(top_level->last_width, top_level->last_height);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#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++)
|
dialog->show_all();
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
#ifndef __GTK_SHADER_PARAMETERS_H
|
#ifndef __GTK_SHADER_PARAMETERS_H
|
||||||
#define __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);
|
bool gtk_shader_parameters_dialog(GtkWindow *parent);
|
||||||
void gtk_shader_parameters_dialog_close ();
|
void gtk_shader_parameters_dialog_close();
|
||||||
|
|
||||||
#endif // __GTK_SHADER_PARAMETERS_H
|
#endif // __GTK_SHADER_PARAMETERS_H
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "gtk_s9x.h"
|
#include "gtk_s9x.h"
|
||||||
#include "gtk_sound.h"
|
#include "gtk_sound.h"
|
||||||
#include "gtk_sound_driver.h"
|
#include "gtk_sound_driver.h"
|
||||||
|
#include "snes9x.h"
|
||||||
|
#include "apu/apu.h"
|
||||||
|
|
||||||
#ifdef USE_PORTAUDIO
|
#ifdef USE_PORTAUDIO
|
||||||
#include "gtk_sound_driver_portaudio.h"
|
#include "gtk_sound_driver_portaudio.h"
|
||||||
|
@ -30,10 +32,9 @@ static int playback_rates[8] =
|
||||||
0, 8000, 11025, 16000, 22050, 32000, 44100, 48000
|
0, 8000, 11025, 16000, 22050, 32000, 44100, 48000
|
||||||
};
|
};
|
||||||
|
|
||||||
S9xSoundDriver *driver;
|
static S9xSoundDriver *driver;
|
||||||
|
|
||||||
int
|
int S9xSoundBase2log(int num)
|
||||||
S9xSoundBase2log (int num)
|
|
||||||
{
|
{
|
||||||
int power;
|
int power;
|
||||||
|
|
||||||
|
@ -48,14 +49,12 @@ S9xSoundBase2log (int num)
|
||||||
return power;
|
return power;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int S9xSoundPowerof2(int num)
|
||||||
S9xSoundPowerof2 (int num)
|
|
||||||
{
|
{
|
||||||
return (1 << num);
|
return (1 << num);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void S9xPortSoundInit()
|
||||||
S9xPortSoundInit ()
|
|
||||||
{
|
{
|
||||||
int pao_driver = 0;
|
int pao_driver = 0;
|
||||||
int sdl_driver = 0;
|
int sdl_driver = 0;
|
||||||
|
@ -103,34 +102,34 @@ S9xPortSoundInit ()
|
||||||
|
|
||||||
#ifdef USE_PORTAUDIO
|
#ifdef USE_PORTAUDIO
|
||||||
if (gui_config->sound_driver == pao_driver)
|
if (gui_config->sound_driver == pao_driver)
|
||||||
driver = new S9xPortAudioSoundDriver ();
|
driver = new S9xPortAudioSoundDriver();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_OSS
|
#ifdef USE_OSS
|
||||||
if (gui_config->sound_driver == oss_driver)
|
if (gui_config->sound_driver == oss_driver)
|
||||||
driver = new S9xOSSSoundDriver ();
|
driver = new S9xOSSSoundDriver();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gui_config->sound_driver == sdl_driver)
|
if (gui_config->sound_driver == sdl_driver)
|
||||||
driver = new S9xSDLSoundDriver ();
|
driver = new S9xSDLSoundDriver();
|
||||||
|
|
||||||
#ifdef USE_ALSA
|
#ifdef USE_ALSA
|
||||||
if (gui_config->sound_driver == alsa_driver)
|
if (gui_config->sound_driver == alsa_driver)
|
||||||
driver = new S9xAlsaSoundDriver ();
|
driver = new S9xAlsaSoundDriver();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PULSEAUDIO
|
#ifdef USE_PULSEAUDIO
|
||||||
if (gui_config->sound_driver == pulse_driver)
|
if (gui_config->sound_driver == pulse_driver)
|
||||||
driver = new S9xPulseSoundDriver ();
|
driver = new S9xPulseSoundDriver();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (driver != NULL)
|
if (driver != NULL)
|
||||||
{
|
{
|
||||||
driver->init ();
|
driver->init();
|
||||||
|
|
||||||
if (gui_config->auto_input_rate)
|
if (gui_config->auto_input_rate)
|
||||||
{
|
{
|
||||||
Settings.SoundInputRate = top_level->get_auto_input_rate ();
|
Settings.SoundInputRate = top_level->get_auto_input_rate();
|
||||||
if (Settings.SoundInputRate == 0.0)
|
if (Settings.SoundInputRate == 0.0)
|
||||||
{
|
{
|
||||||
Settings.SoundInputRate = 31950;
|
Settings.SoundInputRate = 31950;
|
||||||
|
@ -139,68 +138,65 @@ S9xPortSoundInit ()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Settings.SoundInputRate = CLAMP (gui_config->sound_input_rate, 31700, 32300);
|
Settings.SoundInputRate = CLAMP(gui_config->sound_input_rate, 31700, 32300);
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings.SoundPlaybackRate = playback_rates[gui_config->sound_playback_rate];
|
Settings.SoundPlaybackRate = playback_rates[gui_config->sound_playback_rate];
|
||||||
|
|
||||||
S9xInitSound(0);
|
S9xInitSound(0);
|
||||||
|
|
||||||
S9xSetSoundMute (false);
|
S9xSetSoundMute(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
S9xSetSoundMute (gui_config->mute_sound);
|
S9xSetSoundMute(gui_config->mute_sound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void S9xPortSoundReinit()
|
||||||
S9xPortSoundReinit ()
|
|
||||||
{
|
{
|
||||||
S9xPortSoundDeinit ();
|
S9xPortSoundDeinit();
|
||||||
|
|
||||||
/* Ensure the sound device is released before trying to reopen it. */
|
/* Ensure the sound device is released before trying to reopen it. */
|
||||||
sync ();
|
sync();
|
||||||
|
|
||||||
S9xPortSoundInit ();
|
S9xPortSoundInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void S9xPortSoundDeinit()
|
||||||
S9xPortSoundDeinit ()
|
|
||||||
{
|
{
|
||||||
S9xSoundStop ();
|
S9xSoundStop();
|
||||||
|
|
||||||
driver->terminate ();
|
if (driver)
|
||||||
|
driver->terminate();
|
||||||
|
|
||||||
delete driver;
|
delete driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void S9xSoundStart()
|
||||||
S9xSoundStart ()
|
|
||||||
{
|
{
|
||||||
driver->start ();
|
if (driver)
|
||||||
|
driver->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void S9xSoundStop()
|
||||||
S9xSoundStop ()
|
|
||||||
{
|
{
|
||||||
driver->stop ();
|
if (driver)
|
||||||
|
driver->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool8
|
bool8 S9xOpenSoundDevice()
|
||||||
S9xOpenSoundDevice ()
|
|
||||||
{
|
{
|
||||||
if (gui_config->mute_sound)
|
if (gui_config->mute_sound)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
gui_config->sound_buffer_size = CLAMP (gui_config->sound_buffer_size, 2, 256);
|
gui_config->sound_buffer_size = CLAMP(gui_config->sound_buffer_size, 2, 256);
|
||||||
|
|
||||||
return driver->open_device ();
|
return driver->open_device();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This really shouldn't be in the port layer */
|
/* This really shouldn't be in the port layer */
|
||||||
void
|
void S9xToggleSoundChannel(int c)
|
||||||
S9xToggleSoundChannel (int c)
|
|
||||||
{
|
{
|
||||||
static int sound_switch = 255;
|
static int sound_switch = 255;
|
||||||
|
|
||||||
|
@ -209,5 +205,5 @@ S9xToggleSoundChannel (int c)
|
||||||
else
|
else
|
||||||
sound_switch ^= 1 << c;
|
sound_switch ^= 1 << c;
|
||||||
|
|
||||||
S9xSetSoundControl (sound_switch);
|
S9xSetSoundControl(sound_switch);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include "gtk_sound_driver_alsa.h"
|
#include "gtk_sound_driver_alsa.h"
|
||||||
#include "gtk_s9x.h"
|
#include "gtk_s9x.h"
|
||||||
|
#include "snes9x.h"
|
||||||
|
#include "apu/apu.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include "gtk_sound_driver_oss.h"
|
#include "gtk_sound_driver_oss.h"
|
||||||
#include "gtk_s9x.h"
|
#include "gtk_s9x.h"
|
||||||
|
#include "snes9x.h"
|
||||||
|
#include "apu/apu.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include "gtk_sound_driver_portaudio.h"
|
#include "gtk_sound_driver_portaudio.h"
|
||||||
#include "gtk_s9x.h"
|
#include "gtk_s9x.h"
|
||||||
|
#include "apu/apu.h"
|
||||||
|
#include "snes9x.h"
|
||||||
|
|
||||||
static void port_audio_samples_available_callback(void *data)
|
static void port_audio_samples_available_callback(void *data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include "gtk_sound_driver_pulse.h"
|
#include "gtk_sound_driver_pulse.h"
|
||||||
#include "gtk_s9x.h"
|
#include "gtk_s9x.h"
|
||||||
|
#include "snes9x.h"
|
||||||
|
#include "apu/apu.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include "gtk_sound_driver_sdl.h"
|
#include "gtk_sound_driver_sdl.h"
|
||||||
#include "gtk_s9x.h"
|
#include "gtk_s9x.h"
|
||||||
|
#include "apu/apu.h"
|
||||||
|
#include "snes9x.h"
|
||||||
|
|
||||||
static void sdl_audio_callback(void *userdata, Uint8 *stream, int len)
|
static void sdl_audio_callback(void *userdata, Uint8 *stream, int len)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
#ifndef __GTK_WAYLAND_EGL_CONTEXT_H
|
#ifndef __GTK_WAYLAND_EGL_CONTEXT_H
|
||||||
#define __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_opengl_context.h"
|
||||||
|
#include "gtk_compat.h"
|
||||||
|
|
||||||
|
#include <epoxy/egl.h>
|
||||||
|
#include <wayland-egl.h>
|
||||||
|
|
||||||
class WaylandEGLContext : public OpenGLContext
|
class WaylandEGLContext : public OpenGLContext
|
||||||
{
|
{
|
||||||
|
|
|
@ -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="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>
|
<property name="layout_style">end</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="button7">
|
<object class="GtkButton" id="cheats_close">
|
||||||
<property name="label">gtk-close</property>
|
<property name="label">gtk-close</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
|
@ -351,7 +351,7 @@
|
||||||
<property name="border_width">5</property>
|
<property name="border_width">5</property>
|
||||||
<property name="spacing">5</property>
|
<property name="spacing">5</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="button4">
|
<object class="GtkButton" id="add_code">
|
||||||
<property name="label">gtk-add</property>
|
<property name="label">gtk-add</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
|
@ -369,7 +369,7 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="button5">
|
<object class="GtkButton" id="remove_code">
|
||||||
<property name="label">gtk-remove</property>
|
<property name="label">gtk-remove</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
|
@ -551,7 +551,7 @@
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<action-widgets>
|
<action-widgets>
|
||||||
<action-widget response="0">button7</action-widget>
|
<action-widget response="0">cheats_close</action-widget>
|
||||||
</action-widgets>
|
</action-widgets>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkDialog" id="frame_advance_dialog">
|
<object class="GtkDialog" id="frame_advance_dialog">
|
||||||
|
@ -2274,7 +2274,7 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="button11">
|
<object class="GtkButton" id="clear_netplay">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
|
@ -2701,7 +2701,7 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="button8">
|
<object class="GtkButton" id="about_button">
|
||||||
<property name="label">gtk-about</property>
|
<property name="label">gtk-about</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
|
@ -5446,7 +5446,7 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="button6">
|
<object class="GtkButton" id="reset_current_joypad">
|
||||||
<property name="label" translatable="yes">_Reset</property>
|
<property name="label" translatable="yes">_Reset</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
|
@ -5502,7 +5502,7 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="button12">
|
<object class="GtkButton" id="swap_with">
|
||||||
<property name="label" translatable="yes">_Swap</property>
|
<property name="label" translatable="yes">_Swap</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
|
@ -9320,7 +9320,7 @@
|
||||||
<action-widget response="-6">cancel_button</action-widget>
|
<action-widget response="-6">cancel_button</action-widget>
|
||||||
<action-widget response="-10">ok_button</action-widget>
|
<action-widget response="-10">ok_button</action-widget>
|
||||||
<action-widget response="-5">button1</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>
|
</action-widgets>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkTextBuffer" id="textbuffer1">
|
<object class="GtkTextBuffer" id="textbuffer1">
|
||||||
|
|
|
@ -7,9 +7,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
int
|
int main(int argc, char *argv[])
|
||||||
main (int argc,
|
|
||||||
char *argv[])
|
|
||||||
{
|
{
|
||||||
FILE *infile, *outfile;
|
FILE *infile, *outfile;
|
||||||
unsigned char inchar;
|
unsigned char inchar;
|
||||||
|
@ -18,49 +16,46 @@ main (int argc,
|
||||||
|
|
||||||
if (argc != 4)
|
if (argc != 4)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Usage: %s infile outfile identifier\n", argv[0]);
|
fprintf(stderr, "Usage: %s infile outfile identifier\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
stat (argv[1], &file_info);
|
stat(argv[1], &file_info);
|
||||||
|
|
||||||
infile = fopen (argv[1], "r");
|
infile = fopen(argv[1], "r");
|
||||||
|
|
||||||
if (!infile)
|
if (!infile)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Input file doesn't exist.\n");
|
fprintf(stderr, "Input file doesn't exist.\n");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
outfile = fopen (argv[2], "w+");
|
outfile = fopen(argv[2], "w+");
|
||||||
|
|
||||||
fprintf (outfile,
|
fprintf(outfile, "int %s_size = %d;\n\n", argv[3], (int)file_info.st_size);
|
||||||
"int %s_size = %d;\n\n",
|
fprintf(outfile, "unsigned char %s [] = \n{\n ", argv[3]);
|
||||||
argv[3],
|
|
||||||
(int) file_info.st_size);
|
|
||||||
fprintf (outfile, "unsigned char %s [] = \n{\n ", argv[3]);
|
|
||||||
|
|
||||||
counter = 0;
|
counter = 0;
|
||||||
|
|
||||||
while (fread (&inchar, 1, 1, infile))
|
while (fread(&inchar, 1, 1, infile))
|
||||||
{
|
{
|
||||||
if (counter >= 32)
|
if (counter >= 32)
|
||||||
{
|
{
|
||||||
counter = 0;
|
counter = 0;
|
||||||
fprintf (outfile, "\n ");
|
fprintf(outfile, "\n ");
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (outfile, "%d,", inchar);
|
fprintf(outfile, "%d,", inchar);
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Erase extra "," */
|
/* Erase extra "," */
|
||||||
fseek (outfile, -1, SEEK_CUR);
|
fseek(outfile, -1, SEEK_CUR);
|
||||||
|
|
||||||
fprintf (outfile, "\n};\n");
|
fprintf(outfile, "\n};\n");
|
||||||
|
|
||||||
fclose (infile);
|
fclose(infile);
|
||||||
fclose (outfile);
|
fclose(outfile);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
sscanf(line.c_str(), "#pragma parameter %s \"%[^\"]\" %f %f %f %f",
|
||||||
par.id, par.name, &par.val, &par.min, &par.max, &par.step);
|
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)
|
if (par.step == 0.0f)
|
||||||
par.step = 1.0f;
|
par.step = 1.0f;
|
||||||
|
|
||||||
|
|
|
@ -151,6 +151,7 @@ typedef struct
|
||||||
float max;
|
float max;
|
||||||
float val;
|
float val;
|
||||||
float step;
|
float step;
|
||||||
|
int digits;
|
||||||
GLint unif[glsl_max_passes];
|
GLint unif[glsl_max_passes];
|
||||||
} GLSLParam;
|
} GLSLParam;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue