0

Merge branch '19prep'

Conflicts:
	overviewer_core/src/overviewer.h
	overviewer_core/textures.py
This commit is contained in:
Aaron Griffith
2011-11-18 17:25:01 -05:00
8 changed files with 2526 additions and 2114 deletions

View File

@@ -125,25 +125,6 @@ def get_tileentity_data(level):
data = level['TileEntities'] data = level['TileEntities']
return data return data
# This set holds blocks ids that can be seen through, for occlusion calculations
transparent_blocks = set([ 0, 6, 8, 9, 18, 20, 26, 27, 28, 29, 30, 31, 32, 33,
34, 37, 38, 39, 40, 44, 50, 51, 52, 53, 55, 59, 63, 64,
65, 66, 67, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79,
81, 83, 85, 90, 92, 93, 94, 96, 101, 102, 104, 105,
106, 107, 108, 109])
# This set holds block ids that are solid blocks
solid_blocks = set([1, 2, 3, 4, 5, 7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 35, 41, 42, 43, 44, 45, 46, 47, 48, 49, 53, 54, 56, 57, 58, 60,
61, 62, 67, 73, 74, 78, 79, 80, 81, 82, 84, 86, 87, 88, 89, 91])
# This set holds block ids that are fluid blocks
fluid_blocks = set([8,9,10,11])
# This set holds block ids that are not candidates for spawning mobs on
# (glass, slabs, stairs, fluids, ice, pistons, webs,TNT, wheat, cactus, iron bars, glass planes, fences, fence gate, cake, bed, repeaters, trapdoor)
nospawn_blocks = set([20,26, 29, 30, 33, 34, 44, 46, 53, 59, 67, 79, 81, 85, 92, 93, 94, 96, 107, 109, 101, 102]).union(fluid_blocks)
class ChunkCorrupt(Exception): class ChunkCorrupt(Exception):
pass pass
@@ -412,7 +393,7 @@ def generate_facemasks():
left = Image.new("L", (24,24), 0) left = Image.new("L", (24,24), 0)
whole = Image.new("L", (24,24), 0) whole = Image.new("L", (24,24), 0)
toppart = textures.transform_image(white) toppart = textures.transform_image_top(white)
leftpart = textures.transform_image_side(white) leftpart = textures.transform_image_side(white)
# using the real PIL paste here (not alpha_over) because there is # using the real PIL paste here (not alpha_over) because there is

View File

