diff --git a/overviewer_core/src/iterate.c b/overviewer_core/src/iterate.c index 4cc853c..0fc1109 100644 --- a/overviewer_core/src/iterate.c +++ b/overviewer_core/src/iterate.c @@ -20,14 +20,21 @@ static PyObject *textures = NULL; static PyObject *chunk_mod = NULL; static PyObject *blockmap = NULL; + +unsigned int max_blockid = 0; +unsigned int max_data = 0; +unsigned char *block_properties = NULL; + static PyObject *known_blocks = NULL; static PyObject *transparent_blocks = NULL; -static unsigned int max_blockid = 0; -static unsigned int max_data = 0; +static PyObject *solid_blocks = NULL; +static PyObject *fluid_blocks = NULL; +static PyObject *nospawn_blocks = NULL; PyObject *init_chunk_render(PyObject *self, PyObject *args) { PyObject *tmp = NULL; + unsigned int i; /* this function only needs to be called once, anything more should be * ignored */ @@ -50,12 +57,6 @@ PyObject *init_chunk_render(PyObject *self, PyObject *args) { blockmap = PyObject_GetAttrString(textures, "blockmap"); if (!blockmap) return NULL; - known_blocks = PyObject_GetAttrString(textures, "known_blocks"); - if (!known_blocks) - return NULL; - transparent_blocks = PyObject_GetAttrString(textures, "transparent_blocks"); - if (!transparent_blocks) - return NULL; tmp = PyObject_GetAttrString(textures, "max_blockid"); if (!tmp) @@ -66,23 +67,44 @@ PyObject *init_chunk_render(PyObject *self, PyObject *args) { return NULL; max_data = PyInt_AsLong(tmp); + /* assemble the property table */ + known_blocks = PyObject_GetAttrString(textures, "known_blocks"); + if (!known_blocks) + return NULL; + transparent_blocks = PyObject_GetAttrString(textures, "transparent_blocks"); + if (!transparent_blocks) + return NULL; + solid_blocks = PyObject_GetAttrString(textures, "solid_blocks"); + if (!solid_blocks) + return NULL; + fluid_blocks = PyObject_GetAttrString(textures, "fluid_blocks"); + if (!fluid_blocks) + return NULL; + nospawn_blocks = PyObject_GetAttrString(textures, "nospawn_blocks"); + if (!nospawn_blocks) + return NULL; + + block_properties = calloc(max_blockid, sizeof(unsigned char)); + for (i = 0; i < max_blockid; i++) { + PyObject *block = PyInt_FromLong(i); + + if (PySequence_Contains(known_blocks, block)) + block_properties[i] |= 1 << KNOWN; + if (PySequence_Contains(transparent_blocks, block)) + block_properties[i] |= 1 << TRANSPARENT; + if (PySequence_Contains(solid_blocks, block)) + block_properties[i] |= 1 << SOLID; + if (PySequence_Contains(fluid_blocks, block)) + block_properties[i] |= 1 << FLUID; + if (PySequence_Contains(nospawn_blocks, block)) + block_properties[i] |= 1 << NOSPAWN; + + Py_DECREF(block); + } + Py_RETURN_NONE; } -int -is_transparent(unsigned char b) { - PyObject *block = PyInt_FromLong(b); - int ret = PySequence_Contains(transparent_blocks, block); - if (!ret) - { - ret = !(PySequence_Contains(known_blocks, block)); - } - Py_DECREF(block); - return ret; - -} - - unsigned char check_adjacent_blocks(RenderState *state, int x,int y,int z, unsigned char blockid) { /* diff --git a/overviewer_core/src/overviewer.h b/overviewer_core/src/overviewer.h index 934dae8..780b298 100644 --- a/overviewer_core/src/overviewer.h +++ b/overviewer_core/src/overviewer.h @@ -86,8 +86,32 @@ typedef struct { PyObject *right_blocks; } RenderState; PyObject *init_chunk_render(PyObject *self, PyObject *args); -int is_transparent(unsigned char b); PyObject *chunk_render(PyObject *self, PyObject *args); +typedef enum +{ + KNOWN, + TRANSPARENT, + SOLID, + FLUID, + NOSPAWN, +} BlockProperty; +/* globals set in init_chunk_render, here because they're used + in block_has_property */ +extern unsigned int max_blockid; +extern unsigned int max_data; +extern unsigned char *block_properties; +static inline int +block_has_property(unsigned char b, BlockProperty prop) { + if (b >= max_blockid || !(block_properties[b] & (1 << KNOWN))) { + /* block is unknown, return defaults */ + if (prop == TRANSPARENT) + return 1; + return 0; + } + + return block_properties[b] & (1 << prop); +} +#define is_transparent(b) block_has_property((b), TRANSPARENT) /* pull in the rendermode info */ #include "rendermodes.h" diff --git a/overviewer_core/src/rendermode-overlay.c b/overviewer_core/src/rendermode-overlay.c index 72e58ff..47c44fc 100644 --- a/overviewer_core/src/rendermode-overlay.c +++ b/overviewer_core/src/rendermode-overlay.c @@ -37,10 +37,6 @@ rendermode_overlay_start(void *data, RenderState *state, PyObject *options) { Py_DECREF(facemasks_py); self->white_color = PyObject_GetAttrString(state->chunk, "white_color"); - - self->solid_blocks = PyObject_GetAttrString(state->textures, "solid_blocks"); - self->fluid_blocks = PyObject_GetAttrString(state->textures, "fluid_blocks"); - self->get_color = get_color; return 0; @@ -52,8 +48,6 @@ rendermode_overlay_finish(void *data, RenderState *state) { Py_DECREF(self->facemask_top); Py_DECREF(self->white_color); - Py_DECREF(self->solid_blocks); - Py_DECREF(self->fluid_blocks); } static int @@ -81,8 +75,7 @@ static void rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { RenderModeOverlay *self = (RenderModeOverlay *)data; unsigned char r, g, b, a; - PyObject *top_block_py, *block_py; - + // exactly analogous to edge-line code for these special blocks int increment=0; if (state->block == 44) // half-step @@ -101,27 +94,19 @@ rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject } /* check to be sure this block is solid/fluid */ - top_block_py = PyInt_FromLong(top_block); - if (PySequence_Contains(self->solid_blocks, top_block_py) || - PySequence_Contains(self->fluid_blocks, top_block_py)) { + if (block_has_property(top_block, SOLID) || block_has_property(top_block, FLUID)) { /* top block is fluid or solid, skip drawing */ - Py_DECREF(top_block_py); return; } - Py_DECREF(top_block_py); } /* check to be sure this block is solid/fluid */ - block_py = PyInt_FromLong(state->block); - if (!PySequence_Contains(self->solid_blocks, block_py) && - !PySequence_Contains(self->fluid_blocks, block_py)) { + if (!block_has_property(state->block, SOLID) && !block_has_property(state->block, FLUID)) { /* not fluid or solid, skip drawing the overlay */ - Py_DECREF(block_py); return; } - Py_DECREF(block_py); /* get our color info */ self->get_color(data, state, &r, &g, &b, &a); diff --git a/overviewer_core/src/rendermode-spawn.c b/overviewer_core/src/rendermode-spawn.c index c303f23..275f33c 100644 --- a/overviewer_core/src/rendermode-spawn.c +++ b/overviewer_core/src/rendermode-spawn.c @@ -35,13 +35,10 @@ static void get_color(void *data, RenderState *state, /* default to no overlay, until told otherwise */ *a = 0; - block_py = PyInt_FromLong(state->block); - if (PySequence_Contains(self->nospawn_blocks, block_py)) { + if (block_has_property(state->block, NOSPAWN)) { /* nothing can spawn on this */ - Py_DECREF(block_py); return; } - Py_DECREF(block_py); blocklight = getArrayByte3D(self->blocklight, x, y, MIN(127, z_light)); @@ -72,7 +69,6 @@ rendermode_spawn_start(void *data, RenderState *state, PyObject *options) { /* now do custom initializations */ self = (RenderModeSpawn *)data; - self->nospawn_blocks = PyObject_GetAttrString(state->textures, "nospawn_blocks"); self->blocklight = PyObject_GetAttrString(state->self, "blocklight"); self->skylight = PyObject_GetAttrString(state->self, "skylight"); @@ -87,7 +83,6 @@ rendermode_spawn_finish(void *data, RenderState *state) { /* first free all *our* stuff */ RenderModeSpawn* self = (RenderModeSpawn *)data; - Py_DECREF(self->nospawn_blocks); Py_DECREF(self->blocklight); Py_DECREF(self->skylight); diff --git a/overviewer_core/src/rendermodes.h b/overviewer_core/src/rendermodes.h index 1a145cf..67bd598 100644 --- a/overviewer_core/src/rendermodes.h +++ b/overviewer_core/src/rendermodes.h @@ -143,8 +143,6 @@ extern RenderModeInterface rendermode_normal; typedef struct { /* top facemask and white color image, for drawing overlays */ PyObject *facemask_top, *white_color; - /* only show overlay on top of solid or fluid blocks */ - PyObject *solid_blocks, *fluid_blocks; /* can be overridden in derived classes to control overlay alpha and color last four vars are r, g, b, a out */ @@ -195,8 +193,6 @@ typedef struct { /* inherits from overlay */ RenderModeOverlay parent; - /* used to figure out which blocks are spawnable */ - PyObject *nospawn_blocks; PyObject *skylight, *blocklight; } RenderModeSpawn; extern RenderModeInterface rendermode_spawn;