diff --git a/overviewer_core/src/iterate.c b/overviewer_core/src/iterate.c index 47e175b..4cc853c 100644 --- a/overviewer_core/src/iterate.c +++ b/overviewer_core/src/iterate.c @@ -22,9 +22,13 @@ static PyObject *chunk_mod = NULL; static PyObject *blockmap = NULL; static PyObject *known_blocks = NULL; static PyObject *transparent_blocks = NULL; +static unsigned int max_blockid = 0; +static unsigned int max_data = 0; PyObject *init_chunk_render(PyObject *self, PyObject *args) { + PyObject *tmp = NULL; + /* this function only needs to be called once, anything more should be * ignored */ if (blockmap) { @@ -53,6 +57,15 @@ PyObject *init_chunk_render(PyObject *self, PyObject *args) { if (!transparent_blocks) return NULL; + tmp = PyObject_GetAttrString(textures, "max_blockid"); + if (!tmp) + return NULL; + max_blockid = PyInt_AsLong(tmp); + tmp = PyObject_GetAttrString(textures, "max_data"); + if (!tmp) + return NULL; + max_data = PyInt_AsLong(tmp); + Py_RETURN_NONE; } @@ -373,15 +386,13 @@ chunk_render(PyObject *self, PyObject *args) { for (state.x = 15; state.x > -1; state.x--) { for (state.y = 0; state.y < 16; state.y++) { - PyObject *blockid = NULL; - + /* set up the render coordinates */ state.imgx = xoff + state.x*12 + state.y*12; /* 128*12 -- offset for z direction, 15*6 -- offset for x */ state.imgy = yoff - state.x*6 + state.y*6 + 128*12 + 15*6; for (state.z = 0; state.z < 128; state.z++) { - PyObject *tmp; unsigned char ancilData; state.imgy -= 12; @@ -399,14 +410,7 @@ chunk_render(PyObject *self, PyObject *args) { if ((state.imgy >= imgsize1 + 24) || (state.imgy <= -24)) { continue; } - - /* decref'd on replacement *and* at the end of the z for block */ - if (blockid) { - Py_DECREF(blockid); - } - blockid = PyInt_FromLong(state.block); - /* check for occlusion */ if (render_mode_occluded(rendermode, state.x, state.y, state.z)) { continue; @@ -431,15 +435,12 @@ chunk_render(PyObject *self, PyObject *args) { state.block_pdata = 0; } - tmp = PyTuple_New(2); + /* make sure our block info is in-bounds */ + if (state.block >= max_blockid || ancilData >= max_data) + continue; - Py_INCREF(blockid); /* because SetItem steals */ - PyTuple_SetItem(tmp, 0, blockid); - PyTuple_SetItem(tmp, 1, PyInt_FromLong(ancilData)); - - /* this is a borrowed reference. no need to decref */ - t = PyDict_GetItem(blockmap, tmp); - Py_DECREF(tmp); + /* get the texture */ + t = PyList_GET_ITEM(blockmap, max_data * state.block + ancilData); /* if we found a proper texture, render it! */ if (t != NULL && t != Py_None) @@ -470,11 +471,6 @@ chunk_render(PyObject *self, PyObject *args) { } } } - - if (blockid) { - Py_DECREF(blockid); - blockid = NULL; - } } } diff --git a/overviewer_core/textures.py b/overviewer_core/textures.py index 39d4739..ae9d46f 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -423,7 +423,7 @@ def tintTexture(im, c): def generate_texture_tuple(img): """ This takes an image and returns the needed tuple for the - blockmap dictionary.""" + blockmap array.""" if img is None: return None return (img, generate_opaque_mask(img)) @@ -543,10 +543,14 @@ def loadLightColor(): # placeholders that are generated in generate() texture_dimensions = None blockmap_generators = {} -blockmap = {} +blockmap = [] biome_grass_texture = None known_blocks = set() +used_datas = set() +max_blockid = 0 +max_data = 0 + transparent_blocks = set() solid_blocks = set() fluid_blocks = set() @@ -578,6 +582,7 @@ def material(blockid=[], data=[0], **kwargs): except TypeError: return func(blockid, data) + used_datas.update(data) for block in blockid: # set the property sets appropriately known_blocks.update([block]) @@ -658,23 +663,26 @@ def generate(path=None,texture_size=24,bgc = (26,26,26,0),north_direction='lower # generate the blocks global blockmap, blockmap_generators - blockmap = {} + global max_blockid, max_data + max_blockid = max(known_blocks) + 1 + max_data = max(used_datas) + 1 + blockmap = [None] * max_blockid * max_data + for blockid, data in blockmap_generators: texgen = blockmap_generators[(blockid, data)] tex = texgen(blockid, data, north_direction) - blockmap[(blockid, data)] = generate_texture_tuple(tex) + blockmap[blockid * max_data + data] = generate_texture_tuple(tex) if texture_size != 24: # rescale biome textures. biome_grass_texture = biome_grass_texture.resize(texture_dimensions, Image.ANTIALIAS) # rescale the special block images - for blockid, data in iter(blockmap): - block = blockmap[(blockid,data)] - if block != None: - block = block[0] + for i, tex in enumerate(blockmap): + if tex != None: + block = tex[0] scaled_block = block.resize(texture_dimensions, Image.ANTIALIAS) - blockmap[(blockid,data)] = generate_texture_tuple(scaled_block, blockid) + blockmap[i] = generate_texture_tuple(scaled_block) ## ## and finally: actual texture definitions