@@ -20,12 +20,22 @@
static PyObject *textures = NULL; static PyObject *textures = NULL;
static PyObject *chunk_mod = NULL; static PyObject *chunk_mod = NULL;
static PyObject *blockmap = NULL; static PyObject *blockmap = NULL;
static PyObject *special_blocks = NULL;
static PyObject *specialblockmap = 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 PyObject *transparent_blocks = NULL;
static PyObject *solid_blocks = NULL;
static PyObject *fluid_blocks = NULL;
static PyObject *nospawn_blocks = NULL;
PyObject *init_chunk_render(PyObject *self, PyObject *args) { 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 /* this function only needs to be called once, anything more should be
* ignored */ * ignored */
if (blockmap) { if (blockmap) {
@@ -47,29 +57,54 @@ PyObject *init_chunk_render(PyObject *self, PyObject *args) {
blockmap = PyObject_GetAttrString(textures, "blockmap"); blockmap = PyObject_GetAttrString(textures, "blockmap");
if (!blockmap) if (!blockmap)
return NULL; return NULL;
special_blocks = PyObject_GetAttrString(textures, "special_blocks");
if (!special_blocks) tmp = PyObject_GetAttrString(textures, "max_blockid");
if (!tmp)
return NULL; return NULL;
specialblockmap = PyObject_GetAttrString(textures, "specialblockmap"); max_blockid = PyInt_AsLong(tmp);
if (!specialblockmap) tmp = PyObject_GetAttrString(textures, "max_data");
if (!tmp)
return NULL; return NULL;
transparent_blocks = PyObject_GetAttrString(chunk_mod, "transparent_blocks"); 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) if (!transparent_blocks)
return NULL; 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; Py_RETURN_NONE;
} }
int
is_transparent(unsigned char b) {
PyObject *block = PyInt_FromLong(b);
int ret = PySequence_Contains(transparent_blocks, block);
Py_DECREF(block);
return ret;
}
unsigned char unsigned char
check_adjacent_blocks(RenderState *state, int x,int y,int z, unsigned char blockid) { check_adjacent_blocks(RenderState *state, int x,int y,int z, unsigned char blockid) {
/* /*
@@ -284,14 +319,15 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) {
return final_data; return final_data;
/* portal, iron bars and glass panes } else if ((state->block == 101) || (state->block == 102)) {
* Note: iron bars and glass panes "stick" to other blocks, but /* iron bars and glass panes:
* at the moment of writing this is not clear which ones stick and * they seem to stick to almost everything but air, but
* which others no, so for the moment stick only with himself. * not sure yet! Still a TODO! */
* This is a TODO! /* return check adjacent blocks with air, bit inverted */
*/ return check_adjacent_blocks(state, x, y, z, 0) ^ 0x0f;
} else if ((state->block == 90) || (state->block == 101) ||
(state->block == 102)) { } else if ((state->block == 90) || (state->block == 113)) {
/* portal and nether brick fences */
return check_adjacent_blocks(state, x, y, z, state->block); return check_adjacent_blocks(state, x, y, z, state->block);
} }
@@ -372,7 +408,6 @@ chunk_render(PyObject *self, PyObject *args) {
for (state.x = 15; state.x > -1; state.x--) { for (state.x = 15; state.x > -1; state.x--) {
for (state.y = 0; state.y < 16; state.y++) { for (state.y = 0; state.y < 16; state.y++) {
PyObject *blockid = NULL;
/* set up the render coordinates */ /* set up the render coordinates */
state.imgx = xoff + state.x*12 + state.y*12; state.imgx = xoff + state.x*12 + state.y*12;
@@ -380,6 +415,8 @@ chunk_render(PyObject *self, PyObject *args) {
state.imgy = yoff - state.x*6 + state.y*6 + 128*12 + 15*6; state.imgy = yoff - state.x*6 + state.y*6 + 128*12 + 15*6;
for (state.z = 0; state.z < 128; state.z++) { for (state.z = 0; state.z < 128; state.z++) {
unsigned char ancilData;
state.imgy -= 12; state.imgy -= 12;
/* get blockid */ /* get blockid */
@@ -396,28 +433,14 @@ chunk_render(PyObject *self, PyObject *args) {
continue; continue;
} }
/* check for occlusion */
/* 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)) { if (render_mode_occluded(rendermode, state.x, state.y, state.z)) {
continue; continue;
} }
// everything stored here will be a borrowed ref /* everything stored here will be a borrowed ref */
/* get the texture and mask from block type / ancil. data */ ancilData = getArrayByte3D(state.blockdata_expanded, state.x, state.y, state.z);
if (!PySequence_Contains(special_blocks, blockid)) {
/* t = textures.blockmap[blockid] */
t = PyList_GetItem(blockmap, state.block);
} else {
PyObject *tmp;
unsigned char ancilData = getArrayByte3D(state.blockdata_expanded, state.x, state.y, state.z);
state.block_data = ancilData; state.block_data = ancilData;
/* block that need pseudo ancildata: /* block that need pseudo ancildata:
* grass, water, glass, chest, restone wire, * grass, water, glass, chest, restone wire,
@@ -426,23 +449,20 @@ chunk_render(PyObject *self, PyObject *args) {
(state.block == 20) || (state.block == 54) || (state.block == 20) || (state.block == 54) ||
(state.block == 55) || (state.block == 79) || (state.block == 55) || (state.block == 79) ||
(state.block == 85) || (state.block == 90) || (state.block == 85) || (state.block == 90) ||
(state.block == 101) || (state.block == 102)) { (state.block == 101) || (state.block == 102) ||
(state.block == 113)) {
ancilData = generate_pseudo_data(&state, ancilData); ancilData = generate_pseudo_data(&state, ancilData);
state.block_pdata = ancilData; state.block_pdata = ancilData;
} else { } else {
state.block_pdata = 0; 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 */ /* get the texture */
PyTuple_SetItem(tmp, 0, blockid); t = PyList_GET_ITEM(blockmap, max_data * state.block + ancilData);
PyTuple_SetItem(tmp, 1, PyInt_FromLong(ancilData));
/* this is a borrowed reference. no need to decref */
t = PyDict_GetItem(specialblockmap, tmp);
Py_DECREF(tmp);
}
/* if we found a proper texture, render it! */ /* if we found a proper texture, render it! */
if (t != NULL && t != Py_None) if (t != NULL && t != Py_None)
@@ -450,8 +470,8 @@ chunk_render(PyObject *self, PyObject *args) {
PyObject *src, *mask, *mask_light; PyObject *src, *mask, *mask_light;
int randx = 0, randy = 0; int randx = 0, randy = 0;
src = PyTuple_GetItem(t, 0); src = PyTuple_GetItem(t, 0);
mask = PyTuple_GetItem(t, 1); mask = PyTuple_GetItem(t, 0);
mask_light = PyTuple_GetItem(t, 2); mask_light = PyTuple_GetItem(t, 1);
if (mask == Py_None) if (mask == Py_None)
mask = src; mask = src;
@@ -473,11 +493,6 @@ chunk_render(PyObject *self, PyObject *args) {
} }
} }
} }
if (blockid) {
Py_DECREF(blockid);
blockid = NULL;
}
} }
} }

