diff --git a/overviewer_core/rendermodes.py b/overviewer_core/rendermodes.py index 12ab93b..76200c2 100644 --- a/overviewer_core/rendermodes.py +++ b/overviewer_core/rendermodes.py @@ -146,6 +146,42 @@ class Lighting(RenderPrimitive): class SmoothLighting(Lighting): name = "smooth-lighting" +class Overlay(RenderPrimitive): + name = "overlay" + + @property + def whitecolor(self): + whitecolor = getattr(self, "_whitecolor", None) + if whitecolor: + return whitecolor + white = Image.new("RGBA", (24,24), (255, 255, 255, 255)) + self._whitecolor = white + return white + + @property + def facemask_top(self): + facemask_top = getattr(self, "_facemask_top", None) + if facemask_top: + return facemask_top + + white = Image.new("L", (24,24), 255) + top = Image.new("L", (24,24), 0) + toppart = textures.Textures.transform_image_top(white) + top.paste(toppart, (0,0)) + for x,y in [(3,4), (7,2), (11,0)]: + top.putpixel((x,y), 255) + self._facemask_top = top + return top + +class SpawnOverlay(Overlay): + name = "overlay-spawn" + +class MineralOverlay(Overlay): + name = "overlay-mineral" + options = { + 'minerals' : ('a list of (blockid, (r, g, b)) tuples for coloring minerals', None), + } + # Built-in rendermodes for your convenience! normal = [Base(), EdgeLines()] lighting = [Base(), EdgeLines(), Lighting()] diff --git a/overviewer_core/src/overviewer.h b/overviewer_core/src/overviewer.h index e73fb36..b72f831 100644 --- a/overviewer_core/src/overviewer.h +++ b/overviewer_core/src/overviewer.h @@ -26,7 +26,7 @@ // increment this value if you've made a change to the c extesion // and want to force users to rebuild -#define OVERVIEWER_EXTENSION_VERSION 20 +#define OVERVIEWER_EXTENSION_VERSION 21 /* Python PIL, and numpy headers */ #include diff --git a/overviewer_core/src/rendermode-mineral.c b/overviewer_core/src/primitives/overlay-mineral.c similarity index 68% rename from overviewer_core/src/rendermode-mineral.c rename to overviewer_core/src/primitives/overlay-mineral.c index 858333b..b9b1634 100644 --- a/overviewer_core/src/rendermode-mineral.c +++ b/overviewer_core/src/primitives/overlay-mineral.c @@ -15,7 +15,14 @@ * with the Overviewer. If not, see . */ -#include "overviewer.h" +#include "overlay.h" + +typedef struct { + /* inherits from overlay */ + RenderPrimitiveOverlay parent; + + void *minerals; +} RenderPrimitiveMineral; struct MineralColor { unsigned char blockid; @@ -45,7 +52,7 @@ static void get_color(void *data, RenderState *state, int x = state->x, y = state->y, z_max = state->z + 1, z; int max_i = -1; - RenderModeMineral* self = (RenderModeMineral *)data; + RenderPrimitiveMineral* self = (RenderPrimitiveMineral *)data; struct MineralColor *minerals = (struct MineralColor *)(self->minerals); *a = 0; @@ -70,20 +77,21 @@ static void get_color(void *data, RenderState *state, } static int -rendermode_mineral_start(void *data, RenderState *state, PyObject *options) { +overlay_mineral_start(void *data, RenderState *state, PyObject *support) { PyObject *opt; - RenderModeMineral* self; + RenderPrimitiveMineral* self; /* first, chain up */ - int ret = rendermode_overlay.start(data, state, options); + int ret = primitive_overlay.start(data, state, support); if (ret != 0) return ret; /* now do custom initializations */ - self = (RenderModeMineral *)data; + self = (RenderPrimitiveMineral *)data; - opt = PyDict_GetItemString(options, "minerals"); - if (opt) { + if (!render_mode_parse_option(support, "minerals", "O", &(opt))) + return 1; + if (opt && opt != Py_None) { struct MineralColor *minerals = NULL; Py_ssize_t minerals_size = 0, i; /* create custom minerals */ @@ -110,6 +118,7 @@ rendermode_mineral_start(void *data, RenderState *state, PyObject *options) { } else { self->minerals = default_minerals; } + Py_XDECREF(opt); /* setup custom color */ self->parent.get_color = get_color; @@ -118,50 +127,24 @@ rendermode_mineral_start(void *data, RenderState *state, PyObject *options) { } static void -rendermode_mineral_finish(void *data, RenderState *state) { +overlay_mineral_finish(void *data, RenderState *state) { /* first free all *our* stuff */ - RenderModeMineral* self = (RenderModeMineral *)data; + RenderPrimitiveMineral* self = (RenderPrimitiveMineral *)data; if (self->minerals && self->minerals != default_minerals) { free(self->minerals); } /* now, chain up */ - rendermode_overlay.finish(data, state); + primitive_overlay.finish(data, state); } -static int -rendermode_mineral_occluded(void *data, RenderState *state, int x, int y, int z) { - /* no special occlusion here */ - return rendermode_overlay.occluded(data, state, x, y, z); -} - -static int -rendermode_mineral_hidden(void *data, RenderState *state, int x, int y, int z) { - /* no special hiding here */ - return rendermode_overlay.hidden(data, state, x, y, z); -} - -static void -rendermode_mineral_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { - /* draw normally */ - rendermode_overlay.draw(data, state, src, mask, mask_light); -} - -const RenderModeOption rendermode_mineral_options[] = { - {"minerals", "a list of (blockid, (r, g, b)) tuples for coloring minerals"}, - {NULL, NULL} -}; - -RenderModeInterface rendermode_mineral = { - "mineral", "Mineral", - "draws a colored overlay showing where ores are located", - rendermode_mineral_options, - &rendermode_overlay, - sizeof(RenderModeMineral), - rendermode_mineral_start, - rendermode_mineral_finish, - rendermode_mineral_occluded, - rendermode_mineral_hidden, - rendermode_mineral_draw, +RenderPrimitiveInterface primitive_overlay_mineral = { + "overlay-mineral", + sizeof(RenderPrimitiveMineral), + overlay_mineral_start, + overlay_mineral_finish, + overlay_occluded, + NULL, + overlay_draw, }; diff --git a/overviewer_core/src/rendermode-spawn.c b/overviewer_core/src/primitives/overlay-spawn.c similarity index 63% rename from overviewer_core/src/rendermode-spawn.c rename to overviewer_core/src/primitives/overlay-spawn.c index 0c8027b..1d00030 100644 --- a/overviewer_core/src/rendermode-spawn.c +++ b/overviewer_core/src/primitives/overlay-spawn.c @@ -15,13 +15,20 @@ * with the Overviewer. If not, see . */ -#include "overviewer.h" +#include "overlay.h" #include +typedef struct { + /* inherits from overlay */ + RenderPrimitiveOverlay parent; + + PyObject *skylight, *blocklight; +} RenderPrimitiveSpawn; + static void get_color(void *data, RenderState *state, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) { - RenderModeSpawn* self = (RenderModeSpawn *)data; + RenderPrimitiveSpawn* self = (RenderPrimitiveSpawn *)data; int x = state->x, y = state->y, z = state->z; int z_light = z + 1; unsigned char blocklight, skylight; @@ -59,16 +66,16 @@ static void get_color(void *data, RenderState *state, } static int -rendermode_spawn_start(void *data, RenderState *state, PyObject *options) { - RenderModeSpawn* self; +overlay_spawn_start(void *data, RenderState *state, PyObject *support) { + RenderPrimitiveSpawn* self; /* first, chain up */ - int ret = rendermode_overlay.start(data, state, options); + int ret = primitive_overlay.start(data, state, support); if (ret != 0) return ret; /* now do custom initializations */ - self = (RenderModeSpawn *)data; + self = (RenderPrimitiveSpawn *)data; self->blocklight = get_chunk_data(state, CURRENT, BLOCKLIGHT, 1); self->skylight = get_chunk_data(state, CURRENT, SKYLIGHT, 1); @@ -79,44 +86,23 @@ rendermode_spawn_start(void *data, RenderState *state, PyObject *options) { } static void -rendermode_spawn_finish(void *data, RenderState *state) { +overlay_spawn_finish(void *data, RenderState *state) { /* first free all *our* stuff */ - RenderModeSpawn* self = (RenderModeSpawn *)data; + RenderPrimitiveSpawn* self = (RenderPrimitiveSpawn *)data; Py_DECREF(self->blocklight); Py_DECREF(self->skylight); /* now, chain up */ - rendermode_overlay.finish(data, state); + primitive_overlay.finish(data, state); } -static int -rendermode_spawn_occluded(void *data, RenderState *state, int x, int y, int z) { - /* no special occlusion here */ - return rendermode_overlay.occluded(data, state, x, y, z); -} - -static int -rendermode_spawn_hidden(void *data, RenderState *state, int x, int y, int z) { - /* no special hiding here */ - return rendermode_overlay.hidden(data, state, x, y, z); -} - -static void -rendermode_spawn_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { - /* draw normally */ - rendermode_overlay.draw(data, state, src, mask, mask_light); -} - -RenderModeInterface rendermode_spawn = { - "spawn", "Spawn", - "draws a red overlay where monsters can spawn at night", +RenderPrimitiveInterface primitive_overlay_spawn = { + "overlay-spawn", + sizeof(RenderPrimitiveSpawn), + overlay_spawn_start, + overlay_spawn_finish, + overlay_occluded, NULL, - &rendermode_overlay, - sizeof(RenderModeSpawn), - rendermode_spawn_start, - rendermode_spawn_finish, - rendermode_spawn_occluded, - rendermode_spawn_hidden, - rendermode_spawn_draw, + overlay_draw, }; diff --git a/overviewer_core/src/rendermode-overlay.c b/overviewer_core/src/primitives/overlay.c similarity index 69% rename from overviewer_core/src/rendermode-overlay.c rename to overviewer_core/src/primitives/overlay.c index 9ae4e25..f2152d0 100644 --- a/overviewer_core/src/rendermode-overlay.c +++ b/overviewer_core/src/primitives/overlay.c @@ -15,7 +15,7 @@ * with the Overviewer. If not, see . */ -#include "overviewer.h" +#include "overlay.h" static void get_color(void *data, RenderState *state, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) { @@ -26,32 +26,27 @@ static void get_color(void *data, RenderState *state, } static int -rendermode_overlay_start(void *data, RenderState *state, PyObject *options) { +overlay_start(void *data, RenderState *state, PyObject *support) { PyObject *facemasks_py; - RenderModeOverlay *self = (RenderModeOverlay *)data; + RenderPrimitiveOverlay *self = (RenderPrimitiveOverlay *)data; - facemasks_py = PyObject_GetAttrString(state->support, "facemasks"); - /* borrowed reference, needs to be incref'd if we keep it */ - self->facemask_top = PyTuple_GetItem(facemasks_py, 0); - Py_INCREF(self->facemask_top); - Py_DECREF(facemasks_py); - - self->white_color = PyObject_GetAttrString(state->support, "white_color"); + self->facemask_top = PyObject_GetAttrString(support, "facemask_top"); + self->white_color = PyObject_GetAttrString(support, "whitecolor"); self->get_color = get_color; return 0; } static void -rendermode_overlay_finish(void *data, RenderState *state) { - RenderModeOverlay *self = (RenderModeOverlay *)data; +overlay_finish(void *data, RenderState *state) { + RenderPrimitiveOverlay *self = (RenderPrimitiveOverlay *)data; Py_DECREF(self->facemask_top); Py_DECREF(self->white_color); } -static int -rendermode_overlay_occluded(void *data, RenderState *state, int x, int y, int z) { +int +overlay_occluded(void *data, RenderState *state, int x, int y, int z) { if ( (x != 0) && (y != 15) && (z != 127) && !render_mode_hidden(state->rendermode, x-1, y, z) && !render_mode_hidden(state->rendermode, x, y, z+1) && @@ -65,15 +60,9 @@ rendermode_overlay_occluded(void *data, RenderState *state, int x, int y, int z) return 0; } -static int -rendermode_overlay_hidden(void *data, RenderState *state, int x, int y, int z) { - /* overlays hide nothing by default */ - return 0; -} - -static void -rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { - RenderModeOverlay *self = (RenderModeOverlay *)data; +void +overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { + RenderPrimitiveOverlay *self = (RenderPrimitiveOverlay *)data; unsigned char r, g, b, a; // exactly analogous to edge-line code for these special blocks @@ -118,15 +107,12 @@ rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject } } -RenderModeInterface rendermode_overlay = { - "overlay", "Overlay", - "base rendermode for informational overlays", +RenderPrimitiveInterface primitive_overlay = { + "overlay", + sizeof(RenderPrimitiveOverlay), + overlay_start, + overlay_finish, + overlay_occluded, NULL, - NULL, - sizeof(RenderModeOverlay), - rendermode_overlay_start, - rendermode_overlay_finish, - rendermode_overlay_occluded, - rendermode_overlay_hidden, - rendermode_overlay_draw, + overlay_draw, }; diff --git a/overviewer_core/src/primitives/overlay.h b/overviewer_core/src/primitives/overlay.h new file mode 100644 index 0000000..4529ab2 --- /dev/null +++ b/overviewer_core/src/primitives/overlay.h @@ -0,0 +1,32 @@ +/* + * 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" + +typedef struct { + /* top facemask and white color image, for drawing overlays */ + PyObject *facemask_top, *white_color; + /* can be overridden in derived classes to control + overlay alpha and color + last four vars are r, g, b, a out */ + void (*get_color)(void *, RenderState *, + unsigned char *, unsigned char *, unsigned char *, unsigned char *); +} RenderPrimitiveOverlay; +extern RenderPrimitiveInterface primitive_overlay; + +void overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light); +int overlay_occluded(void *data, RenderState *state, int x, int y, int z); diff --git a/overviewer_core/src/rendermodes.h b/overviewer_core/src/rendermodes.h index 23df5e6..6408760 100644 --- a/overviewer_core/src/rendermodes.h +++ b/overviewer_core/src/rendermodes.h @@ -102,38 +102,4 @@ void render_mode_draw(RenderMode *self, PyObject *img, PyObject *mask, PyObject works like PyArg_ParseTuple on a support object */ int render_mode_parse_option(PyObject *support, const char *name, const char *format, ...); -/* XXX individual rendermode interface declarations follow */ -#ifdef OLD_MODES - -/* OVERLAY */ -typedef struct { - /* top facemask and white color image, for drawing overlays */ - PyObject *facemask_top, *white_color; - /* can be overridden in derived classes to control - overlay alpha and color - last four vars are r, g, b, a out */ - void (*get_color)(void *, RenderState *, - unsigned char *, unsigned char *, unsigned char *, unsigned char *); -} RenderModeOverlay; -extern RenderModeInterface rendermode_overlay; - -/* SPAWN */ -typedef struct { - /* inherits from overlay */ - RenderModeOverlay parent; - - PyObject *skylight, *blocklight; -} RenderModeSpawn; -extern RenderModeInterface rendermode_spawn; - -/* MINERAL */ -typedef struct { - /* inherits from overlay */ - RenderModeOverlay parent; - - void *minerals; -} RenderModeMineral; -extern RenderModeInterface rendermode_mineral; -#endif /* OLD_MODES */ - #endif /* __RENDERMODES_H_INCLUDED__ */