diff --git a/setup.py b/setup.py
index d918bd7..5777aa8 100644
--- a/setup.py
+++ b/setup.py
@@ -44,7 +44,7 @@ except AttributeError:
numpy_include = numpy.get_numpy_include()
-c_overviewer_files = ['src/main.c', 'src/composite.c', 'src/iterate.c', 'src/rendermodes.c']
+c_overviewer_files = ['src/main.c', 'src/composite.c', 'src/iterate.c', 'src/rendermodes.c', 'src/rendermode-lighting.c']
setup_kwargs['ext_modules'].append(Extension('c_overviewer', c_overviewer_files, include_dirs=['.', numpy_include], extra_link_args=["/MANIFEST"] if platform.system() == "Windows" else []))
# tell build_ext to build the extension in-place
# (NOT in build/)
diff --git a/src/overviewer.h b/src/overviewer.h
index 4c6ec39..f85636e 100644
--- a/src/overviewer.h
+++ b/src/overviewer.h
@@ -63,20 +63,7 @@ int init_chunk_render(void);
int is_transparent(unsigned char b);
PyObject *chunk_render(PyObject *self, PyObject *args);
-/* in rendermode.c */
-typedef struct {
- /* the size of the local storage for this rendermode */
- unsigned int data_size;
-
- /* may return non-zero on error */
- int (*start)(void *, RenderState *);
- void (*finish)(void *, RenderState *);
- /* returns non-zero to skip rendering this block */
- 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);
+/* pull in the rendermode info */
+#include "rendermodes.h"
#endif /* __OVERVIEWER_H_INCLUDED__ */
diff --git a/src/rendermode-lighting.c b/src/rendermode-lighting.c
new file mode 100644
index 0000000..d6a123e
--- /dev/null
+++ b/src/rendermode-lighting.c
@@ -0,0 +1,114 @@
+/*
+ * This file is part of the Minecraft Overviewer.
+ *
+ * Minecraft Overviewer is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Minecraft Overviewer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with the Overviewer. If not, see .
+ */
+
+#include "overviewer.h"
+
+/* shades the drawn block with the given facemask/black_color, based on the
+ lighting results from (x, y, z) */
+static inline void
+do_shading_for_face(PyObject *chunk, int x, int y, int z, PyObject *facemask, PyObject *black_color,
+ PyObject *img, int imgx, int imgy) {
+ // returns new references
+ PyObject* light_tup = PyObject_CallMethod(chunk, "get_lighting_coefficient", "iii", x, y, z);
+ PyObject *black_coeff_py = PySequence_GetItem(light_tup, 0);
+ double black_coeff = PyFloat_AsDouble(black_coeff_py);
+ Py_DECREF(black_coeff_py);
+
+ PyObject *face_occlude_py = PySequence_GetItem(light_tup, 1);
+ int face_occlude = PyInt_AsLong(face_occlude_py);
+ Py_DECREF(face_occlude_py);
+
+
+ if (!face_occlude) {
+ //#composite.alpha_over(img, over_color, (imgx, imgy), ImageEnhance.Brightness(facemasks[0]).enhance(black_coeff))
+
+ PyObject *mask = PyObject_CallMethod(facemask, "copy", NULL); // new ref
+ //printf("black_coeff: %f\n", black_coeff);
+ brightness(mask, black_coeff);
+ //printf("done with brightness\n");
+ alpha_over(img, black_color, mask, imgx, imgy, 0, 0);
+ //printf("done with alpha_over\n");
+ Py_DECREF(mask);
+
+ }
+}
+
+static int
+rendermode_lighting_start(void *data, RenderState *state) {
+ /* first, chain up */
+ int ret = rendermode_normal.start(data, state);
+ if (ret != 0)
+ return ret;
+
+ RenderModeLighting* self = (RenderModeLighting *)data;
+
+ self->black_color = PyObject_GetAttrString(state->chunk, "black_color");
+ self->facemasks_py = PyObject_GetAttrString(state->chunk, "facemasks");
+ // borrowed references, don't need to be decref'd
+ self->facemasks[0] = PyTuple_GetItem(self->facemasks_py, 0);
+ self->facemasks[1] = PyTuple_GetItem(self->facemasks_py, 1);
+ self->facemasks[2] = PyTuple_GetItem(self->facemasks_py, 2);
+
+ return 0;
+}
+
+static void
+rendermode_lighting_finish(void *data, RenderState *state) {
+ RenderModeLighting *self = (RenderModeLighting *)data;
+
+ Py_DECREF(self->black_color);
+ Py_DECREF(self->facemasks_py);
+
+ /* now chain up */
+ rendermode_normal.finish(data, state);
+}
+
+static int
+rendermode_lighting_occluded(void *data, RenderState *state) {
+ /* no special occlusion here */
+ return rendermode_normal.occluded(data, state);
+}
+
+static void
+rendermode_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) {
+ /* first, chain up */
+ rendermode_normal.draw(data, state, src, mask);
+
+ RenderModeLighting* self = (RenderModeLighting *)data;
+
+ PyObject *chunk = state->self;
+ int x = state->x, y = state->y, z = state->z;
+ PyObject **facemasks = self->facemasks;
+ PyObject *black_color = self->black_color, *img = state->img;
+ int imgx = state->imgx, imgy = state->imgy;
+
+ // FIXME whole-block shading for transparent blocks
+ do_shading_for_face(chunk, x, y, z+1, facemasks[0], black_color,
+ img, imgx, imgy);
+ do_shading_for_face(chunk, x-1, y, z, facemasks[1], black_color,
+ img, imgx, imgy);
+ do_shading_for_face(chunk, x, y+1, z, facemasks[2], black_color,
+ img, imgx, imgy);
+}
+
+RenderModeInterface rendermode_lighting = {
+ sizeof(RenderModeLighting),
+ rendermode_lighting_start,
+ rendermode_lighting_finish,
+ rendermode_lighting_occluded,
+ rendermode_lighting_draw,
+};
diff --git a/src/rendermodes.c b/src/rendermodes.c
index d90968a..c4675e5 100644
--- a/src/rendermodes.c
+++ b/src/rendermodes.c
@@ -17,18 +17,6 @@
#include "overviewer.h"
-/*
- * ========================
- * == NORMAL rendermode ===
- * ========================
- */
-
-typedef struct {
- /* normal mode does not have any special data, so just use a dummy int
- this way, normal mode is just like any other type of render mode */
- int dummy;
-} RenderModeNormal;
-
static int
rendermode_normal_start(void *data, RenderState *state) {
/* do nothing */
@@ -67,114 +55,8 @@ RenderModeInterface rendermode_normal = {
rendermode_normal_draw,
};
-/*
- * ===========================
- * === LIGHTING rendermode ===
- * ===========================
- */
-
-typedef struct {
- /* inherits from normal render mode */
- RenderModeNormal parent;
-
- PyObject *black_color, *facemasks_py;
- PyObject *facemasks[3];
-} RenderModeLighting;
-
-/* shades the drawn block with the given facemask/black_color, based on the
- lighting results from (x, y, z) */
-static inline void
-do_shading_for_face(PyObject *chunk, int x, int y, int z, PyObject *facemask, PyObject *black_color,
- PyObject *img, int imgx, int imgy) {
- // returns new references
- PyObject* light_tup = PyObject_CallMethod(chunk, "get_lighting_coefficient", "iii", x, y, z);
- PyObject *black_coeff_py = PySequence_GetItem(light_tup, 0);
- double black_coeff = PyFloat_AsDouble(black_coeff_py);
- Py_DECREF(black_coeff_py);
-
- PyObject *face_occlude_py = PySequence_GetItem(light_tup, 1);
- int face_occlude = PyInt_AsLong(face_occlude_py);
- Py_DECREF(face_occlude_py);
-
-
- if (!face_occlude) {
- //#composite.alpha_over(img, over_color, (imgx, imgy), ImageEnhance.Brightness(facemasks[0]).enhance(black_coeff))
-
- PyObject *mask = PyObject_CallMethod(facemask, "copy", NULL); // new ref
- //printf("black_coeff: %f\n", black_coeff);
- brightness(mask, black_coeff);
- //printf("done with brightness\n");
- alpha_over(img, black_color, mask, imgx, imgy, 0, 0);
- //printf("done with alpha_over\n");
- Py_DECREF(mask);
-
- }
-}
-
-static int
-rendermode_lighting_start(void *data, RenderState *state) {
- /* first, chain up */
- int ret = rendermode_normal_start(data, state);
- if (ret != 0)
- return ret;
-
- RenderModeLighting* self = (RenderModeLighting *)data;
-
- self->black_color = PyObject_GetAttrString(state->chunk, "black_color");
- self->facemasks_py = PyObject_GetAttrString(state->chunk, "facemasks");
- // borrowed references, don't need to be decref'd
- self->facemasks[0] = PyTuple_GetItem(self->facemasks_py, 0);
- self->facemasks[1] = PyTuple_GetItem(self->facemasks_py, 1);
- self->facemasks[2] = PyTuple_GetItem(self->facemasks_py, 2);
-
- return 0;
-}
-
-static void
-rendermode_lighting_finish(void *data, RenderState *state) {
- RenderModeLighting *self = (RenderModeLighting *)data;
-
- Py_DECREF(self->black_color);
- Py_DECREF(self->facemasks_py);
-
- /* now chain up */
- rendermode_normal_finish(data, state);
-}
-
-static void
-rendermode_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) {
- /* first, chain up */
- rendermode_normal_draw(data, state, src, mask);
-
- RenderModeLighting* self = (RenderModeLighting *)data;
-
- PyObject *chunk = state->self;
- int x = state->x, y = state->y, z = state->z;
- PyObject **facemasks = self->facemasks;
- PyObject *black_color = self->black_color, *img = state->img;
- int imgx = state->imgx, imgy = state->imgy;
-
- // FIXME whole-block shading for transparent blocks
- do_shading_for_face(chunk, x, y, z+1, facemasks[0], black_color,
- img, imgx, imgy);
- do_shading_for_face(chunk, x-1, y, z, facemasks[1], black_color,
- img, imgx, imgy);
- do_shading_for_face(chunk, x, y+1, z, facemasks[2], black_color,
- img, imgx, imgy);
-}
-
-RenderModeInterface rendermode_lighting = {
- sizeof(RenderModeLighting),
- rendermode_lighting_start,
- rendermode_lighting_finish,
- /* no special occlusion for lighting */
- rendermode_normal_occluded,
- rendermode_lighting_draw,
-};
-
/* putting it all together */
-RenderModeInterface *get_render_mode(RenderState *state)
-{
+RenderModeInterface *get_render_mode(RenderState *state) {
/* default: normal */
RenderModeInterface *iface = &rendermode_normal;
PyObject *quadtree = PyObject_GetAttrString(state->self, "quadtree");
diff --git a/src/rendermodes.h b/src/rendermodes.h
new file mode 100644
index 0000000..89f12f1
--- /dev/null
+++ b/src/rendermodes.h
@@ -0,0 +1,76 @@
+/*
+ * This file is part of the Minecraft Overviewer.
+ *
+ * Minecraft Overviewer is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Minecraft Overviewer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with the Overviewer. If not, see .
+ */
+
+/*
+ * To make a new render mode (the C part, at least):
+ *
+ * * add a data struct and extern'd interface declaration below
+ *
+ * * fill in this interface struct in rendermode-(yourmode).c
+ * (see rendermodes.c for an example: the "normal" mode)
+ *
+ * * if you want to derive from (say) the "normal" mode, put
+ * a RenderModeNormal entry at the top of your data struct, and
+ * be sure to call your parent's functions in your own!
+ * (see rendermode-lighting.c for an example)
+ *
+ * * add a condition to get_render_mode() in rendermodes.c
+ */
+
+#ifndef __RENDERMODES_H_INCLUDED__
+#define __RENDERMODES_H_INCLUDED__
+
+#include
+
+/* rendermode interface */
+typedef struct {
+ /* the size of the local storage for this rendermode */
+ unsigned int data_size;
+
+ /* may return non-zero on error */
+ int (*start)(void *, RenderState *);
+ void (*finish)(void *, RenderState *);
+ /* returns non-zero to skip rendering this block */
+ 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);
+
+/* individual rendermode interface declarations follow */
+
+/* NORMAL */
+typedef struct {
+ /* normal mode does not have any special data, so just use a dummy int
+ this way, normal mode is just like any other type of render mode */
+ int dummy;
+} RenderModeNormal;
+extern RenderModeInterface rendermode_normal;
+
+/* LIGHTING */
+typedef struct {
+ /* inherits from normal render mode */
+ RenderModeNormal parent;
+
+ PyObject *black_color, *facemasks_py;
+ PyObject *facemasks[3];
+} RenderModeLighting;
+extern RenderModeInterface rendermode_lighting;
+
+#endif /* __RENDERMODES_H_INCLUDED__ */