View File

@@ -26,7 +26,7 @@
// increment this value if you've made a change to the c extesion // increment this value if you've made a change to the c extesion
// and want to force users to rebuild // and want to force users to rebuild
#define OVERVIEWER_EXTENSION_VERSION 12 #define OVERVIEWER_EXTENSION_VERSION 13
/* Python PIL, and numpy headers */ /* Python PIL, and numpy headers */
#include <Python.h> #include <Python.h>
@@ -94,8 +94,32 @@ typedef struct {
PyObject *right_blocks; PyObject *right_blocks;
} RenderState; } RenderState;
PyObject *init_chunk_render(PyObject *self, PyObject *args); PyObject *init_chunk_render(PyObject *self, PyObject *args);
int is_transparent(unsigned char b);
PyObject *chunk_render(PyObject *self, PyObject *args); 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 */ /* pull in the rendermode info */
#include "rendermodes.h" #include "rendermodes.h"

View File

@@ -173,7 +173,9 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *
* get constant brown color (see textures.py) */ * get constant brown color (see textures.py) */
(((state->block == 104) || (state->block == 105)) && (state->block_data != 7)) || (((state->block == 104) || (state->block == 105)) && (state->block_data != 7)) ||
/* vines */ /* vines */
state->block == 106) state->block == 106 ||
/* lily pads */
state->block == 111)
{ {
/* do the biome stuff! */ /* do the biome stuff! */
PyObject *facemask = mask; PyObject *facemask = mask;
@@ -240,6 +242,10 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *
/* vines */ /* vines */
color = PySequence_GetItem(self->grasscolor, index); color = PySequence_GetItem(self->grasscolor, index);
break; break;
case 111:
/* lily padas */
color = PySequence_GetItem(self->grasscolor, index);
break;
default: default:
break; break;
}; };
@@ -270,7 +276,8 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *
facemask = NULL; facemask = NULL;
} }
if (state->block == 18 || state->block == 106) /* leaves and vines */ if (state->block == 18 || state->block == 106 || state->block == 111)
/* leaves, vines and lyli pads */
{ {
r = 37; r = 37;
g = 118; g = 118;

View File

@@ -37,10 +37,6 @@ rendermode_overlay_start(void *data, RenderState *state, PyObject *options) {
Py_DECREF(facemasks_py); Py_DECREF(facemasks_py);
self->white_color = PyObject_GetAttrString(state->chunk, "white_color"); self->white_color = PyObject_GetAttrString(state->chunk, "white_color");
self->solid_blocks = PyObject_GetAttrString(state->chunk, "solid_blocks");
self->fluid_blocks = PyObject_GetAttrString(state->chunk, "fluid_blocks");
self->get_color = get_color; self->get_color = get_color;
return 0; return 0;
@@ -52,8 +48,6 @@ rendermode_overlay_finish(void *data, RenderState *state) {
Py_DECREF(self->facemask_top); Py_DECREF(self->facemask_top);
Py_DECREF(self->white_color); Py_DECREF(self->white_color);
Py_DECREF(self->solid_blocks);
Py_DECREF(self->fluid_blocks);
} }
static int static int
@@ -81,7 +75,6 @@ static void
rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
RenderModeOverlay *self = (RenderModeOverlay *)data; RenderModeOverlay *self = (RenderModeOverlay *)data;
unsigned char r, g, b, a; unsigned char r, g, b, a;
PyObject *top_block_py, *block_py;
// exactly analogous to edge-line code for these special blocks // exactly analogous to edge-line code for these special blocks
int increment=0; int increment=0;
@@ -101,27 +94,19 @@ rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject
} }
/* check to be sure this block is solid/fluid */ /* check to be sure this block is solid/fluid */
top_block_py = PyInt_FromLong(top_block); if (block_has_property(top_block, SOLID) || block_has_property(top_block, FLUID)) {
if (PySequence_Contains(self->solid_blocks, top_block_py) ||
PySequence_Contains(self->fluid_blocks, top_block_py)) {
/* top block is fluid or solid, skip drawing */ /* top block is fluid or solid, skip drawing */
Py_DECREF(top_block_py);
return; return;
} }
Py_DECREF(top_block_py);
} }
/* check to be sure this block is solid/fluid */ /* check to be sure this block is solid/fluid */
block_py = PyInt_FromLong(state->block); if (!block_has_property(state->block, SOLID) && !block_has_property(state->block, FLUID)) {
if (!PySequence_Contains(self->solid_blocks, block_py) &&
!PySequence_Contains(self->fluid_blocks, block_py)) {
/* not fluid or solid, skip drawing the overlay */ /* not fluid or solid, skip drawing the overlay */
Py_DECREF(block_py);
return; return;
} }
Py_DECREF(block_py);
/* get our color info */ /* get our color info */
self->get_color(data, state, &r, &g, &b, &a); self->get_color(data, state, &r, &g, &b, &a);

