mirror of
https://github.com/libretro/RetroArch
synced 2025-03-29 22:20:21 +00:00
Remove state tracker - legacy code - we can revisit this later
and integrate it in a way so that it scales across all drivers
This commit is contained in:
parent
e1d8cdffe9
commit
f0f5c32b51
@ -508,12 +508,6 @@ ifeq ($(HAVE_STDIN_CMD), 1)
|
||||
DEFINES += -DHAVE_COMMAND -DHAVE_STDIN_CMD
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_PYTHON), 1)
|
||||
DEFINES += $(PYTHON_CFLAGS) -Wno-unused-parameter
|
||||
LIBS += $(PYTHON_LIBS)
|
||||
OBJ += gfx/drivers_tracker/video_state_python.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_EMSCRIPTEN), 1)
|
||||
OBJ += frontend/drivers/platform_emscripten.o \
|
||||
input/drivers/rwebinput_input.o \
|
||||
@ -1045,8 +1039,7 @@ endif
|
||||
|
||||
# Video
|
||||
|
||||
OBJ += gfx/drivers_context/gfx_null_ctx.o \
|
||||
gfx/video_state_tracker.o
|
||||
OBJ += gfx/drivers_context/gfx_null_ctx.o
|
||||
|
||||
ifeq ($(HAVE_KMS), 1)
|
||||
HAVE_AND_WILL_USE_DRM = 1
|
||||
|
@ -53,7 +53,6 @@ typedef struct d3d9_renderchain_driver
|
||||
bool smooth);
|
||||
bool (*render)(d3d9_video_t *d3d,
|
||||
const video_frame_info_t *video_info,
|
||||
state_tracker_t *tracker,
|
||||
const void *frame,
|
||||
unsigned width, unsigned height, unsigned pitch, unsigned rotation);
|
||||
const char *ident;
|
||||
@ -82,7 +81,6 @@ typedef struct d3d9_video
|
||||
math_matrix_4x4 mvp_rotate;
|
||||
math_matrix_4x4 mvp_transposed;
|
||||
|
||||
state_tracker_t *state_tracker;
|
||||
struct video_viewport vp;
|
||||
struct video_shader shader;
|
||||
video_info_t video_info;
|
||||
|
@ -99,51 +99,6 @@ static bool d3d9_set_resize(d3d9_video_t *d3d,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool d3d9_init_imports(d3d9_video_t *d3d)
|
||||
{
|
||||
retro_ctx_memory_info_t mem_info;
|
||||
state_tracker_t *state_tracker = NULL;
|
||||
struct state_tracker_info tracker_info = {0};
|
||||
|
||||
if (!d3d->shader.variables)
|
||||
return true;
|
||||
|
||||
mem_info.id = RETRO_MEMORY_SYSTEM_RAM;
|
||||
|
||||
core_get_memory(&mem_info);
|
||||
|
||||
tracker_info.script_class = NULL;
|
||||
tracker_info.wram = (uint8_t*)mem_info.data;
|
||||
tracker_info.info = d3d->shader.variable;
|
||||
tracker_info.info_elem = d3d->shader.variables;
|
||||
tracker_info.script = NULL;
|
||||
tracker_info.script_is_file = false;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
if (*d3d->shader.script_path)
|
||||
{
|
||||
tracker_info.script = d3d->shader.script_path;
|
||||
tracker_info.script_is_file = true;
|
||||
}
|
||||
|
||||
if (*d3d->shader.script_class)
|
||||
tracker_info.script_class = d3d->shader.script_class;
|
||||
#endif
|
||||
|
||||
state_tracker =
|
||||
state_tracker_init(&tracker_info);
|
||||
|
||||
if (!state_tracker)
|
||||
{
|
||||
RARCH_ERR("[D3D9]: Failed to initialize state tracker.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
d3d->state_tracker = state_tracker;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
extern d3d9_renderchain_driver_t cg_d3d9_renderchain;
|
||||
extern d3d9_renderchain_driver_t hlsl_d3d9_renderchain;
|
||||
|
||||
@ -334,12 +289,6 @@ static bool d3d9_init_chain(d3d9_video_t *d3d, const video_info_t *video_info)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!d3d9_init_imports(d3d))
|
||||
{
|
||||
RARCH_ERR("[D3D9]: Failed to init imports.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -622,10 +571,6 @@ static void d3d9_deinitialize(d3d9_video_t *d3d)
|
||||
d3d9_deinit_chain(d3d);
|
||||
d3d9_vertex_buffer_free(d3d->menu_display.buffer, d3d->menu_display.decl);
|
||||
|
||||
if (d3d->state_tracker)
|
||||
state_tracker_free(d3d->state_tracker);
|
||||
|
||||
d3d->state_tracker = NULL;
|
||||
d3d->menu_display.buffer = NULL;
|
||||
d3d->menu_display.decl = NULL;
|
||||
}
|
||||
@ -1682,7 +1627,6 @@ static bool d3d9_frame(void *data, const void *frame,
|
||||
|
||||
if (!d3d->renderchain_driver->render(
|
||||
d3d, video_info,
|
||||
d3d->state_tracker,
|
||||
frame, frame_width, frame_height,
|
||||
pitch, d3d->dev_rotation))
|
||||
{
|
||||
|
@ -891,34 +891,9 @@ static void d3d9_cg_renderchain_set_vertices(
|
||||
vp_width, vp_height);
|
||||
}
|
||||
|
||||
static void d3d9_cg_renderchain_set_params(
|
||||
d3d9_renderchain_t *chain,
|
||||
LPDIRECT3DDEVICE9 dev,
|
||||
struct shader_pass *pass,
|
||||
state_tracker_t *tracker,
|
||||
unsigned pass_index)
|
||||
{
|
||||
unsigned i;
|
||||
/* Set state parameters. */
|
||||
/* Only query uniforms in first pass. */
|
||||
static struct state_tracker_uniform tracker_info[GFX_MAX_VARIABLES];
|
||||
static unsigned cnt = 0;
|
||||
|
||||
if (pass_index == 1)
|
||||
cnt = state_tracker_get_uniform(tracker, tracker_info,
|
||||
GFX_MAX_VARIABLES, chain->frame_count);
|
||||
|
||||
for (i = 0; i < cnt; i++)
|
||||
{
|
||||
d3d9_cg_set_param_2f(pass->fprg, dev, tracker_info[i].id, &tracker_info[i].value);
|
||||
d3d9_cg_set_param_2f(pass->vprg, dev, tracker_info[i].id, &tracker_info[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
static void d3d9_cg_renderchain_render_pass(
|
||||
d3d9_renderchain_t *chain,
|
||||
struct shader_pass *pass,
|
||||
state_tracker_t *tracker,
|
||||
unsigned pass_index)
|
||||
{
|
||||
unsigned i;
|
||||
@ -974,9 +949,6 @@ static void d3d9_cg_renderchain_render_pass(
|
||||
if (pass_index >= 3)
|
||||
d3d9_cg_renderchain_bind_pass(chain, chain->dev, pass, pass_index);
|
||||
|
||||
if (tracker)
|
||||
d3d9_cg_renderchain_set_params(chain, chain->dev, pass, tracker, pass_index);
|
||||
|
||||
d3d9_draw_primitive(chain->dev, D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
|
||||
/* So we don't render with linear filter into render targets,
|
||||
@ -990,7 +962,6 @@ static void d3d9_cg_renderchain_render_pass(
|
||||
static bool d3d9_cg_renderchain_render(
|
||||
d3d9_video_t *d3d,
|
||||
const video_frame_info_t *video_info,
|
||||
state_tracker_t *tracker,
|
||||
const void *frame_data,
|
||||
unsigned width, unsigned height,
|
||||
unsigned pitch, unsigned rotation)
|
||||
@ -1063,7 +1034,7 @@ static bool d3d9_cg_renderchain_render(
|
||||
out_width, out_height, 0);
|
||||
|
||||
d3d9_cg_renderchain_render_pass(chain,
|
||||
from_pass, tracker,
|
||||
from_pass,
|
||||
i + 1);
|
||||
|
||||
current_width = out_width;
|
||||
@ -1093,7 +1064,6 @@ static bool d3d9_cg_renderchain_render(
|
||||
|
||||
d3d9_cg_renderchain_render_pass(chain,
|
||||
last_pass,
|
||||
tracker,
|
||||
chain->passes->count);
|
||||
|
||||
chain->frame_count++;
|
||||
|
@ -468,34 +468,9 @@ static void hlsl_d3d9_renderchain_set_final_viewport(
|
||||
d3d9_recompute_pass_sizes(chain->dev, chain, d3d);
|
||||
}
|
||||
|
||||
static void d3d9_hlsl_renderchain_set_params(
|
||||
d3d9_renderchain_t *chain,
|
||||
LPDIRECT3DDEVICE9 dev,
|
||||
struct shader_pass *pass,
|
||||
state_tracker_t *tracker,
|
||||
unsigned pass_index)
|
||||
{
|
||||
unsigned i;
|
||||
/* Set state parameters. */
|
||||
/* Only query uniforms in first pass. */
|
||||
static struct state_tracker_uniform tracker_info[GFX_MAX_VARIABLES];
|
||||
static unsigned cnt = 0;
|
||||
|
||||
if (pass_index == 1)
|
||||
cnt = state_tracker_get_uniform(tracker, tracker_info,
|
||||
GFX_MAX_VARIABLES, chain->frame_count);
|
||||
|
||||
for (i = 0; i < cnt; i++)
|
||||
{
|
||||
d3d9_hlsl_set_param_2f(pass->fprg, dev, tracker_info[i].id, &tracker_info[i].value);
|
||||
d3d9_hlsl_set_param_2f(pass->vprg, dev, tracker_info[i].id, &tracker_info[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
static void hlsl_d3d9_renderchain_render_pass(
|
||||
hlsl_renderchain_t *chain,
|
||||
struct shader_pass *pass,
|
||||
state_tracker_t *tracker,
|
||||
unsigned pass_index)
|
||||
{
|
||||
unsigned i;
|
||||
@ -553,9 +528,6 @@ static void hlsl_d3d9_renderchain_render_pass(
|
||||
d3d9_hlsl_renderchain_bind_pass(chain, chain->chain.dev, pass, pass_index);
|
||||
|
||||
#endif
|
||||
if (tracker)
|
||||
d3d9_hlsl_renderchain_set_params(&chain->chain,
|
||||
chain->chain.dev, pass, tracker, pass_index);
|
||||
|
||||
d3d9_draw_primitive(chain->chain.dev, D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
|
||||
@ -570,7 +542,6 @@ static void hlsl_d3d9_renderchain_render_pass(
|
||||
static bool hlsl_d3d9_renderchain_render(
|
||||
d3d9_video_t *d3d,
|
||||
const video_frame_info_t *video_info,
|
||||
state_tracker_t *tracker,
|
||||
const void *frame,
|
||||
unsigned width, unsigned height,
|
||||
unsigned pitch, unsigned rotation)
|
||||
@ -649,7 +620,7 @@ static bool hlsl_d3d9_renderchain_render(
|
||||
chain->chain.frame_count, 0);
|
||||
|
||||
hlsl_d3d9_renderchain_render_pass(chain,
|
||||
from_pass, tracker,
|
||||
from_pass,
|
||||
i + 1);
|
||||
|
||||
current_width = out_width;
|
||||
@ -679,7 +650,6 @@ static bool hlsl_d3d9_renderchain_render(
|
||||
chain->chain.frame_count, rotation);
|
||||
|
||||
hlsl_d3d9_renderchain_render_pass(chain, last_pass,
|
||||
tracker,
|
||||
chain->chain.passes->count);
|
||||
|
||||
chain->chain.frame_count++;
|
||||
|
@ -109,7 +109,6 @@ typedef struct cg_shader_data
|
||||
CGprofile cgFProf;
|
||||
struct shader_program_cg prg[GFX_MAX_SHADERS];
|
||||
GLuint lut_textures[GFX_MAX_TEXTURES];
|
||||
state_tracker_t *state_tracker;
|
||||
CGcontext cgCtx;
|
||||
} cg_shader_data_t;
|
||||
|
||||
@ -397,28 +396,6 @@ static void gl_cg_set_params(void *dat, void *shader_data)
|
||||
cg_gl_set_param_1f(param_v, cg->shader->parameters[i].current);
|
||||
cg_gl_set_param_1f(param_f, cg->shader->parameters[i].current);
|
||||
}
|
||||
|
||||
/* Set state parameters. */
|
||||
if (cg->state_tracker)
|
||||
{
|
||||
/* Only query uniforms in first pass. */
|
||||
static struct state_tracker_uniform tracker_info[GFX_MAX_VARIABLES];
|
||||
static unsigned cnt = 0;
|
||||
|
||||
if (cg->active_idx == 1)
|
||||
cnt = state_tracker_get_uniform(cg->state_tracker, tracker_info,
|
||||
GFX_MAX_VARIABLES, frame_count);
|
||||
|
||||
for (i = 0; i < cnt; i++)
|
||||
{
|
||||
CGparameter param_v = cgGetNamedParameter(
|
||||
cg->prg[cg->active_idx].vprg, tracker_info[i].id);
|
||||
CGparameter param_f = cgGetNamedParameter(
|
||||
cg->prg[cg->active_idx].fprg, tracker_info[i].id);
|
||||
cg_gl_set_param_1f(param_v, tracker_info[i].value);
|
||||
cg_gl_set_param_1f(param_f, tracker_info[i].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gl_cg_deinit_progs(void *data)
|
||||
@ -466,12 +443,6 @@ static void gl_cg_destroy_resources(void *data)
|
||||
memset(cg->lut_textures, 0, sizeof(cg->lut_textures));
|
||||
}
|
||||
|
||||
if (cg->state_tracker)
|
||||
{
|
||||
state_tracker_free(cg->state_tracker);
|
||||
cg->state_tracker = NULL;
|
||||
}
|
||||
|
||||
free(cg->shader);
|
||||
cg->shader = NULL;
|
||||
}
|
||||
@ -680,72 +651,6 @@ static bool gl_cg_load_plain(void *data, const char *path)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gl_cg_load_imports(void *data)
|
||||
{
|
||||
unsigned i;
|
||||
retro_ctx_memory_info_t mem_info;
|
||||
struct state_tracker_info tracker_info;
|
||||
cg_shader_data_t *cg = (cg_shader_data_t*)data;
|
||||
|
||||
if (!cg->shader->variables)
|
||||
return true;
|
||||
|
||||
for (i = 0; i < cg->shader->variables; i++)
|
||||
{
|
||||
unsigned memtype;
|
||||
|
||||
switch (cg->shader->variable[i].ram_type)
|
||||
{
|
||||
case RARCH_STATE_WRAM:
|
||||
memtype = RETRO_MEMORY_SYSTEM_RAM;
|
||||
break;
|
||||
|
||||
default:
|
||||
memtype = -1u;
|
||||
}
|
||||
|
||||
mem_info.id = memtype;
|
||||
|
||||
core_get_memory(&mem_info);
|
||||
|
||||
if ((memtype != -1u) &&
|
||||
(cg->shader->variable[i].addr >= mem_info.size))
|
||||
{
|
||||
RARCH_ERR("Address out of bounds.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mem_info.data = NULL;
|
||||
mem_info.size = 0;
|
||||
mem_info.id = RETRO_MEMORY_SYSTEM_RAM;
|
||||
|
||||
core_get_memory(&mem_info);
|
||||
|
||||
tracker_info.wram = (uint8_t*)mem_info.data;
|
||||
tracker_info.info = cg->shader->variable;
|
||||
tracker_info.info_elem = cg->shader->variables;
|
||||
tracker_info.script = NULL;
|
||||
tracker_info.script_is_file = false;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
if (*cg->shader->script_path)
|
||||
{
|
||||
tracker_info.script = cg->shader->script_path;
|
||||
tracker_info.script_is_file = true;
|
||||
}
|
||||
|
||||
tracker_info.script_class =
|
||||
*cg->shader->script_class ? cg->shader->script_class : NULL;
|
||||
#endif
|
||||
|
||||
cg->state_tracker = state_tracker_init(&tracker_info);
|
||||
if (!cg->state_tracker)
|
||||
RARCH_WARN("Failed to initialize state tracker.\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gl_cg_load_shader(void *data, unsigned i)
|
||||
{
|
||||
struct shader_program_info program_info;
|
||||
@ -829,12 +734,6 @@ static bool gl_cg_load_preset(void *data, const char *path)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gl_cg_load_imports(cg))
|
||||
{
|
||||
RARCH_ERR("Failed to load imports ...\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,6 @@ typedef struct glsl_shader_data
|
||||
struct cache_vbo vbo[GFX_MAX_SHADERS];
|
||||
struct shader_program_glsl_data prg[GFX_MAX_SHADERS];
|
||||
struct video_shader *shader;
|
||||
state_tracker_t *state_tracker;
|
||||
} glsl_shader_data_t;
|
||||
|
||||
static bool glsl_core;
|
||||
@ -660,7 +659,6 @@ static void gl_glsl_deinit_shader(glsl_shader_data_t *glsl)
|
||||
free(glsl->shader->pass[i].source.string.fragment);
|
||||
}
|
||||
|
||||
free(glsl->shader->script);
|
||||
free(glsl->shader);
|
||||
glsl->shader = NULL;
|
||||
}
|
||||
@ -695,10 +693,6 @@ static void gl_glsl_destroy_resources(glsl_shader_data_t *glsl)
|
||||
|
||||
gl_glsl_deinit_shader(glsl);
|
||||
|
||||
if (glsl->state_tracker)
|
||||
state_tracker_free(glsl->state_tracker);
|
||||
glsl->state_tracker = NULL;
|
||||
|
||||
gl_glsl_reset_attrib(glsl);
|
||||
|
||||
for (i = 0; i < GFX_MAX_SHADERS; i++)
|
||||
@ -1022,34 +1016,6 @@ static void *gl_glsl_init(void *data, const char *path)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (glsl->shader->variables)
|
||||
{
|
||||
retro_ctx_memory_info_t mem_info;
|
||||
struct state_tracker_info info;
|
||||
|
||||
mem_info.id = RETRO_MEMORY_SYSTEM_RAM;
|
||||
|
||||
core_get_memory(&mem_info);
|
||||
|
||||
info.wram = (uint8_t*)mem_info.data;
|
||||
info.info = glsl->shader->variable;
|
||||
info.info_elem = glsl->shader->variables;
|
||||
|
||||
info.script = NULL;
|
||||
info.script_class = NULL;
|
||||
#ifdef HAVE_PYTHON
|
||||
info.script = glsl->shader->script;
|
||||
if (*glsl->shader->script_class)
|
||||
info.script_class= glsl->shader->script_class;
|
||||
#endif
|
||||
info.script_is_file = false;
|
||||
|
||||
glsl->state_tracker = state_tracker_init(&info);
|
||||
|
||||
if (!glsl->state_tracker)
|
||||
RARCH_WARN("Failed to init state tracker.\n");
|
||||
}
|
||||
|
||||
glsl->prg[glsl->shader->passes + 1] = glsl->prg[0];
|
||||
glsl->uniforms[glsl->shader->passes + 1] = glsl->uniforms[0];
|
||||
|
||||
@ -1399,25 +1365,6 @@ static void gl_glsl_set_params(void *dat, void *shader_data)
|
||||
glsl->shader->parameters[i].id);
|
||||
glUniform1f(location, glsl->shader->parameters[i].current);
|
||||
}
|
||||
|
||||
/* Set state parameters. */
|
||||
if (glsl->state_tracker)
|
||||
{
|
||||
static struct state_tracker_uniform state_info[GFX_MAX_VARIABLES];
|
||||
static unsigned cnt = 0;
|
||||
|
||||
if (glsl->active_idx == 1)
|
||||
cnt = state_tracker_get_uniform(glsl->state_tracker, state_info,
|
||||
GFX_MAX_VARIABLES, frame_count);
|
||||
|
||||
for (i = 0; i < cnt; i++)
|
||||
{
|
||||
int location = glGetUniformLocation(
|
||||
glsl->prg[glsl->active_idx].id,
|
||||
state_info[i].id);
|
||||
glUniform1f(location, state_info[i].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool gl_glsl_set_mvp(void *shader_data, const void *mat_data)
|
||||
|
@ -1,438 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <compat/posix_string.h>
|
||||
#include <streams/file_stream.h>
|
||||
|
||||
#include <libretro.h>
|
||||
|
||||
#include "video_state_python.h"
|
||||
|
||||
#include "../../configuration.h"
|
||||
#include "../../dynamic.h"
|
||||
#include "../../core.h"
|
||||
#include "../../verbosity.h"
|
||||
#include "../../input/input_driver.h"
|
||||
|
||||
static PyObject* py_read_wram(PyObject *self, PyObject *args)
|
||||
{
|
||||
unsigned addr;
|
||||
size_t max;
|
||||
retro_ctx_memory_info_t mem_info;
|
||||
const uint8_t *data = NULL;
|
||||
|
||||
mem_info.id = RETRO_MEMORY_SYSTEM_RAM;
|
||||
|
||||
core_get_memory(&mem_info);
|
||||
|
||||
data = (const uint8_t*)mem_info.data;
|
||||
|
||||
(void)self;
|
||||
|
||||
if (!data)
|
||||
{
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
max = mem_info.size;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "I", &addr))
|
||||
return NULL;
|
||||
|
||||
if (addr >= max)
|
||||
{
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
return PyLong_FromLong(data[addr]);
|
||||
}
|
||||
|
||||
static PyObject* py_read_vram(PyObject *self, PyObject *args)
|
||||
{
|
||||
unsigned addr;
|
||||
size_t max;
|
||||
retro_ctx_memory_info_t mem_info;
|
||||
const uint8_t *data = NULL;
|
||||
|
||||
mem_info.id = RETRO_MEMORY_VIDEO_RAM;
|
||||
|
||||
core_get_memory(&mem_info);
|
||||
|
||||
data = (const uint8_t*)mem_info.data;
|
||||
|
||||
(void)self;
|
||||
|
||||
if (!data)
|
||||
{
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
max = mem_info.size;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "I", &addr))
|
||||
return NULL;
|
||||
|
||||
if (addr >= max)
|
||||
{
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
return PyLong_FromLong(data[addr]);
|
||||
}
|
||||
|
||||
static PyObject *py_read_input(PyObject *self, PyObject *args)
|
||||
{
|
||||
unsigned user, key, i;
|
||||
rarch_joypad_info_t joypad_info;
|
||||
const struct retro_keybind *py_binds[MAX_USERS];
|
||||
int16_t res = 0;
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
for (i = 0; i < MAX_USERS; i++)
|
||||
py_binds[i] = input_config_binds[i];
|
||||
|
||||
(void)self;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "II", &user, &key))
|
||||
return NULL;
|
||||
|
||||
if (user > MAX_USERS || user < 1 || key >= RARCH_FIRST_META_KEY)
|
||||
return NULL;
|
||||
|
||||
joypad_info.joy_idx = settings->uints.input_joypad_map[user - 1];
|
||||
joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx];
|
||||
|
||||
if (!input_driver_is_libretro_input_blocked())
|
||||
res = input_driver_input_state(joypad_info,
|
||||
py_binds,
|
||||
user - 1, RETRO_DEVICE_JOYPAD, 0, key);
|
||||
return PyBool_FromLong(res);
|
||||
}
|
||||
|
||||
static PyObject *py_read_analog(PyObject *self, PyObject *args)
|
||||
{
|
||||
unsigned user, index, id, i;
|
||||
rarch_joypad_info_t joypad_info;
|
||||
const struct retro_keybind *py_binds[MAX_USERS];
|
||||
int16_t res = 0;
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
for (i = 0; i < MAX_USERS; i++)
|
||||
py_binds[i] = input_config_binds[i];
|
||||
|
||||
(void)self;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "III", &user, &index, &id))
|
||||
return NULL;
|
||||
|
||||
if (user > MAX_USERS || user < 1 || index > 1 || id > 1)
|
||||
return NULL;
|
||||
|
||||
joypad_info.joy_idx = settings->uints.input_joypad_map[user - 1];
|
||||
joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx];
|
||||
|
||||
res = input_driver_input_state(
|
||||
joypad_info, py_binds,
|
||||
user - 1, RETRO_DEVICE_ANALOG, index, id);
|
||||
return PyFloat_FromDouble((double)res / 0x7fff);
|
||||
}
|
||||
|
||||
static PyMethodDef RarchMethods[] = {
|
||||
{ "read_wram", py_read_wram, METH_VARARGS, "Read WRAM from system." },
|
||||
{ "read_vram", py_read_vram, METH_VARARGS, "Read VRAM from system." },
|
||||
{ "input", py_read_input, METH_VARARGS, "Read input state from system." },
|
||||
{ "input_analog", py_read_analog, METH_VARARGS, "Read analog input state from system." },
|
||||
{ NULL, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
#define DECL_ATTR_RETRO(attr) PyObject_SetAttrString(mod, #attr, PyLong_FromLong(RETRO_DEVICE_ID_JOYPAD_##attr))
|
||||
static void py_set_attrs(PyObject *mod)
|
||||
{
|
||||
DECL_ATTR_RETRO(B);
|
||||
DECL_ATTR_RETRO(Y);
|
||||
DECL_ATTR_RETRO(SELECT);
|
||||
DECL_ATTR_RETRO(START);
|
||||
DECL_ATTR_RETRO(UP);
|
||||
DECL_ATTR_RETRO(DOWN);
|
||||
DECL_ATTR_RETRO(LEFT);
|
||||
DECL_ATTR_RETRO(RIGHT);
|
||||
DECL_ATTR_RETRO(A);
|
||||
DECL_ATTR_RETRO(X);
|
||||
DECL_ATTR_RETRO(L);
|
||||
DECL_ATTR_RETRO(R);
|
||||
DECL_ATTR_RETRO(L2);
|
||||
DECL_ATTR_RETRO(R2);
|
||||
DECL_ATTR_RETRO(L3);
|
||||
DECL_ATTR_RETRO(R3);
|
||||
|
||||
PyObject_SetAttrString(mod, "ANALOG_LEFT",
|
||||
PyLong_FromLong(RETRO_DEVICE_INDEX_ANALOG_LEFT));
|
||||
PyObject_SetAttrString(mod, "ANALOG_RIGHT",
|
||||
PyLong_FromLong(RETRO_DEVICE_INDEX_ANALOG_RIGHT));
|
||||
PyObject_SetAttrString(mod, "ANALOG_X",
|
||||
PyLong_FromLong(RETRO_DEVICE_ID_ANALOG_X));
|
||||
PyObject_SetAttrString(mod, "ANALOG_Y",
|
||||
PyLong_FromLong(RETRO_DEVICE_ID_ANALOG_Y));
|
||||
}
|
||||
|
||||
static PyModuleDef RarchModule = {
|
||||
PyModuleDef_HEAD_INIT, "rarch", NULL, -1, RarchMethods,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
static PyObject* PyInit_Retro(void)
|
||||
{
|
||||
PyObject *mod = PyModule_Create(&RarchModule);
|
||||
if (!mod)
|
||||
return NULL;
|
||||
|
||||
py_set_attrs(mod);
|
||||
return mod;
|
||||
}
|
||||
|
||||
struct py_state
|
||||
{
|
||||
PyObject *main;
|
||||
PyObject *dict;
|
||||
PyObject *inst;
|
||||
|
||||
bool warned_ret;
|
||||
bool warned_type;
|
||||
};
|
||||
|
||||
static char *dupe_newline(const char *str)
|
||||
{
|
||||
unsigned size;
|
||||
char *ret = NULL;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
size = strlen(str) + 2;
|
||||
ret = (char*)malloc(size);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
strlcpy(ret, str, size);
|
||||
ret[size - 2] = '\n';
|
||||
ret[size - 1] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Need to make sure that first-line indentation is 0. */
|
||||
static char *align_program(const char *program)
|
||||
{
|
||||
size_t prog_size;
|
||||
char *new_prog = NULL;
|
||||
char *save = NULL;
|
||||
char *line = NULL;
|
||||
unsigned skip_chars = 0;
|
||||
char *prog = strdup(program);
|
||||
if (!prog)
|
||||
return NULL;
|
||||
|
||||
prog_size = strlen(program) + 1;
|
||||
new_prog = (char*)calloc(1, prog_size);
|
||||
if (!new_prog)
|
||||
{
|
||||
free(prog);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
line = dupe_newline(strtok_r(prog, "\n", &save));
|
||||
if (!line)
|
||||
{
|
||||
free(prog);
|
||||
free(new_prog);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (isblank(line[skip_chars]) && line[skip_chars])
|
||||
skip_chars++;
|
||||
|
||||
while (line)
|
||||
{
|
||||
unsigned length = strlen(line);
|
||||
unsigned skip_len = skip_chars > length ? length : skip_chars;
|
||||
|
||||
strlcat(new_prog, line + skip_len, prog_size);
|
||||
|
||||
free(line);
|
||||
line = dupe_newline(strtok_r(NULL, "\n", &save));
|
||||
}
|
||||
|
||||
free(prog);
|
||||
return new_prog;
|
||||
}
|
||||
|
||||
py_state_t *py_state_new(const char *script,
|
||||
unsigned is_file, const char *pyclass)
|
||||
{
|
||||
py_state_t *handle;
|
||||
PyObject *hook;
|
||||
|
||||
RARCH_LOG("Initializing Python runtime ...\n");
|
||||
PyImport_AppendInittab("rarch", &PyInit_Retro);
|
||||
Py_Initialize();
|
||||
RARCH_LOG("Initialized Python runtime.\n");
|
||||
|
||||
handle = (py_state_t*)calloc(1, sizeof(*handle));
|
||||
hook = NULL;
|
||||
|
||||
handle->main = PyImport_AddModule("__main__");
|
||||
if (!handle->main)
|
||||
goto error;
|
||||
Py_INCREF(handle->main);
|
||||
|
||||
if (is_file)
|
||||
{
|
||||
/* Have to hack around the fact that the FILE struct
|
||||
* isn't standardized across environments.
|
||||
* PyRun_SimpleFile() breaks on Windows because it's
|
||||
* compiled with MSVC. */
|
||||
int64_t len;
|
||||
char *script_ = NULL;
|
||||
bool ret = filestream_read_file
|
||||
(script, (void**)&script_, &len);
|
||||
|
||||
if (!ret || len < 0)
|
||||
{
|
||||
RARCH_ERR("Python: Failed to read script\n");
|
||||
free(script_);
|
||||
goto error;
|
||||
}
|
||||
|
||||
PyRun_SimpleString(script_);
|
||||
free(script_);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *script_ = align_program(script);
|
||||
if (script_)
|
||||
{
|
||||
PyRun_SimpleString(script_);
|
||||
free(script_);
|
||||
}
|
||||
}
|
||||
|
||||
RARCH_LOG("Python: Script loaded.\n");
|
||||
handle->dict = PyModule_GetDict(handle->main);
|
||||
if (!handle->dict)
|
||||
{
|
||||
RARCH_ERR("Python: PyModule_GetDict() failed.\n");
|
||||
goto error;
|
||||
}
|
||||
Py_INCREF(handle->dict);
|
||||
|
||||
hook = PyDict_GetItemString(handle->dict, pyclass);
|
||||
if (!hook)
|
||||
{
|
||||
RARCH_ERR("Python: PyDict_GetItemString() failed.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
handle->inst = PyObject_CallFunction(hook, NULL);
|
||||
if (!handle->inst)
|
||||
{
|
||||
RARCH_ERR("Python: PyObject_CallFunction() failed.\n");
|
||||
goto error;
|
||||
}
|
||||
Py_INCREF(handle->inst);
|
||||
|
||||
return handle;
|
||||
|
||||
error:
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
py_state_free(handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void py_state_free(py_state_t *handle)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
|
||||
Py_CLEAR(handle->inst);
|
||||
Py_CLEAR(handle->dict);
|
||||
Py_CLEAR(handle->main);
|
||||
|
||||
free(handle);
|
||||
Py_Finalize();
|
||||
}
|
||||
|
||||
float py_state_get(py_state_t *handle, const char *id,
|
||||
unsigned frame_count)
|
||||
{
|
||||
unsigned i;
|
||||
float retval;
|
||||
PyObject *ret = NULL;
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
for (i = 0; i < MAX_USERS; i++)
|
||||
{
|
||||
struct retro_keybind *general_binds = input_config_binds[i];
|
||||
struct retro_keybind *auto_binds = input_autoconf_binds[i];
|
||||
enum analog_dpad_mode dpad_mode = settings->uints.input_analog_dpad_mode[i];
|
||||
|
||||
if (dpad_mode == ANALOG_DPAD_NONE)
|
||||
continue;
|
||||
|
||||
input_push_analog_dpad(general_binds, dpad_mode);
|
||||
input_push_analog_dpad(auto_binds, dpad_mode);
|
||||
}
|
||||
|
||||
ret = PyObject_CallMethod(handle->inst, (char*)id, (char*)"I", frame_count);
|
||||
|
||||
for (i = 0; i < MAX_USERS; i++)
|
||||
{
|
||||
struct retro_keybind *general_binds = input_config_binds[i];
|
||||
struct retro_keybind *auto_binds = input_autoconf_binds[i];
|
||||
input_pop_analog_dpad(general_binds);
|
||||
input_pop_analog_dpad(auto_binds);
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
if (!handle->warned_ret)
|
||||
{
|
||||
RARCH_WARN("Didn't get return value from script. Bug?\n");
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
handle->warned_ret = true;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
retval = (float)PyFloat_AsDouble(ret);
|
||||
Py_DECREF(ret);
|
||||
return retval;
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __VIDEO_STATE_PYTHON_H
|
||||
#define __VIDEO_STATE_PYTHON_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#ifndef PY_STATE_OMIT_DECLARATION
|
||||
typedef struct py_state py_state_t;
|
||||
#endif
|
||||
|
||||
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,
|
||||
const char *id, unsigned frame_count);
|
||||
|
||||
#endif
|
@ -570,144 +570,6 @@ bool video_shader_resolve_parameters(config_file_t *conf,
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* video_shader_parse_imports:
|
||||
* @conf : Preset file to read from.
|
||||
* @shader : Shader passes handle.
|
||||
*
|
||||
* Resolves import parameters belonging to shaders.
|
||||
*
|
||||
* Returns: true (1) if successful, otherwise false (0).
|
||||
**/
|
||||
static bool video_shader_parse_imports(config_file_t *conf,
|
||||
struct video_shader *shader)
|
||||
{
|
||||
size_t path_size = PATH_MAX_LENGTH * sizeof(char);
|
||||
const char *id = NULL;
|
||||
char *save = NULL;
|
||||
char *tmp_str = NULL;
|
||||
char *imports = (char*)malloc(1024 * sizeof(char));
|
||||
|
||||
imports[0] = '\0';
|
||||
|
||||
if (!config_get_array(conf, "imports", imports,
|
||||
1024 * sizeof(char)))
|
||||
{
|
||||
free(imports);
|
||||
return true;
|
||||
}
|
||||
|
||||
for (id = strtok_r(imports, ";", &save);
|
||||
id && shader->variables < GFX_MAX_VARIABLES;
|
||||
shader->variables++, id = strtok_r(NULL, ";", &save))
|
||||
{
|
||||
char semantic_buf[64];
|
||||
char wram_buf[64];
|
||||
char input_slot_buf[64];
|
||||
char mask_buf[64];
|
||||
char equal_buf[64];
|
||||
char semantic[64];
|
||||
unsigned addr = 0;
|
||||
unsigned mask = 0;
|
||||
unsigned equal = 0;
|
||||
struct state_tracker_uniform_info *var =
|
||||
&shader->variable[shader->variables];
|
||||
|
||||
semantic_buf[0] = wram_buf[0] = input_slot_buf[0] =
|
||||
mask_buf[0] = equal_buf[0] = semantic[0] = '\0';
|
||||
|
||||
strlcpy(var->id, id, sizeof(var->id));
|
||||
|
||||
snprintf(semantic_buf, sizeof(semantic_buf), "%s_semantic", id);
|
||||
|
||||
if (!config_get_array(conf, semantic_buf, semantic, sizeof(semantic)))
|
||||
{
|
||||
RARCH_ERR("No semantic for import variable.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
snprintf(wram_buf, sizeof(wram_buf), "%s_wram", id);
|
||||
snprintf(input_slot_buf, sizeof(input_slot_buf), "%s_input_slot", id);
|
||||
snprintf(mask_buf, sizeof(mask_buf), "%s_mask", id);
|
||||
snprintf(equal_buf, sizeof(equal_buf), "%s_equal", id);
|
||||
|
||||
if (string_is_equal(semantic, "capture"))
|
||||
var->type = RARCH_STATE_CAPTURE;
|
||||
else if (string_is_equal(semantic, "transition"))
|
||||
var->type = RARCH_STATE_TRANSITION;
|
||||
else if (string_is_equal(semantic, "transition_count"))
|
||||
var->type = RARCH_STATE_TRANSITION_COUNT;
|
||||
else if (string_is_equal(semantic, "capture_previous"))
|
||||
var->type = RARCH_STATE_CAPTURE_PREV;
|
||||
else if (string_is_equal(semantic, "transition_previous"))
|
||||
var->type = RARCH_STATE_TRANSITION_PREV;
|
||||
else if (string_is_equal(semantic, "python"))
|
||||
var->type = RARCH_STATE_PYTHON;
|
||||
else
|
||||
{
|
||||
RARCH_ERR("Invalid semantic.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (var->type != RARCH_STATE_PYTHON)
|
||||
{
|
||||
unsigned input_slot = 0;
|
||||
|
||||
if (config_get_uint(conf, input_slot_buf, &input_slot))
|
||||
{
|
||||
switch (input_slot)
|
||||
{
|
||||
case 1:
|
||||
var->ram_type = RARCH_STATE_INPUT_SLOT1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
var->ram_type = RARCH_STATE_INPUT_SLOT2;
|
||||
break;
|
||||
|
||||
default:
|
||||
RARCH_ERR("Invalid input slot for import.\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (config_get_hex(conf, wram_buf, &addr))
|
||||
{
|
||||
var->ram_type = RARCH_STATE_WRAM;
|
||||
var->addr = addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
RARCH_ERR("No address assigned to semantic.\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (config_get_hex(conf, mask_buf, &mask))
|
||||
var->mask = mask;
|
||||
if (config_get_hex(conf, equal_buf, &equal))
|
||||
var->equal = equal;
|
||||
}
|
||||
|
||||
tmp_str = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
|
||||
if (!tmp_str)
|
||||
goto error;
|
||||
|
||||
tmp_str[0] = '\0';
|
||||
if (config_get_path(conf, "import_script", tmp_str, path_size))
|
||||
strlcpy(shader->script_path, tmp_str, sizeof(shader->script_path));
|
||||
config_get_array(conf, "import_script_class",
|
||||
shader->script_class, sizeof(shader->script_class));
|
||||
free(tmp_str);
|
||||
|
||||
free(imports);
|
||||
return true;
|
||||
|
||||
error:
|
||||
free(imports);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* video_shader_read_conf_preset:
|
||||
* @conf : Preset file to read from.
|
||||
@ -799,9 +661,6 @@ bool video_shader_read_conf_preset(config_file_t *conf,
|
||||
if (!video_shader_parse_textures(conf, shader))
|
||||
return false;
|
||||
|
||||
if (!video_shader_parse_imports(conf, shader))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -863,87 +722,6 @@ static void shader_write_fbo(config_file_t *conf,
|
||||
fbo->scale_y, fbo->abs_y, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* import_semantic_to_string:
|
||||
* @type : Import semantic type from state tracker.
|
||||
*
|
||||
* Translates import semantic to human-readable string identifier.
|
||||
*
|
||||
* Returns: human-readable string identifier of import semantic.
|
||||
**/
|
||||
static const char *import_semantic_to_str(enum state_tracker_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case RARCH_STATE_CAPTURE:
|
||||
return "capture";
|
||||
case RARCH_STATE_TRANSITION:
|
||||
return "transition";
|
||||
case RARCH_STATE_TRANSITION_COUNT:
|
||||
return "transition_count";
|
||||
case RARCH_STATE_CAPTURE_PREV:
|
||||
return "capture_previous";
|
||||
case RARCH_STATE_TRANSITION_PREV:
|
||||
return "transition_previous";
|
||||
case RARCH_STATE_PYTHON:
|
||||
return "python";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "?";
|
||||
}
|
||||
|
||||
/**
|
||||
* shader_write_variable:
|
||||
* @conf : Preset file to read from.
|
||||
* @info : State tracker uniform info handle.
|
||||
*
|
||||
* Writes variable to shader preset file.
|
||||
**/
|
||||
static void shader_write_variable(config_file_t *conf,
|
||||
const struct state_tracker_uniform_info *info)
|
||||
{
|
||||
char semantic_buf[64];
|
||||
char wram_buf[64];
|
||||
char input_slot_buf[64];
|
||||
char mask_buf[64];
|
||||
char equal_buf[64];
|
||||
const char *id = info->id;
|
||||
|
||||
semantic_buf[0] = wram_buf[0] = input_slot_buf[0] =
|
||||
mask_buf[0] = equal_buf[0] = '\0';
|
||||
|
||||
snprintf(semantic_buf, sizeof(semantic_buf), "%s_semantic", id);
|
||||
snprintf(wram_buf, sizeof(wram_buf), "%s_wram", id);
|
||||
snprintf(input_slot_buf, sizeof(input_slot_buf), "%s_input_slot", id);
|
||||
snprintf(mask_buf, sizeof(mask_buf), "%s_mask", id);
|
||||
snprintf(equal_buf, sizeof(equal_buf), "%s_equal", id);
|
||||
|
||||
config_set_string(conf, semantic_buf,
|
||||
import_semantic_to_str(info->type));
|
||||
config_set_hex(conf, mask_buf, info->mask);
|
||||
config_set_hex(conf, equal_buf, info->equal);
|
||||
|
||||
switch (info->ram_type)
|
||||
{
|
||||
case RARCH_STATE_INPUT_SLOT1:
|
||||
config_set_int(conf, input_slot_buf, 1);
|
||||
break;
|
||||
|
||||
case RARCH_STATE_INPUT_SLOT2:
|
||||
config_set_int(conf, input_slot_buf, 2);
|
||||
break;
|
||||
|
||||
case RARCH_STATE_WRAM:
|
||||
config_set_hex(conf, wram_buf, info->addr);
|
||||
break;
|
||||
|
||||
case RARCH_STATE_NONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* video_shader_write_conf_preset:
|
||||
* @conf : Preset file to write to.
|
||||
@ -1096,36 +874,6 @@ void video_shader_write_conf_preset(config_file_t *conf,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*shader->script_path)
|
||||
config_set_string(conf, "import_script", shader->script_path);
|
||||
if (*shader->script_class)
|
||||
config_set_string(conf, "import_script_class", shader->script_class);
|
||||
|
||||
if (shader->variables)
|
||||
{
|
||||
size_t var_tmp = 4096 * sizeof(char);
|
||||
char *variables = (char*)malloc(var_tmp);
|
||||
|
||||
if (variables)
|
||||
{
|
||||
variables[0] = '\0';
|
||||
|
||||
strlcpy(variables, shader->variable[0].id, var_tmp);
|
||||
|
||||
for (i = 1; i < shader->variables; i++)
|
||||
{
|
||||
strlcat(variables, ";", var_tmp);
|
||||
strlcat(variables, shader->variable[i].id, var_tmp);
|
||||
}
|
||||
|
||||
config_set_string(conf, "imports", variables);
|
||||
|
||||
for (i = 0; i < shader->variables; i++)
|
||||
shader_write_variable(conf, &shader->variable[i]);
|
||||
free(variables);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *video_shader_to_str(enum rarch_shader_type type)
|
||||
@ -1297,13 +1045,6 @@ void video_shader_resolve_relative(struct video_shader *shader,
|
||||
ref_path, tmp_path, sizeof(shader->lut[i].path));
|
||||
}
|
||||
|
||||
if (*shader->script_path)
|
||||
{
|
||||
strlcpy(tmp_path, shader->script_path, tmp_path_size);
|
||||
fill_pathname_resolve_relative(shader->script_path,
|
||||
ref_path, tmp_path, sizeof(shader->script_path));
|
||||
}
|
||||
|
||||
free(tmp_path);
|
||||
}
|
||||
|
||||
|
@ -17,8 +17,6 @@
|
||||
#ifndef __VIDEO_SHADER_PARSE_H
|
||||
#define __VIDEO_SHADER_PARSE_H
|
||||
|
||||
#include "video_state_tracker.h"
|
||||
|
||||
#include <boolean.h>
|
||||
#include <retro_common_api.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
@ -142,11 +140,7 @@ struct video_shader_lut
|
||||
struct video_shader
|
||||
{
|
||||
char prefix[64];
|
||||
char script_class[512];
|
||||
char script_path[PATH_MAX_LENGTH];
|
||||
char path[PATH_MAX_LENGTH];
|
||||
char *script; /* Dynamically allocated. Must be free'd. Only used by XML. */
|
||||
|
||||
bool modern; /* Only used for XML shaders. */
|
||||
|
||||
unsigned passes;
|
||||
@ -163,7 +157,6 @@ struct video_shader
|
||||
struct video_shader_lut lut[GFX_MAX_TEXTURES];
|
||||
|
||||
struct video_shader_parameter parameters[GFX_MAX_PARAMETERS];
|
||||
struct state_tracker_uniform_info variable[GFX_MAX_VARIABLES];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,296 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <retro_inline.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
#include "drivers_tracker/video_state_python.h"
|
||||
#endif
|
||||
|
||||
#include "video_state_tracker.h"
|
||||
|
||||
#include "../input/input_driver.h"
|
||||
|
||||
#include "../verbosity.h"
|
||||
|
||||
struct state_tracker_internal
|
||||
{
|
||||
char id[64];
|
||||
|
||||
bool is_input;
|
||||
const uint16_t *input_ptr;
|
||||
const uint8_t *ptr;
|
||||
#ifdef HAVE_PYTHON
|
||||
py_state_t *py;
|
||||
#endif
|
||||
|
||||
uint32_t addr;
|
||||
uint16_t mask;
|
||||
|
||||
uint16_t equal;
|
||||
|
||||
enum state_tracker_type type;
|
||||
|
||||
uint32_t prev[2];
|
||||
int frame_count;
|
||||
int frame_count_prev;
|
||||
uint32_t old_value;
|
||||
int transition_count;
|
||||
};
|
||||
|
||||
struct state_tracker
|
||||
{
|
||||
struct state_tracker_internal *info;
|
||||
unsigned info_elem;
|
||||
|
||||
uint16_t input_state[2];
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
py_state_t *py;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* state_tracker_init:
|
||||
* @info : State tracker info handle.
|
||||
*
|
||||
* Creates and initializes graphics state tracker.
|
||||
*
|
||||
* Returns: new state tracker handle if successful, otherwise NULL.
|
||||
**/
|
||||
state_tracker_t* state_tracker_init(const struct state_tracker_info *info)
|
||||
{
|
||||
unsigned i;
|
||||
struct state_tracker_internal *tracker_info = NULL;
|
||||
state_tracker_t *tracker = (state_tracker_t*)
|
||||
calloc(1, sizeof(*tracker));
|
||||
|
||||
if (!tracker)
|
||||
return NULL;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
if (info->script)
|
||||
{
|
||||
tracker->py = py_state_new(info->script, info->script_is_file,
|
||||
info->script_class ? info->script_class : "GameAware");
|
||||
|
||||
if (!tracker->py)
|
||||
{
|
||||
RARCH_ERR("Failed to initialize Python script.\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
tracker_info = (struct state_tracker_internal*)
|
||||
calloc(info->info_elem, sizeof(struct state_tracker_internal));
|
||||
|
||||
if (!tracker_info)
|
||||
goto error;
|
||||
|
||||
tracker->info = tracker_info;
|
||||
tracker->info_elem = info->info_elem;
|
||||
|
||||
for (i = 0; i < info->info_elem; i++)
|
||||
{
|
||||
/* If we don't have a valid pointer. */
|
||||
static const uint8_t empty = 0;
|
||||
|
||||
strlcpy(tracker->info[i].id, info->info[i].id,
|
||||
sizeof(tracker->info[i].id));
|
||||
|
||||
tracker->info[i].addr = info->info[i].addr;
|
||||
tracker->info[i].type = info->info[i].type;
|
||||
tracker->info[i].mask = (info->info[i].mask == 0)
|
||||
? 0xffff : info->info[i].mask;
|
||||
tracker->info[i].equal = info->info[i].equal;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
if (info->info[i].type == RARCH_STATE_PYTHON)
|
||||
{
|
||||
if (!tracker->py)
|
||||
{
|
||||
RARCH_ERR("Python semantic was requested, but Python tracker is not loaded.\n");
|
||||
|
||||
free(tracker->info);
|
||||
goto error;
|
||||
}
|
||||
tracker->info[i].py = tracker->py;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (info->info[i].ram_type)
|
||||
{
|
||||
case RARCH_STATE_WRAM:
|
||||
tracker->info[i].ptr = info->wram ? info->wram : ∅
|
||||
break;
|
||||
case RARCH_STATE_INPUT_SLOT1:
|
||||
tracker->info[i].input_ptr = &tracker->input_state[0];
|
||||
tracker->info[i].is_input = true;
|
||||
break;
|
||||
case RARCH_STATE_INPUT_SLOT2:
|
||||
tracker->info[i].input_ptr = &tracker->input_state[1];
|
||||
tracker->info[i].is_input = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
tracker->info[i].ptr = ∅
|
||||
}
|
||||
}
|
||||
|
||||
return tracker;
|
||||
|
||||
error:
|
||||
RARCH_ERR("Allocation of state tracker info failed.\n");
|
||||
free(tracker);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* state_tracker_free:
|
||||
* @tracker : State tracker handle.
|
||||
*
|
||||
* Frees a state tracker handle.
|
||||
**/
|
||||
void state_tracker_free(state_tracker_t *tracker)
|
||||
{
|
||||
if (tracker)
|
||||
{
|
||||
free(tracker->info);
|
||||
#ifdef HAVE_PYTHON
|
||||
py_state_free(tracker->py);
|
||||
#endif
|
||||
}
|
||||
|
||||
free(tracker);
|
||||
}
|
||||
|
||||
static INLINE uint16_t state_tracker_fetch(
|
||||
const struct state_tracker_internal *info)
|
||||
{
|
||||
uint16_t val = info->ptr[info->addr];
|
||||
|
||||
if (info->is_input)
|
||||
val = *info->input_ptr;
|
||||
|
||||
val &= info->mask;
|
||||
|
||||
if (info->equal && val != info->equal)
|
||||
val = 0;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void state_tracker_update_element(
|
||||
struct state_tracker_uniform *uniform,
|
||||
struct state_tracker_internal *info,
|
||||
unsigned frame_count)
|
||||
{
|
||||
uniform->id = info->id;
|
||||
|
||||
switch (info->type)
|
||||
{
|
||||
case RARCH_STATE_CAPTURE:
|
||||
uniform->value = state_tracker_fetch(info);
|
||||
break;
|
||||
|
||||
case RARCH_STATE_CAPTURE_PREV:
|
||||
if (info->prev[0] != state_tracker_fetch(info))
|
||||
{
|
||||
info->prev[1] = info->prev[0];
|
||||
info->prev[0] = state_tracker_fetch(info);
|
||||
}
|
||||
uniform->value = info->prev[1];
|
||||
break;
|
||||
|
||||
case RARCH_STATE_TRANSITION:
|
||||
if (info->old_value != state_tracker_fetch(info))
|
||||
{
|
||||
info->old_value = state_tracker_fetch(info);
|
||||
info->frame_count = frame_count;
|
||||
}
|
||||
uniform->value = info->frame_count;
|
||||
break;
|
||||
|
||||
case RARCH_STATE_TRANSITION_COUNT:
|
||||
if (info->old_value != state_tracker_fetch(info))
|
||||
{
|
||||
info->old_value = state_tracker_fetch(info);
|
||||
info->transition_count++;
|
||||
}
|
||||
uniform->value = info->transition_count;
|
||||
break;
|
||||
|
||||
case RARCH_STATE_TRANSITION_PREV:
|
||||
if (info->old_value != state_tracker_fetch(info))
|
||||
{
|
||||
info->old_value = state_tracker_fetch(info);
|
||||
info->frame_count_prev = info->frame_count;
|
||||
info->frame_count = frame_count;
|
||||
}
|
||||
uniform->value = info->frame_count_prev;
|
||||
break;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
case RARCH_STATE_PYTHON:
|
||||
uniform->value = py_state_get(info->py, info->id, frame_count);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void state_tracker_update_input(uint16_t *input1, uint16_t *input2);
|
||||
|
||||
/**
|
||||
* state_tracker_get_uniform:
|
||||
* @tracker : State tracker handle.
|
||||
* @uniforms : State tracker uniforms.
|
||||
* @elem : Amount of uniform elements.
|
||||
* @frame_count : Frame count.
|
||||
*
|
||||
* Calls state_tracker_update_input(), and updates each uniform
|
||||
* element accordingly.
|
||||
*
|
||||
* Returns: Amount of state elements (either equal to @elem
|
||||
* or equal to @tracker->info_eleme).
|
||||
**/
|
||||
unsigned state_tracker_get_uniform(state_tracker_t *tracker,
|
||||
struct state_tracker_uniform *uniforms,
|
||||
unsigned elem, unsigned frame_count)
|
||||
{
|
||||
unsigned i, elems = elem;
|
||||
|
||||
if (tracker->info_elem < elem)
|
||||
elems = tracker->info_elem;
|
||||
|
||||
state_tracker_update_input(&tracker->input_state[0], &tracker->input_state[1]);
|
||||
|
||||
for (i = 0; i < elems; i++)
|
||||
state_tracker_update_element(
|
||||
&uniforms[i], &tracker->info[i], frame_count);
|
||||
|
||||
return elems;
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __VIDEO_STATE_TRACKER_H
|
||||
#define __VIDEO_STATE_TRACKER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
enum state_tracker_type
|
||||
{
|
||||
RARCH_STATE_CAPTURE = 0,
|
||||
RARCH_STATE_CAPTURE_PREV,
|
||||
RARCH_STATE_TRANSITION,
|
||||
RARCH_STATE_TRANSITION_COUNT,
|
||||
RARCH_STATE_TRANSITION_PREV,
|
||||
RARCH_STATE_PYTHON
|
||||
};
|
||||
|
||||
enum state_ram_type
|
||||
{
|
||||
RARCH_STATE_NONE,
|
||||
RARCH_STATE_WRAM,
|
||||
RARCH_STATE_INPUT_SLOT1,
|
||||
RARCH_STATE_INPUT_SLOT2
|
||||
};
|
||||
|
||||
struct state_tracker_uniform_info
|
||||
{
|
||||
enum state_tracker_type type;
|
||||
enum state_ram_type ram_type;
|
||||
char id[64];
|
||||
uint16_t mask;
|
||||
uint16_t equal;
|
||||
uint32_t addr;
|
||||
};
|
||||
|
||||
struct state_tracker_info
|
||||
{
|
||||
const char *script;
|
||||
const char *script_class;
|
||||
bool script_is_file;
|
||||
const uint8_t *wram;
|
||||
unsigned info_elem;
|
||||
const struct state_tracker_uniform_info *info;
|
||||
};
|
||||
|
||||
struct state_tracker_uniform
|
||||
{
|
||||
const char *id;
|
||||
float value;
|
||||
};
|
||||
|
||||
typedef struct state_tracker state_tracker_t;
|
||||
|
||||
/**
|
||||
* state_tracker_init:
|
||||
* @info : State tracker info handle.
|
||||
*
|
||||
* Creates and initializes graphics state tracker.
|
||||
*
|
||||
* Returns: new state tracker handle if successful, otherwise NULL.
|
||||
**/
|
||||
state_tracker_t* state_tracker_init(const struct state_tracker_info *info);
|
||||
|
||||
/**
|
||||
* state_tracker_free:
|
||||
* @tracker : State tracker handle.
|
||||
*
|
||||
* Frees a state tracker handle.
|
||||
**/
|
||||
void state_tracker_free(state_tracker_t *tracker);
|
||||
|
||||
/**
|
||||
* state_tracker_get_uniform:
|
||||
* @tracker : State tracker handle.
|
||||
* @uniforms : State tracker uniforms.
|
||||
* @elem : Amount of uniform elements.
|
||||
* @frame_count : Frame count.
|
||||
*
|
||||
* Calls update_input(), and updates each uniform
|
||||
* element accordingly.
|
||||
*
|
||||
* Returns: Amount of state elements (either equal to @elem
|
||||
* or equal to @tracker->info_eleme).
|
||||
**/
|
||||
unsigned state_tracker_get_uniform(state_tracker_t *tracker,
|
||||
struct state_tracker_uniform *uniforms,
|
||||
unsigned elem, unsigned frame_count);
|
||||
|
||||
void state_tracker_update_input(uint16_t *input1, uint16_t *input2);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
@ -729,15 +729,6 @@ INPUT (HID)
|
||||
#include "../input/drivers_keyboard/keyboard_event_xkb.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
STATE TRACKER
|
||||
============================================================ */
|
||||
#include "../gfx/video_state_tracker.c"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
#include "../gfx/drivers_tracker/video_state_python.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
FIFO BUFFER
|
||||
============================================================ */
|
||||
|
@ -484,8 +484,6 @@ else
|
||||
check_lib '' VULKAN -lvulkan vkCreateInstance
|
||||
fi
|
||||
|
||||
check_pkgconf PYTHON 'python3 python3 python-3.7 python-3.6 python-3.5 python-3.4 python-3.3 python-3.2'
|
||||
|
||||
if [ "$HAVE_MENU" != 'no' ]; then
|
||||
if [ "$HAVE_OPENGL" = 'no' ] && [ "$HAVE_OPENGLES" = 'no' ] && [ "$HAVE_VULKAN" = 'no' ]; then
|
||||
if [ "$OS" = 'Win32' ]; then
|
||||
|
@ -103,8 +103,6 @@ HAVE_STB_IMAGE=yes # stb image loading support
|
||||
HAVE_STB_VORBIS=yes # stb vorbis support
|
||||
HAVE_IBXM=yes # IBXM support
|
||||
HAVE_XVIDEO=auto # XVideo support
|
||||
HAVE_PYTHON=no # Python 3 support for shaders
|
||||
C89_PYTHON=no
|
||||
HAVE_V4L2=auto # Video4linux2 support
|
||||
HAVE_NEON=no # ARM NEON optimizations
|
||||
HAVE_SSE=no # x86 SSE optimizations (SSE, SSE2)
|
||||
|
65
retroarch.c
65
retroarch.c
@ -3659,71 +3659,6 @@ int16_t input_state(unsigned port, unsigned device,
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* state_tracker_update_input:
|
||||
*
|
||||
* Updates 16-bit input in same format as libretro API itself.
|
||||
**/
|
||||
void state_tracker_update_input(uint16_t *input1, uint16_t *input2)
|
||||
{
|
||||
unsigned i;
|
||||
const struct retro_keybind *binds[MAX_USERS];
|
||||
settings_t *settings = configuration_settings;
|
||||
uint8_t max_users = (uint8_t)input_driver_max_users;
|
||||
|
||||
for (i = 0; i < max_users; i++)
|
||||
{
|
||||
struct retro_keybind *general_binds = input_config_binds[i];
|
||||
struct retro_keybind *auto_binds = input_autoconf_binds[i];
|
||||
enum analog_dpad_mode dpad_mode = (enum analog_dpad_mode)settings->uints.input_analog_dpad_mode[i];
|
||||
binds[i] = input_config_binds[i];
|
||||
|
||||
if (dpad_mode == ANALOG_DPAD_NONE)
|
||||
continue;
|
||||
|
||||
input_push_analog_dpad(general_binds, dpad_mode);
|
||||
input_push_analog_dpad(auto_binds, dpad_mode);
|
||||
}
|
||||
|
||||
if (!input_driver_block_libretro_input)
|
||||
{
|
||||
rarch_joypad_info_t joypad_info;
|
||||
joypad_info.axis_threshold = input_driver_axis_threshold;
|
||||
|
||||
for (i = 4; i < 16; i++)
|
||||
{
|
||||
unsigned id = buttons[i - 4];
|
||||
|
||||
if (binds[0][id].valid)
|
||||
{
|
||||
joypad_info.joy_idx = settings->uints.input_joypad_map[0];
|
||||
joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx];
|
||||
*input1 |= (current_input->input_state(current_input_data, joypad_info,
|
||||
binds,
|
||||
0, RETRO_DEVICE_JOYPAD, 0, id) ? 1 : 0) << i;
|
||||
}
|
||||
|
||||
if (binds[1][id].valid)
|
||||
{
|
||||
joypad_info.joy_idx = settings->uints.input_joypad_map[1];
|
||||
joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx];
|
||||
*input2 |= (current_input->input_state(current_input_data, joypad_info,
|
||||
binds,
|
||||
1, RETRO_DEVICE_JOYPAD, 0, id) ? 1 : 0) << i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < max_users; i++)
|
||||
{
|
||||
struct retro_keybind *general_binds = input_config_binds[i];
|
||||
struct retro_keybind *auto_binds = input_autoconf_binds[i];
|
||||
|
||||
input_pop_analog_dpad(general_binds);
|
||||
input_pop_analog_dpad(auto_binds);
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE bool input_keys_pressed_other_sources(unsigned i,
|
||||
input_bits_t* p_new_state)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user