Minecraft-Overviewer/overviewer_core/src/overviewer.h

231 lines
7.3 KiB
C

/*
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* This is a general include file for the Overviewer C extension. It
* lists useful, defined functions as well as those that are exported
* to python, so all files can use them.
*/
#ifndef __OVERVIEWER_H_INCLUDED__
#define __OVERVIEWER_H_INCLUDED__
#define WINVER 0x0601
#define _WIN32_WINNT 0x0601
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
// increment this value if you've made a change to the c extesion
// and want to force users to rebuild
#define OVERVIEWER_EXTENSION_VERSION 65
/* Python PIL, and numpy headers */
#include <Imaging.h>
#include <Python.h>
#include <numpy/arrayobject.h>
/* Fix Pillow on mingw-w64 which includes windows.h in Imaging.h */
#undef TRANSPARENT
/* Utility macros */
#include "utils.h"
/* macro for getting a value out of various numpy arrays the 3D arrays have
interesting, swizzled coordinates because minecraft (anvil) stores blocks
in y/z/x order for 3D, z/x order for 2D */
#define getArrayByte3D(array, x, y, z) (*(unsigned char*)(PyArray_GETPTR3((array), (y), (z), (x))))
#define getArrayShort3D(array, x, y, z) (*(unsigned short*)(PyArray_GETPTR3((array), (y), (z), (x))))
#define getArrayByte2D(array, x, y) (*(unsigned char*)(PyArray_GETPTR2((array), (y), (x))))
/* in composite.c */
Imaging imaging_python_to_c(PyObject* obj);
PyObject* alpha_over(PyObject* dest, PyObject* src, PyObject* mask,
int dx, int dy, int xsize, int ysize);
PyObject* alpha_over_full(PyObject* dest, PyObject* src, PyObject* mask, float overall_alpha,
int dx, int dy, int xsize, int ysize);
PyObject* alpha_over_wrap(PyObject* self, PyObject* args);
PyObject* tint_with_mask(PyObject* dest, unsigned char sr, unsigned char sg,
unsigned char sb, unsigned char sa,
PyObject* mask, int dx, int dy, int xsize, int ysize);
PyObject* draw_triangle(PyObject* dest, int inclusive,
int x0, int y0,
unsigned char r0, unsigned char g0, unsigned char b0,
int x1, int y1,
unsigned char r1, unsigned char g1, unsigned char b1,
int x2, int y2,
unsigned char r2, unsigned char g2, unsigned char b2,
int tux, int tuy, int* touchups, unsigned int num_touchups);
PyObject* resize_half(PyObject* dest, PyObject* src);
PyObject* resize_half_wrap(PyObject* self, PyObject* args);
/* forward declaration of RenderMode object */
typedef struct _RenderMode RenderMode;
/* in iterate.c */
#define SECTIONS_PER_CHUNK 16
typedef struct {
/* whether this chunk is loaded: use load_chunk to load */
int loaded;
/* chunk biome array */
PyArrayObject* biomes;
/* all the sections in a given chunk */
struct {
/* all there is to know about each section */
PyArrayObject *blocks, *data, *skylight, *blocklight;
} sections[SECTIONS_PER_CHUNK];
} ChunkData;
typedef struct {
/* the regionset object, and chunk coords */
PyObject* world;
PyObject* regionset;
int chunkx, chunky, chunkz;
/* the tile image and destination */
PyObject* img;
int imgx, imgy;
/* the current render mode in use */
RenderMode* rendermode;
/* the Texture object */
PyObject* textures;
/* the block position and type, and the block array */
int x, y, z;
unsigned short block;
unsigned char block_data;
unsigned short block_pdata;
/* useful information about this, and neighboring, chunks */
PyArrayObject* blockdatas;
PyArrayObject* blocks;
/* 3x3 array of this and neighboring chunk columns */
ChunkData chunks[3][3];
} RenderState;
PyObject* init_chunk_render(void);
/* returns true on error, x,z relative */
int load_chunk(RenderState* state, int x, int z, unsigned char required);
PyObject* chunk_render(PyObject* self, PyObject* args);
typedef enum {
KNOWN,
TRANSPARENT,
SOLID,
FLUID,
NOSPAWN,
NODATA,
} 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 short 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)
#define is_known_transparent(b) block_has_property((b), TRANSPARENT) && block_has_property((b), KNOWN)
/* helper for indexing section data possibly across section boundaries */
typedef enum {
BLOCKS,
DATA,
BLOCKLIGHT,
SKYLIGHT,
BIOMES,
} DataType;
static inline unsigned int get_data(RenderState* state, DataType type, int x, int y, int z) {
int chunkx = 1, chunky = state->chunky, chunkz = 1;
PyArrayObject* data_array = NULL;
unsigned int def = 0;
if (type == SKYLIGHT)
def = 15;
if (x >= 16) {
x -= 16;
chunkx++;
} else if (x < 0) {
x += 16;
chunkx--;
}
if (z >= 16) {
z -= 16;
chunkz++;
} else if (z < 0) {
z += 16;
chunkz--;
}
while (y >= 16) {
y -= 16;
chunky++;
}
while (y < 0) {
y += 16;
chunky--;
}
if (chunky < 0 || chunky >= SECTIONS_PER_CHUNK)
return def;
if (!(state->chunks[chunkx][chunkz].loaded)) {
if (load_chunk(state, chunkx - 1, chunkz - 1, 0))
return def;
}
switch (type) {
case BLOCKS:
data_array = state->chunks[chunkx][chunkz].sections[chunky].blocks;
break;
case DATA:
data_array = state->chunks[chunkx][chunkz].sections[chunky].data;
break;
case BLOCKLIGHT:
data_array = state->chunks[chunkx][chunkz].sections[chunky].blocklight;
break;
case SKYLIGHT:
data_array = state->chunks[chunkx][chunkz].sections[chunky].skylight;
break;
case BIOMES:
data_array = state->chunks[chunkx][chunkz].biomes;
};
if (data_array == NULL)
return def;
if (type == BLOCKS)
return getArrayShort3D(data_array, x, y, z);
if (type == BIOMES)
return getArrayByte2D(data_array, x, z);
return getArrayByte3D(data_array, x, y, z);
}
/* pull in the rendermode info */
#include "rendermodes.h"
/* in endian.c */
void init_endian(void);
unsigned short big_endian_ushort(unsigned short in);
unsigned int big_endian_uint(unsigned int in);
#endif /* __OVERVIEWER_H_INCLUDED__ */