diff --git a/Makefile.win b/Makefile.win index d855e0fb31..c06463383f 100644 --- a/Makefile.win +++ b/Makefile.win @@ -30,7 +30,7 @@ libsnes ?= -lsnes LIBS = -lm -lshlwapi DEFINES = -I. -DHAVE_CONFIGFILE -LDFLAGS = -L. -static-libgcc -s +LDFLAGS = -L. -static-libgcc LDCXXFLAGS = -static-libstdc++ ifeq ($(HAVE_SDL), 1) diff --git a/gfx/ext.c b/gfx/ext.c index 5bc1fb5301..c5dfc94ea5 100644 --- a/gfx/ext.c +++ b/gfx/ext.c @@ -31,6 +31,11 @@ #include "fonts.h" #endif +#ifdef HAVE_PYTHON +#define PY_STATE_OMIT_DECLARATION +#include "py_state/py_state.h" +#endif + static bool g_input_dead = true; static bool g_video_dead = true; static dylib_t g_lib = NULL; @@ -279,6 +284,12 @@ static bool setup_video(ext_t *ext, const video_info_t *video, const input_drive .ttf_font_size = g_settings.video.font_size, .ttf_font_color = (font_color_r << 16) | (font_color_g << 8) | (font_color_b << 0), .title_hint = title_buf, + +#ifdef HAVE_PYTHON + .python_state_new = py_state_new, + .python_state_get = py_state_get, + .python_state_free = py_state_free, +#endif }; const ssnes_input_driver_t *input_driver = NULL; diff --git a/gfx/ext/ssnes_video.h b/gfx/ext/ssnes_video.h index 548d752479..8701e5b7ab 100644 --- a/gfx/ext/ssnes_video.h +++ b/gfx/ext/ssnes_video.h @@ -6,6 +6,8 @@ #ifndef __SSNES_VIDEO_DRIVER_H #define __SSNES_VIDEO_DRIVER_H +#include + #ifdef __cplusplus extern "C" { #endif @@ -22,10 +24,10 @@ extern "C" { #define SSNES_API_CALLTYPE #endif -#define SSNES_GRAPHICS_API_VERSION 1 +#define SSNES_GRAPHICS_API_VERSION 2 // Since we don't want to rely on C++ or C99 for a proper boolean type, -// and make sure return semantics are perfectly clear ... ;) +// make sure return semantics are perfectly clear ... ;) #ifndef SSNES_OK #define SSNES_OK 1 @@ -48,6 +50,21 @@ extern "C" { #define SSNES_INPUT_SCALE_BASE 256 +typedef struct py_state py_state_t; + +// Create a new runtime for Python. +// py_script: The python script to be loaded. If is_file is true, this will be the full path to a file. +// If false, it will be an UTF-8 encoded string of the script. +// is_file: Tells if py_script is the path to a script, or a script itself. +// py_class: name of the class being instantiated. +typedef py_state_t *(*python_state_new_cb)(const char *py_script, unsigned is_file, const char *py_class); +// Grabs a value from the Python runtime. +// id: The uniform (class method) to be called. +// frame_count: Passes frame_count as an argument to the script. +typedef float (*python_state_get_cb)(py_state_t *handle, const char *id, unsigned frame_count); +// Frees the runtime. +typedef void (*python_state_free_cb)(py_state_t *handle); + typedef struct ssnes_video_info { // Width of window. @@ -111,6 +128,13 @@ typedef struct ssnes_video_info // A title that should be displayed in the title bar of the window. const char *title_hint; + + // Functions to peek into the python runtime for shaders. + // Check typedefs above for explanation. + // These may be NULL if SSNES is not built with Python support. + python_state_new_cb python_state_new; + python_state_get_cb python_state_get; + python_state_free_cb python_state_free; } ssnes_video_info_t; // Some convenience macros. diff --git a/gfx/py_state/py_state.c b/gfx/py_state/py_state.c index 4c457f64b0..58d466c669 100644 --- a/gfx/py_state/py_state.c +++ b/gfx/py_state/py_state.c @@ -242,7 +242,7 @@ static char *align_program(const char *program) return new_prog; } -py_state_t *py_state_new(const char *script, bool is_file, const char *pyclass) +py_state_t *py_state_new(const char *script, unsigned is_file, const char *pyclass) { SSNES_LOG("Initializing Python runtime ...\n"); PyImport_AppendInittab("snes", &PyInit_SNES); diff --git a/gfx/py_state/py_state.h b/gfx/py_state/py_state.h index 4dc4761e7c..7bf873bb62 100644 --- a/gfx/py_state/py_state.h +++ b/gfx/py_state/py_state.h @@ -21,9 +21,11 @@ #include #include +#ifndef PY_STATE_OMIT_DECLARATION typedef struct py_state py_state_t; +#endif -py_state_t *py_state_new(const char *program, bool is_file, const char *pyclass); +py_state_t *py_state_new(const char *program, unsigned is_file, const char *pyclass); void py_state_free(py_state_t *handle); float py_state_get(py_state_t *handle,