mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-14 06:18:34 +00:00
Inline XML python.
This commit is contained in:
parent
e02d9f41e8
commit
3717f7442c
@ -17,11 +17,15 @@
|
||||
|
||||
#include <Python.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "dynamic.h"
|
||||
#include "libsnes.hpp"
|
||||
#include <stdlib.h>
|
||||
#include "py_state.h"
|
||||
#include "general.h"
|
||||
#include "strl.h"
|
||||
|
||||
#define PY_READ_FUNC_DECL(RAMTYPE) py_read_##RAMTYPE
|
||||
#define PY_READ_FUNC(RAMTYPE) \
|
||||
@ -85,7 +89,62 @@ struct py_state
|
||||
bool warned_type;
|
||||
};
|
||||
|
||||
py_state_t *py_state_new(const char *script_path, const char *pyclass)
|
||||
static char *dupe_newline(const char *str)
|
||||
{
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
unsigned size = strlen(str) + 2;
|
||||
char *ret = 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)
|
||||
{
|
||||
char *prog = strdup(program);
|
||||
if (!prog)
|
||||
return NULL;
|
||||
|
||||
size_t prog_size = strlen(program) + 1;
|
||||
char *new_prog = calloc(1, prog_size);
|
||||
if (!new_prog)
|
||||
return NULL;
|
||||
|
||||
char *line = dupe_newline(strtok(prog, "\n"));
|
||||
if (!line)
|
||||
{
|
||||
free(prog);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned skip_chars = 0;
|
||||
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(NULL, "\n"));
|
||||
}
|
||||
|
||||
free(prog);
|
||||
|
||||
return new_prog;
|
||||
}
|
||||
|
||||
py_state_t *py_state_new(const char *script, bool is_file, const char *pyclass)
|
||||
{
|
||||
PyImport_AppendInittab("snes", &PyInit_SNES);
|
||||
Py_Initialize();
|
||||
@ -96,11 +155,23 @@ py_state_t *py_state_new(const char *script_path, const char *pyclass)
|
||||
if (!handle->main)
|
||||
goto error;
|
||||
|
||||
FILE *file = fopen(script_path, "r");
|
||||
if (!file)
|
||||
goto error;
|
||||
PyRun_SimpleFile(file, script_path);
|
||||
fclose(file);
|
||||
if (is_file)
|
||||
{
|
||||
FILE *file = fopen(script, "r");
|
||||
if (!file)
|
||||
goto error;
|
||||
PyRun_SimpleFile(file, script);
|
||||
fclose(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *script_ = align_program(script);
|
||||
if (script_)
|
||||
{
|
||||
PyRun_SimpleString(script_);
|
||||
free(script_);
|
||||
}
|
||||
}
|
||||
|
||||
handle->dict = PyModule_GetDict(handle->main);
|
||||
if (!handle->dict)
|
||||
|
@ -19,10 +19,11 @@
|
||||
#define __SSNES_PY_STATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct py_state py_state_t;
|
||||
|
||||
py_state_t *py_state_new(const char *program, const char *pyclass);
|
||||
py_state_t *py_state_new(const char *program, bool is_file, const char *pyclass);
|
||||
void py_state_free(py_state_t *handle);
|
||||
|
||||
int py_state_get(py_state_t *handle,
|
||||
|
@ -527,6 +527,8 @@ static bool load_imports(const char *dir_path, config_file_t *conf)
|
||||
}
|
||||
if (config_get_string(conf, "import_script_class", &script_class))
|
||||
tracker_info.script_class = script_class;
|
||||
|
||||
tracker_info.script_is_file = true;
|
||||
#endif
|
||||
|
||||
snes_tracker = snes_tracker_init(&tracker_info);
|
||||
|
@ -118,6 +118,7 @@ static struct snes_tracker_uniform_info gl_tracker_info[MAX_VARIABLES];
|
||||
static unsigned gl_tracker_info_cnt = 0;
|
||||
static char gl_tracker_script[256];
|
||||
static char gl_tracker_script_class[64];
|
||||
static xmlChar *gl_script_program = NULL;
|
||||
|
||||
struct shader_program
|
||||
{
|
||||
@ -380,6 +381,43 @@ error:
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool get_script(xmlNodePtr ptr)
|
||||
{
|
||||
if (*gl_tracker_script)
|
||||
{
|
||||
SSNES_ERR("Script already imported.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
xmlChar *script_class = xmlGetProp(ptr, (const xmlChar*)"class");
|
||||
if (script_class)
|
||||
{
|
||||
strlcpy(gl_tracker_script_class, (const char*)script_class, sizeof(gl_tracker_script_class));
|
||||
xmlFree(script_class);
|
||||
}
|
||||
|
||||
xmlChar *language = xmlGetProp(ptr, (const xmlChar*)"language");
|
||||
if (!language || strcmp((const char*)language, "python") != 0)
|
||||
{
|
||||
SSNES_ERR("Script language is not Python!\n");
|
||||
if (language)
|
||||
xmlFree(language);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (language)
|
||||
xmlFree(language);
|
||||
|
||||
xmlChar *script = xmlNodeGetContent(ptr);
|
||||
if (!script)
|
||||
{
|
||||
SSNES_ERR("No content in script!\n");
|
||||
return false;
|
||||
}
|
||||
gl_script_program = script;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool get_import_value(const char *path, xmlNodePtr ptr)
|
||||
{
|
||||
if (gl_tracker_info_cnt >= MAX_VARIABLES)
|
||||
@ -390,7 +428,7 @@ static bool get_import_value(const char *path, xmlNodePtr ptr)
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
xmlChar *script = xmlGetProp(ptr, (const xmlChar*)"script");
|
||||
if (script && *gl_tracker_script)
|
||||
if (script && (*gl_tracker_script || gl_script_program))
|
||||
{
|
||||
SSNES_ERR("Cannot define more than one script!\n");
|
||||
return false;
|
||||
@ -635,6 +673,14 @@ static unsigned get_xml_shaders(const char *path, struct shader_program *prog, s
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (strcmp((const char*)cur->name, "script") == 0)
|
||||
{
|
||||
if (!get_script(cur))
|
||||
{
|
||||
SSNES_ERR("Script is invalid.\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (num == 0)
|
||||
@ -860,11 +906,20 @@ bool gl_glsl_init(const char *path)
|
||||
.oam = psnes_get_memory_data(SNES_MEMORY_OAM),
|
||||
.info = gl_tracker_info,
|
||||
.info_elem = gl_tracker_info_cnt,
|
||||
#ifdef HAVE_PYTHON
|
||||
.script = *gl_tracker_script ? gl_tracker_script : NULL,
|
||||
.script_class = *gl_tracker_script_class ? gl_tracker_script_class : NULL
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
if (*gl_tracker_script)
|
||||
info.script = gl_tracker_script;
|
||||
else if (gl_script_program)
|
||||
info.script = (const char*)gl_script_program;
|
||||
else
|
||||
info.script = NULL;
|
||||
|
||||
info.script_class = *gl_tracker_script_class ? gl_tracker_script_class : NULL;
|
||||
info.script_is_file = *gl_tracker_script;
|
||||
#endif
|
||||
|
||||
gl_snes_tracker = snes_tracker_init(&info);
|
||||
if (!gl_snes_tracker)
|
||||
SSNES_WARN("Failed to init SNES tracker!\n");
|
||||
@ -911,6 +966,11 @@ void gl_glsl_deinit(void)
|
||||
memset(gl_tracker_info, 0, sizeof(gl_tracker_info));
|
||||
memset(gl_tracker_script, 0, sizeof(gl_tracker_script));
|
||||
memset(gl_tracker_script_class, 0, sizeof(gl_tracker_script_class));
|
||||
if (gl_script_program)
|
||||
{
|
||||
xmlFree(gl_script_program);
|
||||
gl_script_program = NULL;
|
||||
}
|
||||
if (gl_snes_tracker)
|
||||
{
|
||||
snes_tracker_free(gl_snes_tracker);
|
||||
|
@ -64,7 +64,7 @@ snes_tracker_t* snes_tracker_init(const struct snes_tracker_info *info)
|
||||
#ifdef HAVE_PYTHON
|
||||
if (info->script)
|
||||
{
|
||||
tracker->py = py_state_new(info->script, info->script_class ? info->script_class : "GameAware");
|
||||
tracker->py = py_state_new(info->script, info->script_is_file, info->script_class ? info->script_class : "GameAware");
|
||||
if (!tracker->py)
|
||||
{
|
||||
free(tracker);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#define __SSNES_SNES_STATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
@ -68,6 +69,7 @@ struct snes_tracker_info
|
||||
#ifdef HAVE_PYTHON
|
||||
const char *script;
|
||||
const char *script_class;
|
||||
bool script_is_file;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user