diff --git a/chunk.py b/chunk.py index 0fdce6c..baf9efc 100644 --- a/chunk.py +++ b/chunk.py @@ -129,10 +129,6 @@ fluid_blocks = set([8,9,10,11]) # (glass, half blocks) nospawn_blocks = set([20,44]) -# overlay rendermodes -# FIXME hook this into render_modes in setup.py, somehow -overlay_rendermodes = ['spawn'] - class ChunkCorrupt(Exception): pass diff --git a/googlemap.py b/googlemap.py index 0f883d3..b8416b5 100644 --- a/googlemap.py +++ b/googlemap.py @@ -23,7 +23,7 @@ from time import strftime, gmtime import json import util -from chunk import overlay_rendermodes +from c_overviewer import get_render_mode_inheritance """ This module has routines related to generating a Google Maps-based @@ -97,7 +97,7 @@ class MapGen(object): # create generated map type data, from given quadtrees maptypedata = map(lambda q: {'label' : q.rendermode.capitalize(), 'path' : q.tiledir, - 'overlay' : q.rendermode in overlay_rendermodes, + 'overlay' : 'overlay' in get_render_mode_inheritance(q.rendermode), 'imgformat' : q.imgformat}, self.quadtrees) config = config.replace("{maptypedata}", json.dumps(maptypedata)) diff --git a/quadtree.py b/quadtree.py index 40773e9..4b2cc68 100644 --- a/quadtree.py +++ b/quadtree.py @@ -34,6 +34,7 @@ from PIL import Image import nbt import chunk +from c_overviewer import get_render_mode_inheritance from optimizeimages import optimize_image import composite @@ -64,7 +65,7 @@ class QuadtreeGen(object): self.rendermode = rendermode # force png renderformat if we're using an overlay mode - if rendermode in chunk.overlay_rendermodes: + if 'overlay' in get_render_mode_inheritance(rendermode): self.imgformat = "png" # Make the destination dir diff --git a/src/main.c b/src/main.c index ddbe0af..4de7eec 100644 --- a/src/main.c +++ b/src/main.c @@ -25,14 +25,24 @@ PyObject *get_extension_version(PyObject *self, PyObject *args) { static PyMethodDef COverviewerMethods[] = { {"alpha_over", alpha_over_wrap, METH_VARARGS, "alpha over composite function"}, + {"render_loop", chunk_render, METH_VARARGS, "Renders stuffs"}, + {"get_render_modes", get_render_modes, METH_VARARGS, "returns available render modes"}, {"get_render_mode_info", get_render_mode_info, METH_VARARGS, "returns info for a particular render mode"}, + {"get_render_mode_parent", get_render_mode_parent, METH_VARARGS, + "returns parent for a particular render mode"}, + {"get_render_mode_inheritance", get_render_mode_inheritance, METH_VARARGS, + "returns inheritance chain for a particular render mode"}, + {"get_render_mode_children", get_render_mode_children, METH_VARARGS, + "returns (direct) children for a particular render mode"}, + {"extension_version", get_extension_version, METH_VARARGS, "Returns the extension version"}, + {NULL, NULL, 0, NULL} /* Sentinel */ }; diff --git a/src/rendermode-cave.c b/src/rendermode-cave.c index e51742c..f8334b2 100644 --- a/src/rendermode-cave.c +++ b/src/rendermode-cave.c @@ -225,6 +225,7 @@ rendermode_cave_draw(void *data, RenderState *state, PyObject *src, PyObject *ma RenderModeInterface rendermode_cave = { "cave", "render only caves in normal mode", + &rendermode_normal, sizeof(RenderModeCave), rendermode_cave_start, rendermode_cave_finish, diff --git a/src/rendermode-lighting.c b/src/rendermode-lighting.c index 628e5c4..83b38d3 100644 --- a/src/rendermode-lighting.c +++ b/src/rendermode-lighting.c @@ -229,6 +229,7 @@ rendermode_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject RenderModeInterface rendermode_lighting = { "lighting", "draw shadows from the lighting data", + &rendermode_normal, sizeof(RenderModeLighting), rendermode_lighting_start, rendermode_lighting_finish, diff --git a/src/rendermode-night.c b/src/rendermode-night.c index 1e54f05..46ca7c2 100644 --- a/src/rendermode-night.c +++ b/src/rendermode-night.c @@ -61,6 +61,7 @@ rendermode_night_draw(void *data, RenderState *state, PyObject *src, PyObject *m RenderModeInterface rendermode_night = { "night", "like \"lighting\", except at night", + &rendermode_lighting, sizeof(RenderModeNight), rendermode_night_start, rendermode_night_finish, diff --git a/src/rendermode-normal.c b/src/rendermode-normal.c index 983050c..9f139a3 100644 --- a/src/rendermode-normal.c +++ b/src/rendermode-normal.c @@ -221,6 +221,7 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * RenderModeInterface rendermode_normal = { "normal", "nothing special, just render the blocks", + NULL, sizeof(RenderModeNormal), rendermode_normal_start, rendermode_normal_finish, diff --git a/src/rendermode-overlay.c b/src/rendermode-overlay.c index 4029ae9..fb4e765 100644 --- a/src/rendermode-overlay.c +++ b/src/rendermode-overlay.c @@ -128,6 +128,7 @@ rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject RenderModeInterface rendermode_overlay = { "overlay", "base rendermode for informational overlays", + NULL, sizeof(RenderModeOverlay), rendermode_overlay_start, rendermode_overlay_finish, diff --git a/src/rendermode-spawn.c b/src/rendermode-spawn.c index ff73780..edd9c44 100644 --- a/src/rendermode-spawn.c +++ b/src/rendermode-spawn.c @@ -109,6 +109,7 @@ rendermode_spawn_draw(void *data, RenderState *state, PyObject *src, PyObject *m RenderModeInterface rendermode_spawn = { "spawn", "draws a red overlay where monsters can spawn at night", + &rendermode_overlay, sizeof(RenderModeSpawn), rendermode_spawn_start, rendermode_spawn_finish, diff --git a/src/rendermodes.c b/src/rendermodes.c index 08ac140..5ee7d54 100644 --- a/src/rendermodes.c +++ b/src/rendermodes.c @@ -98,5 +98,87 @@ PyObject *get_render_mode_info(PyObject *self, PyObject *args) { } Py_DECREF(info); - Py_RETURN_NONE; + return PyErr_Format(PyExc_ValueError, "invalid rendermode: \"%s\"", rendermode); +} + +/* bindings -- get parent's name */ +PyObject *get_render_mode_parent(PyObject *self, PyObject *args) { + const char *rendermode; + unsigned int i; + if (!PyArg_ParseTuple(args, "s", &rendermode)) + return NULL; + + for (i = 0; render_modes[i] != NULL; i++) { + if (strcmp(render_modes[i]->name, rendermode) == 0) { + if (render_modes[i]->parent) { + /* has parent */ + return PyString_FromString(render_modes[i]->parent->name); + } else { + /* no parent */ + Py_RETURN_NONE; + } + } + } + + return PyErr_Format(PyExc_ValueError, "invalid rendermode: \"%s\"", rendermode); +} + +/* bindings -- get list of inherited parents */ +PyObject *get_render_mode_inheritance(PyObject *self, PyObject *args) { + const char *rendermode; + PyObject *parents; + unsigned int i; + if (!PyArg_ParseTuple(args, "s", &rendermode)) + return NULL; + + parents = PyList_New(0); + if (!parents) + return NULL; + + RenderModeInterface *iface = NULL; + for (i = 0; render_modes[i] != NULL; i++) { + if (strcmp(render_modes[i]->name, rendermode) == 0) { + iface = render_modes[i]; + break; + } + } + + if (!iface) { + Py_DECREF(parents); + return PyErr_Format(PyExc_ValueError, "invalid rendermode: \"%s\"", rendermode); + } + + while (iface) { + PyObject *name = PyString_FromString(iface->name); + PyList_Append(parents, name); + Py_DECREF(name); + + iface = iface->parent; + } + + PyList_Reverse(parents); + return parents; +} + +/* bindings -- get list of (direct) children */ +PyObject *get_render_mode_children(PyObject *self, PyObject *args) { + const char *rendermode; + PyObject *children; + unsigned int i; + if (!PyArg_ParseTuple(args, "s", &rendermode)) + return NULL; + + children = PyList_New(0); + if (!children) + return NULL; + + for (i = 0; render_modes[i] != NULL; i++) { + if (render_modes[i]->parent && strcmp(render_modes[i]->parent->name, rendermode) == 0) { + PyObject *child_name = PyString_FromString(render_modes[i]->name); + PyList_Append(children, child_name); + Py_DECREF(child_name); + } + } + + return children; } diff --git a/src/rendermodes.h b/src/rendermodes.h index 980968c..fd0b479 100644 --- a/src/rendermodes.h +++ b/src/rendermodes.h @@ -38,12 +38,15 @@ #include /* rendermode interface */ -typedef struct { +typedef struct _RenderModeInterface RenderModeInterface; +struct _RenderModeInterface { /* the name of this mode */ const char* name; /* the short description of this render mode */ const char* description; + /* the rendermode this is derived from, or NULL */ + RenderModeInterface *parent; /* the size of the local storage for this rendermode */ unsigned int data_size; @@ -54,13 +57,16 @@ typedef struct { int (*occluded)(void *, RenderState *); /* last two arguments are img and mask, from texture lookup */ void (*draw)(void *, RenderState *, PyObject *, PyObject *); -} RenderModeInterface; +}; /* figures out the render mode to use from the given ChunkRenderer */ RenderModeInterface *get_render_mode(RenderState *state); /* python bindings */ PyObject *get_render_modes(PyObject *self, PyObject *args); PyObject *get_render_mode_info(PyObject *self, PyObject *args); +PyObject *get_render_mode_parent(PyObject *self, PyObject *args); +PyObject *get_render_mode_inheritance(PyObject *self, PyObject *args); +PyObject *get_render_mode_children(PyObject *self, PyObject *args); /* individual rendermode interface declarations follow */