diff --git a/src/iterate.c b/src/iterate.c index d86ecbf..92b176b 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -292,6 +292,7 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) { PyObject* chunk_render(PyObject *self, PyObject *args) { RenderState state; + PyObject *rendermode_py; int xoff, yoff; @@ -304,10 +305,8 @@ chunk_render(PyObject *self, PyObject *args) { PyObject *up_left_blocks_py; PyObject *up_right_blocks_py; - RenderModeInterface *rendermode; + RenderMode *rendermode; - void *rm_data; - PyObject *t = NULL; if (!PyArg_ParseTuple(args, "OOiiO", &state.self, &state.img, &xoff, &yoff, &state.blockdata_expanded)) @@ -318,10 +317,10 @@ chunk_render(PyObject *self, PyObject *args) { state.chunk = chunk_mod; /* set up the render mode */ - rendermode = get_render_mode(&state); - rm_data = calloc(1, rendermode->data_size); - if (rendermode->start(rm_data, &state)) { - free(rm_data); + rendermode_py = PyObject_GetAttrString(state.self, "rendermode"); + rendermode = render_mode_create(PyString_AsString(rendermode_py), &state); + Py_DECREF(rendermode_py); + if (rendermode == NULL) { return Py_BuildValue("i", "-1"); } @@ -388,7 +387,7 @@ chunk_render(PyObject *self, PyObject *args) { blockid = PyInt_FromLong(state.block); // check for occlusion - if (rendermode->occluded(rm_data, &state)) { + if (render_mode_occluded(rendermode)) { continue; } @@ -428,7 +427,7 @@ chunk_render(PyObject *self, PyObject *args) { if (mask == Py_None) mask = src; - rendermode->draw(rm_data, &state, src, mask, mask_light); + render_mode_draw(rendermode, src, mask, mask_light); } } @@ -440,8 +439,7 @@ chunk_render(PyObject *self, PyObject *args) { } /* free up the rendermode info */ - rendermode->finish(rm_data, &state); - free(rm_data); + render_mode_destroy(rendermode); Py_DECREF(blocks_py); Py_XDECREF(left_blocks_py); diff --git a/src/rendermodes.c b/src/rendermodes.c index 43658e1..4eac913 100644 --- a/src/rendermodes.c +++ b/src/rendermodes.c @@ -30,23 +30,54 @@ static RenderModeInterface *render_modes[] = { NULL }; -/* decides which render mode to use */ -RenderModeInterface *get_render_mode(RenderState *state) { +RenderMode *render_mode_create(const char *mode, RenderState *state) { unsigned int i; - /* default: NULL --> an error */ + RenderMode *ret = NULL; RenderModeInterface *iface = NULL; - PyObject *rendermode_py = PyObject_GetAttrString(state->self, "rendermode"); - const char *rendermode = PyString_AsString(rendermode_py); - for (i = 0; render_modes[i] != NULL; i++) { - if (strcmp(render_modes[i]->name, rendermode) == 0) { + if (strcmp(render_modes[i]->name, mode) == 0) { iface = render_modes[i]; break; } } - Py_DECREF(rendermode_py); - return iface; + if (iface == NULL) + return NULL; + + ret = malloc(sizeof(RenderMode)); + if (ret == NULL) + return NULL; + + ret->mode = malloc(iface->data_size); + if (ret->mode == NULL) { + free(ret); + return NULL; + } + + ret->iface = iface; + ret->state = state; + + if (iface->start(ret->mode, state)) { + free(ret->mode); + free(ret); + return NULL; + } + + return ret; +} + +void render_mode_destroy(RenderMode *self) { + self->iface->finish(self->mode, self->state); + free(self->mode); + free(self); +} + +int render_mode_occluded(RenderMode *self) { + return self->iface->occluded(self->mode, self->state); +} + +void render_mode_draw(RenderMode *self, PyObject *img, PyObject *mask, PyObject *mask_light) { + self->iface->draw(self->mode, self->state, img, mask, mask_light); } /* bindings for python -- get all the rendermode names */ diff --git a/src/rendermodes.h b/src/rendermodes.h index 80126a4..5be98eb 100644 --- a/src/rendermodes.h +++ b/src/rendermodes.h @@ -59,8 +59,19 @@ struct _RenderModeInterface { void (*draw)(void *, RenderState *, PyObject *, PyObject *, PyObject *); }; -/* figures out the render mode to use from the given ChunkRenderer */ -RenderModeInterface *get_render_mode(RenderState *state); +/* wrapper for passing around rendermodes */ +typedef struct { + void *mode; + RenderModeInterface *iface; + RenderState *state; +} RenderMode; + +/* functions for creating / using rendermodes */ +RenderMode *render_mode_create(const char *mode, RenderState *state); +void render_mode_destroy(RenderMode *self); +int render_mode_occluded(RenderMode *self); +void render_mode_draw(RenderMode *self, PyObject *img, PyObject *mask, PyObject *mask_light); + /* python bindings */ PyObject *get_render_modes(PyObject *self, PyObject *args); PyObject *get_render_mode_info(PyObject *self, PyObject *args); @@ -117,8 +128,6 @@ typedef struct { float (*calculate_darkness)(unsigned char, unsigned char); } RenderModeLighting; extern RenderModeInterface rendermode_lighting; -inline float get_lighting_coefficient(RenderModeLighting *self, RenderState *state, - int x, int y, int z, int *authoratative); /* NIGHT */ typedef struct {