View File

@@ -35,13 +35,10 @@ static void get_color(void *data, RenderState *state,
/* default to no overlay, until told otherwise */ /* default to no overlay, until told otherwise */
*a = 0; *a = 0;
block_py = PyInt_FromLong(state->block); if (block_has_property(state->block, NOSPAWN)) {
if (PySequence_Contains(self->nospawn_blocks, block_py)) {
/* nothing can spawn on this */ /* nothing can spawn on this */
Py_DECREF(block_py);
return; return;
} }
Py_DECREF(block_py);
blocklight = getArrayByte3D(self->blocklight, x, y, MIN(127, z_light)); 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 */ /* now do custom initializations */
self = (RenderModeSpawn *)data; self = (RenderModeSpawn *)data;
self->nospawn_blocks = PyObject_GetAttrString(state->chunk, "nospawn_blocks");
self->blocklight = PyObject_GetAttrString(state->self, "blocklight"); self->blocklight = PyObject_GetAttrString(state->self, "blocklight");
self->skylight = PyObject_GetAttrString(state->self, "skylight"); self->skylight = PyObject_GetAttrString(state->self, "skylight");
@@ -87,7 +83,6 @@ rendermode_spawn_finish(void *data, RenderState *state) {
/* first free all *our* stuff */ /* first free all *our* stuff */
RenderModeSpawn* self = (RenderModeSpawn *)data; RenderModeSpawn* self = (RenderModeSpawn *)data;
Py_DECREF(self->nospawn_blocks);
Py_DECREF(self->blocklight); Py_DECREF(self->blocklight);
Py_DECREF(self->skylight); Py_DECREF(self->skylight);

View File

@@ -143,8 +143,6 @@ extern RenderModeInterface rendermode_normal;
typedef struct { typedef struct {
/* top facemask and white color image, for drawing overlays */ /* top facemask and white color image, for drawing overlays */
PyObject *facemask_top, *white_color; 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 /* can be overridden in derived classes to control
overlay alpha and color overlay alpha and color
last four vars are r, g, b, a out */ last four vars are r, g, b, a out */
@@ -206,8 +204,6 @@ typedef struct {
/* inherits from overlay */ /* inherits from overlay */
RenderModeOverlay parent; RenderModeOverlay parent;
/* used to figure out which blocks are spawnable */
PyObject *nospawn_blocks;
PyObject *skylight, *blocklight; PyObject *skylight, *blocklight;
} RenderModeSpawn; } RenderModeSpawn;
extern RenderModeInterface rendermode_spawn; extern RenderModeInterface rendermode_spawn;

File diff suppressed because it is too large Load Diff