Add .clang_format

Also applies clang-format to the current code base, using command:
`find . -regex '.*\.\(c\|h\)' -exec clang-format -style=file -i {} \;`
This commit is contained in:
Wunkolo 2019-06-23 18:43:32 -07:00
parent 676bf32af9
commit 8162f3f877
36 changed files with 1299 additions and 1372 deletions

38
.clang-format Normal file
View File

@ -0,0 +1,38 @@
---
Language: Cpp
AlignEscapedNewlinesLeft: 'true'
AlignTrailingComments: 'true'
AllowShortBlocksOnASingleLine: 'false'
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: 'false'
AllowShortLoopsOnASingleLine: 'false'
ColumnLimit: '0'
ContinuationIndentWidth: '4'
IndentWidth: '4'
SortIncludes: true
IncludeCategories:
- Regex: '<[[:alnum:].]+>'
Priority: -1
- Regex: '\".*\"'
Priority: 1
IndentCaseLabels: false
MaxEmptyLinesToKeep: '1'
PointerAlignment: Left
SpaceBeforeAssignmentOperators: 'true'
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: 'false'
SpacesBeforeTrailingComments: '1'
SpacesInCStyleCastParentheses: 'false'
SpacesInContainerLiterals: 'false'
SpacesInParentheses: 'false'
TabWidth: '4'
BreakBeforeTernaryOperators: true
Cpp11BracedListStyle: true
BreakBeforeBraces: Custom
BraceWrapping:
BeforeElse: false
AfterEnum: false
AfterFunction: false
AfterStruct: false
AfterUnion: false
...

View File

@ -59,8 +59,8 @@
#include <math.h> #include <math.h>
#define CEIL(v) (int) ceil(v) #define CEIL(v) (int)ceil(v)
#define FLOOR(v) ((v) >= 0.0 ? (int) (v) : (int) floor(v)) #define FLOOR(v) ((v) >= 0.0 ? (int)(v) : (int)floor(v))
#define INK8(ink) (*(UINT8*)ink) #define INK8(ink) (*(UINT8*)ink)
#define INK32(ink) (*(INT32*)ink) #define INK32(ink) (*(INT32*)ink)
@ -78,27 +78,24 @@ typedef struct {
} Edge; } Edge;
static inline void static inline void
point8(Imaging im, int x, int y, int ink) point8(Imaging im, int x, int y, int ink) {
{
if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize)
im->image8[y][x] = (UINT8) ink; im->image8[y][x] = (UINT8)ink;
} }
static inline void static inline void
point32(Imaging im, int x, int y, int ink) point32(Imaging im, int x, int y, int ink) {
{
if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize)
im->image32[y][x] = ink; im->image32[y][x] = ink;
} }
static inline void static inline void
point32rgba(Imaging im, int x, int y, int ink) point32rgba(Imaging im, int x, int y, int ink) {
{
unsigned int tmp1, tmp2; unsigned int tmp1, tmp2;
if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) { if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) {
UINT8* out = (UINT8*) im->image[y]+x*4; UINT8* out = (UINT8*)im->image[y] + x * 4;
UINT8* in = (UINT8*) &ink; UINT8* in = (UINT8*)&ink;
out[0] = OV_BLEND(in[3], out[0], in[0], tmp1, tmp2); out[0] = OV_BLEND(in[3], out[0], in[0], tmp1, tmp2);
out[1] = OV_BLEND(in[3], out[1], in[1], tmp1, tmp2); out[1] = OV_BLEND(in[3], out[1], in[1], tmp1, tmp2);
out[2] = OV_BLEND(in[3], out[2], in[2], tmp1, tmp2); out[2] = OV_BLEND(in[3], out[2], in[2], tmp1, tmp2);
@ -106,8 +103,7 @@ point32rgba(Imaging im, int x, int y, int ink)
} }
static inline void static inline void
hline8(Imaging im, int x0, int y0, int x1, int ink) hline8(Imaging im, int x0, int y0, int x1, int ink) {
{
int tmp; int tmp;
if (y0 >= 0 && y0 < im->ysize) { if (y0 >= 0 && y0 < im->ysize) {
@ -120,15 +116,14 @@ hline8(Imaging im, int x0, int y0, int x1, int ink)
if (x1 < 0) if (x1 < 0)
return; return;
else if (x1 >= im->xsize) else if (x1 >= im->xsize)
x1 = im->xsize-1; x1 = im->xsize - 1;
if (x0 <= x1) if (x0 <= x1)
memset(im->image8[y0] + x0, (UINT8) ink, x1 - x0 + 1); memset(im->image8[y0] + x0, (UINT8)ink, x1 - x0 + 1);
} }
} }
static inline void static inline void
hline32(Imaging im, int x0, int y0, int x1, int ink) hline32(Imaging im, int x0, int y0, int x1, int ink) {
{
int tmp; int tmp;
INT32* p; INT32* p;
@ -142,7 +137,7 @@ hline32(Imaging im, int x0, int y0, int x1, int ink)
if (x1 < 0) if (x1 < 0)
return; return;
else if (x1 >= im->xsize) else if (x1 >= im->xsize)
x1 = im->xsize-1; x1 = im->xsize - 1;
p = im->image32[y0]; p = im->image32[y0];
while (x0 <= x1) while (x0 <= x1)
p[x0++] = ink; p[x0++] = ink;
@ -150,8 +145,7 @@ hline32(Imaging im, int x0, int y0, int x1, int ink)
} }
static inline void static inline void
hline32rgba(Imaging im, int x0, int y0, int x1, int ink) hline32rgba(Imaging im, int x0, int y0, int x1, int ink) {
{
int tmp; int tmp;
unsigned int tmp1, tmp2; unsigned int tmp1, tmp2;
@ -165,34 +159,34 @@ hline32rgba(Imaging im, int x0, int y0, int x1, int ink)
if (x1 < 0) if (x1 < 0)
return; return;
else if (x1 >= im->xsize) else if (x1 >= im->xsize)
x1 = im->xsize-1; x1 = im->xsize - 1;
if (x0 <= x1) { if (x0 <= x1) {
UINT8* out = (UINT8*) im->image[y0]+x0*4; UINT8* out = (UINT8*)im->image[y0] + x0 * 4;
UINT8* in = (UINT8*) &ink; UINT8* in = (UINT8*)&ink;
while (x0 <= x1) { while (x0 <= x1) {
out[0] = OV_BLEND(in[3], out[0], in[0], tmp1, tmp2); out[0] = OV_BLEND(in[3], out[0], in[0], tmp1, tmp2);
out[1] = OV_BLEND(in[3], out[1], in[1], tmp1, tmp2); out[1] = OV_BLEND(in[3], out[1], in[1], tmp1, tmp2);
out[2] = OV_BLEND(in[3], out[2], in[2], tmp1, tmp2); out[2] = OV_BLEND(in[3], out[2], in[2], tmp1, tmp2);
x0++; out += 4; x0++;
out += 4;
} }
} }
} }
} }
static inline void static inline void
line8(Imaging im, int x0, int y0, int x1, int y1, int ink) line8(Imaging im, int x0, int y0, int x1, int y1, int ink) {
{
int i, n, e; int i, n, e;
int dx, dy; int dx, dy;
int xs, ys; int xs, ys;
/* normalize coordinates */ /* normalize coordinates */
dx = x1-x0; dx = x1 - x0;
if (dx < 0) if (dx < 0)
dx = -dx, xs = -1; dx = -dx, xs = -1;
else else
xs = 1; xs = 1;
dy = y1-y0; dy = y1 - y0;
if (dy < 0) if (dy < 0)
dy = -dy, ys = -1; dy = -dy, ys = -1;
else else
@ -251,24 +245,22 @@ line8(Imaging im, int x0, int y0, int x1, int y1, int ink)
e += dx; e += dx;
y0 += ys; y0 += ys;
} }
} }
} }
static inline void static inline void
line32(Imaging im, int x0, int y0, int x1, int y1, int ink) line32(Imaging im, int x0, int y0, int x1, int y1, int ink) {
{
int i, n, e; int i, n, e;
int dx, dy; int dx, dy;
int xs, ys; int xs, ys;
/* normalize coordinates */ /* normalize coordinates */
dx = x1-x0; dx = x1 - x0;
if (dx < 0) if (dx < 0)
dx = -dx, xs = -1; dx = -dx, xs = -1;
else else
xs = 1; xs = 1;
dy = y1-y0; dy = y1 - y0;
if (dy < 0) if (dy < 0)
dy = -dy, ys = -1; dy = -dy, ys = -1;
else else
@ -327,24 +319,22 @@ line32(Imaging im, int x0, int y0, int x1, int y1, int ink)
e += dx; e += dx;
y0 += ys; y0 += ys;
} }
} }
} }
static inline void static inline void
line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink) line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink) {
{
int i, n, e; int i, n, e;
int dx, dy; int dx, dy;
int xs, ys; int xs, ys;
/* normalize coordinates */ /* normalize coordinates */
dx = x1-x0; dx = x1 - x0;
if (dx < 0) if (dx < 0)
dx = -dx, xs = -1; dx = -dx, xs = -1;
else else
xs = 1; xs = 1;
dy = y1-y0; dy = y1 - y0;
if (dy < 0) if (dy < 0)
dy = -dy, ys = -1; dy = -dy, ys = -1;
else else
@ -403,13 +393,11 @@ line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink)
e += dx; e += dx;
y0 += ys; y0 += ys;
} }
} }
} }
static int static int
x_cmp(const void *x0, const void *x1) x_cmp(const void* x0, const void* x1) {
{
float diff = *((float*)x0) - *((float*)x1); float diff = *((float*)x0) - *((float*)x1);
if (diff < 0) if (diff < 0)
return -1; return -1;
@ -420,10 +408,9 @@ x_cmp(const void *x0, const void *x1)
} }
static inline int static inline int
polygon8(Imaging im, int n, Edge *e, int ink, int eofill) polygon8(Imaging im, int n, Edge* e, int ink, int eofill) {
{
int i, j; int i, j;
float *xx; float* xx;
int ymin, ymax; int ymin, ymax;
float y; float y;
@ -435,14 +422,16 @@ polygon8(Imaging im, int n, Edge *e, int ink, int eofill)
ymin = e[0].ymin; ymin = e[0].ymin;
ymax = e[0].ymax; ymax = e[0].ymax;
for (i = 1; i < n; i++) { for (i = 1; i < n; i++) {
if (e[i].ymin < ymin) ymin = e[i].ymin; if (e[i].ymin < ymin)
if (e[i].ymax > ymax) ymax = e[i].ymax; ymin = e[i].ymin;
if (e[i].ymax > ymax)
ymax = e[i].ymax;
} }
if (ymin < 0) if (ymin < 0)
ymin = 0; ymin = 0;
if (ymax >= im->ysize) if (ymax >= im->ysize)
ymax = im->ysize-1; ymax = im->ysize - 1;
/* Process polygon edges */ /* Process polygon edges */
@ -450,24 +439,24 @@ polygon8(Imaging im, int n, Edge *e, int ink, int eofill)
if (!xx) if (!xx)
return -1; return -1;
for (;ymin <= ymax; ymin++) { for (; ymin <= ymax; ymin++) {
y = ymin+0.5F; y = ymin + 0.5F;
for (i = j = 0; i < n; i++) for (i = j = 0; i < n; i++)
if (y >= e[i].ymin && y <= e[i].ymax) { if (y >= e[i].ymin && y <= e[i].ymax) {
if (e[i].d == 0) if (e[i].d == 0)
hline8(im, e[i].xmin, ymin, e[i].xmax, ink); hline8(im, e[i].xmin, ymin, e[i].xmax, ink);
else else
xx[j++] = (y-e[i].y0) * e[i].dx + e[i].x0; xx[j++] = (y - e[i].y0) * e[i].dx + e[i].x0;
} }
if (j == 2) { if (j == 2) {
if (xx[0] < xx[1]) if (xx[0] < xx[1])
hline8(im, CEIL(xx[0]-0.5), ymin, FLOOR(xx[1]+0.5), ink); hline8(im, CEIL(xx[0] - 0.5), ymin, FLOOR(xx[1] + 0.5), ink);
else else
hline8(im, CEIL(xx[1]-0.5), ymin, FLOOR(xx[0]+0.5), ink); hline8(im, CEIL(xx[1] - 0.5), ymin, FLOOR(xx[0] + 0.5), ink);
} else { } else {
qsort(xx, j, sizeof(float), x_cmp); qsort(xx, j, sizeof(float), x_cmp);
for (i = 0; i < j-1 ; i += 2) for (i = 0; i < j - 1; i += 2)
hline8(im, CEIL(xx[i]-0.5), ymin, FLOOR(xx[i+1]+0.5), ink); hline8(im, CEIL(xx[i] - 0.5), ymin, FLOOR(xx[i + 1] + 0.5), ink);
} }
} }
@ -477,10 +466,9 @@ polygon8(Imaging im, int n, Edge *e, int ink, int eofill)
} }
static inline int static inline int
polygon32(Imaging im, int n, Edge *e, int ink, int eofill) polygon32(Imaging im, int n, Edge* e, int ink, int eofill) {
{
int i, j; int i, j;
float *xx; float* xx;
int ymin, ymax; int ymin, ymax;
float y; float y;
@ -492,14 +480,16 @@ polygon32(Imaging im, int n, Edge *e, int ink, int eofill)
ymin = e[0].ymin; ymin = e[0].ymin;
ymax = e[0].ymax; ymax = e[0].ymax;
for (i = 1; i < n; i++) { for (i = 1; i < n; i++) {
if (e[i].ymin < ymin) ymin = e[i].ymin; if (e[i].ymin < ymin)
if (e[i].ymax > ymax) ymax = e[i].ymax; ymin = e[i].ymin;
if (e[i].ymax > ymax)
ymax = e[i].ymax;
} }
if (ymin < 0) if (ymin < 0)
ymin = 0; ymin = 0;
if (ymax >= im->ysize) if (ymax >= im->ysize)
ymax = im->ysize-1; ymax = im->ysize - 1;
/* Process polygon edges */ /* Process polygon edges */
@ -507,25 +497,25 @@ polygon32(Imaging im, int n, Edge *e, int ink, int eofill)
if (!xx) if (!xx)
return -1; return -1;
for (;ymin <= ymax; ymin++) { for (; ymin <= ymax; ymin++) {
y = ymin+0.5F; y = ymin + 0.5F;
for (i = j = 0; i < n; i++) { for (i = j = 0; i < n; i++) {
if (y >= e[i].ymin && y <= e[i].ymax) { if (y >= e[i].ymin && y <= e[i].ymax) {
if (e[i].d == 0) if (e[i].d == 0)
hline32(im, e[i].xmin, ymin, e[i].xmax, ink); hline32(im, e[i].xmin, ymin, e[i].xmax, ink);
else else
xx[j++] = (y-e[i].y0) * e[i].dx + e[i].x0; xx[j++] = (y - e[i].y0) * e[i].dx + e[i].x0;
} }
} }
if (j == 2) { if (j == 2) {
if (xx[0] < xx[1]) if (xx[0] < xx[1])
hline32(im, CEIL(xx[0]-0.5), ymin, FLOOR(xx[1]+0.5), ink); hline32(im, CEIL(xx[0] - 0.5), ymin, FLOOR(xx[1] + 0.5), ink);
else else
hline32(im, CEIL(xx[1]-0.5), ymin, FLOOR(xx[0]+0.5), ink); hline32(im, CEIL(xx[1] - 0.5), ymin, FLOOR(xx[0] + 0.5), ink);
} else { } else {
qsort(xx, j, sizeof(float), x_cmp); qsort(xx, j, sizeof(float), x_cmp);
for (i = 0; i < j-1 ; i += 2) for (i = 0; i < j - 1; i += 2)
hline32(im, CEIL(xx[i]-0.5), ymin, FLOOR(xx[i+1]+0.5), ink); hline32(im, CEIL(xx[i] - 0.5), ymin, FLOOR(xx[i + 1] + 0.5), ink);
} }
} }
@ -535,10 +525,9 @@ polygon32(Imaging im, int n, Edge *e, int ink, int eofill)
} }
static inline int static inline int
polygon32rgba(Imaging im, int n, Edge *e, int ink, int eofill) polygon32rgba(Imaging im, int n, Edge* e, int ink, int eofill) {
{
int i, j; int i, j;
float *xx; float* xx;
int ymin, ymax; int ymin, ymax;
float y; float y;
@ -550,14 +539,16 @@ polygon32rgba(Imaging im, int n, Edge *e, int ink, int eofill)
ymin = e[0].ymin; ymin = e[0].ymin;
ymax = e[0].ymax; ymax = e[0].ymax;
for (i = 1; i < n; i++) { for (i = 1; i < n; i++) {
if (e[i].ymin < ymin) ymin = e[i].ymin; if (e[i].ymin < ymin)
if (e[i].ymax > ymax) ymax = e[i].ymax; ymin = e[i].ymin;
if (e[i].ymax > ymax)
ymax = e[i].ymax;
} }
if (ymin < 0) if (ymin < 0)
ymin = 0; ymin = 0;
if (ymax >= im->ysize) if (ymax >= im->ysize)
ymax = im->ysize-1; ymax = im->ysize - 1;
/* Process polygon edges */ /* Process polygon edges */
@ -565,25 +556,25 @@ polygon32rgba(Imaging im, int n, Edge *e, int ink, int eofill)
if (!xx) if (!xx)
return -1; return -1;
for (;ymin <= ymax; ymin++) { for (; ymin <= ymax; ymin++) {
y = ymin+0.5F; y = ymin + 0.5F;
for (i = j = 0; i < n; i++) { for (i = j = 0; i < n; i++) {
if (y >= e[i].ymin && y <= e[i].ymax) { if (y >= e[i].ymin && y <= e[i].ymax) {
if (e[i].d == 0) if (e[i].d == 0)
hline32rgba(im, e[i].xmin, ymin, e[i].xmax, ink); hline32rgba(im, e[i].xmin, ymin, e[i].xmax, ink);
else else
xx[j++] = (y-e[i].y0) * e[i].dx + e[i].x0; xx[j++] = (y - e[i].y0) * e[i].dx + e[i].x0;
} }
} }
if (j == 2) { if (j == 2) {
if (xx[0] < xx[1]) if (xx[0] < xx[1])
hline32rgba(im, CEIL(xx[0]-0.5), ymin, FLOOR(xx[1]+0.5), ink); hline32rgba(im, CEIL(xx[0] - 0.5), ymin, FLOOR(xx[1] + 0.5), ink);
else else
hline32rgba(im, CEIL(xx[1]-0.5), ymin, FLOOR(xx[0]+0.5), ink); hline32rgba(im, CEIL(xx[1] - 0.5), ymin, FLOOR(xx[0] + 0.5), ink);
} else { } else {
qsort(xx, j, sizeof(float), x_cmp); qsort(xx, j, sizeof(float), x_cmp);
for (i = 0; i < j-1 ; i += 2) for (i = 0; i < j - 1; i += 2)
hline32rgba(im, CEIL(xx[i]-0.5), ymin, FLOOR(xx[i+1]+0.5), ink); hline32rgba(im, CEIL(xx[i] - 0.5), ymin, FLOOR(xx[i + 1] + 0.5), ink);
} }
} }
@ -593,8 +584,7 @@ polygon32rgba(Imaging im, int n, Edge *e, int ink, int eofill)
} }
static inline void static inline void
add_edge(Edge *e, int x0, int y0, int x1, int y1) add_edge(Edge* e, int x0, int y0, int x1, int y1) {
{
/* printf("edge %d %d %d %d\n", x0, y0, x1, y1); */ /* printf("edge %d %d %d %d\n", x0, y0, x1, y1); */
if (x0 <= x1) if (x0 <= x1)
@ -606,12 +596,12 @@ add_edge(Edge *e, int x0, int y0, int x1, int y1)
e->ymin = y0, e->ymax = y1; e->ymin = y0, e->ymax = y1;
else else
e->ymin = y1, e->ymax = y0; e->ymin = y1, e->ymax = y0;
if (y0 == y1) { if (y0 == y1) {
e->d = 0; e->d = 0;
e->dx = 0.0; e->dx = 0.0;
} else { } else {
e->dx = ((float)(x1-x0)) / (y1-y0); e->dx = ((float)(x1 - x0)) / (y1 - y0);
if (y0 == e->ymin) if (y0 == e->ymin)
e->d = 1; e->d = 1;
else else
@ -626,29 +616,27 @@ typedef struct {
void (*point)(Imaging im, int x, int y, int ink); void (*point)(Imaging im, int x, int y, int ink);
void (*hline)(Imaging im, int x0, int y0, int x1, int ink); void (*hline)(Imaging im, int x0, int y0, int x1, int ink);
void (*line)(Imaging im, int x0, int y0, int x1, int y1, int ink); void (*line)(Imaging im, int x0, int y0, int x1, int y1, int ink);
int (*polygon)(Imaging im, int n, Edge *e, int ink, int eofill); int (*polygon)(Imaging im, int n, Edge* e, int ink, int eofill);
} DRAW; } DRAW;
DRAW draw8 = { point8, hline8, line8, polygon8 }; DRAW draw8 = {point8, hline8, line8, polygon8};
DRAW draw32 = { point32, hline32, line32, polygon32 }; DRAW draw32 = {point32, hline32, line32, polygon32};
DRAW draw32rgba = { point32rgba, hline32rgba, line32rgba, polygon32rgba }; DRAW draw32rgba = {point32rgba, hline32rgba, line32rgba, polygon32rgba};
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/* Interface */ /* Interface */
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
#define DRAWINIT()\ #define DRAWINIT() \
if (im->image8) {\ if (im->image8) { \
draw = &draw8;\ draw = &draw8; \
ink = INK8(ink_);\ ink = INK8(ink_); \
} else {\ } else { \
draw = (op) ? &draw32rgba : &draw32; \ draw = (op) ? &draw32rgba : &draw32; \
ink = INK32(ink_);\ ink = INK32(ink_); \
} }
int int ImagingDrawPoint(Imaging im, int x0, int y0, const void* ink_, int op) {
ImagingDrawPoint(Imaging im, int x0, int y0, const void* ink_, int op)
{
DRAW* draw; DRAW* draw;
INT32 ink; INT32 ink;
@ -659,10 +647,8 @@ ImagingDrawPoint(Imaging im, int x0, int y0, const void* ink_, int op)
return 0; return 0;
} }
int int ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, const void* ink_,
ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, const void* ink_, int op) {
int op)
{
DRAW* draw; DRAW* draw;
INT32 ink; INT32 ink;
@ -673,10 +659,8 @@ ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, const void* ink_,
return 0; return 0;
} }
int int ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1,
ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1, const void* ink_, int width, int op) {
const void* ink_, int width, int op)
{
DRAW* draw; DRAW* draw;
INT32 ink; INT32 ink;
@ -692,31 +676,29 @@ ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1,
return 0; return 0;
} }
dx = x1-x0; dx = x1 - x0;
dy = y1-y0; dy = y1 - y0;
if (dx == 0 && dy == 0) { if (dx == 0 && dy == 0) {
draw->point(im, x0, y0, ink); draw->point(im, x0, y0, ink);
return 0; return 0;
} }
d = width / sqrt((float) (dx*dx + dy*dy)) / 2.0; d = width / sqrt((float)(dx * dx + dy * dy)) / 2.0;
dx = (int) floor(d * (y1-y0) + 0.5); dx = (int)floor(d * (y1 - y0) + 0.5);
dy = (int) floor(d * (x1-x0) + 0.5); dy = (int)floor(d * (x1 - x0) + 0.5);
add_edge(e+0, x0 - dx, y0 + dy, x1 - dx, y1 + dy); add_edge(e + 0, x0 - dx, y0 + dy, x1 - dx, y1 + dy);
add_edge(e+1, x1 - dx, y1 + dy, x1 + dx, y1 - dy); add_edge(e + 1, x1 - dx, y1 + dy, x1 + dx, y1 - dy);
add_edge(e+2, x1 + dx, y1 - dy, x0 + dx, y0 - dy); add_edge(e + 2, x1 + dx, y1 - dy, x0 + dx, y0 - dy);
add_edge(e+3, x0 + dx, y0 - dy, x0 - dx, y0 + dy); add_edge(e + 3, x0 + dx, y0 - dy, x0 - dx, y0 + dy);
draw->polygon(im, 4, e, ink, 0); draw->polygon(im, 4, e, ink, 0);
return 0; return 0;
} }
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/* standard shapes */ /* standard shapes */
@ -724,7 +706,6 @@ ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1,
#define CHORD 1 #define CHORD 1
#define PIESLICE 2 #define PIESLICE 2
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/* experimental level 2 ("arrow") graphics stuff. this implements /* experimental level 2 ("arrow") graphics stuff. this implements
@ -741,17 +722,12 @@ struct ImagingOutlineInstance {
float x, y; float x, y;
int count; int count;
Edge *edges; Edge* edges;
int size; int size;
}; };
void ImagingOutlineDelete(ImagingOutline outline) {
void
ImagingOutlineDelete(ImagingOutline outline)
{
if (!outline) if (!outline)
return; return;
@ -761,10 +737,8 @@ ImagingOutlineDelete(ImagingOutline outline)
free(outline); free(outline);
} }
static Edge* static Edge*
allocate(ImagingOutline outline, int extra) allocate(ImagingOutline outline, int extra) {
{
Edge* e; Edge* e;
if (outline->count + extra > outline->size) { if (outline->count + extra > outline->size) {
@ -786,36 +760,30 @@ allocate(ImagingOutline outline, int extra)
return e; return e;
} }
int int ImagingOutlineMove(ImagingOutline outline, float x0, float y0) {
ImagingOutlineMove(ImagingOutline outline, float x0, float y0)
{
outline->x = outline->x0 = x0; outline->x = outline->x0 = x0;
outline->y = outline->y0 = y0; outline->y = outline->y0 = y0;
return 0; return 0;
} }
int int ImagingOutlineLine(ImagingOutline outline, float x1, float y1) {
ImagingOutlineLine(ImagingOutline outline, float x1, float y1)
{
Edge* e; Edge* e;
e = allocate(outline, 1); e = allocate(outline, 1);
if (!e) if (!e)
return -1; /* out of memory */ return -1; /* out of memory */
add_edge(e, (int) outline->x, (int) outline->y, (int) x1, (int) y1); add_edge(e, (int)outline->x, (int)outline->y, (int)x1, (int)y1);
outline->x = x1; outline->x = x1;
outline->y = y1; outline->y = y1;
return 0; return 0;
} }
int int ImagingOutlineCurve(ImagingOutline outline, float x1, float y1,
ImagingOutlineCurve(ImagingOutline outline, float x1, float y1, float x2, float y2, float x3, float y3) {
float x2, float y2, float x3, float y3)
{
Edge* e; Edge* e;
int i; int i;
float xo, yo; float xo, yo;
@ -833,56 +801,48 @@ ImagingOutlineCurve(ImagingOutline outline, float x1, float y1,
for (i = 1; i <= STEPS; i++) { for (i = 1; i <= STEPS; i++) {
float t = ((float) i) / STEPS; float t = ((float)i) / STEPS;
float t2 = t*t; float t2 = t * t;
float t3 = t2*t; float t3 = t2 * t;
float u = 1.0F - t; float u = 1.0F - t;
float u2 = u*u; float u2 = u * u;
float u3 = u2*u; float u3 = u2 * u;
float x = outline->x*u3 + 3*(x1*t*u2 + x2*t2*u) + x3*t3 + 0.5; float x = outline->x * u3 + 3 * (x1 * t * u2 + x2 * t2 * u) + x3 * t3 + 0.5;
float y = outline->y*u3 + 3*(y1*t*u2 + y2*t2*u) + y3*t3 + 0.5; float y = outline->y * u3 + 3 * (y1 * t * u2 + y2 * t2 * u) + y3 * t3 + 0.5;
add_edge(e++, xo, yo, (int) x, (int) y); add_edge(e++, xo, yo, (int)x, (int)y);
xo = x, yo = y; xo = x, yo = y;
} }
outline->x = xo; outline->x = xo;
outline->y = yo; outline->y = yo;
return 0; return 0;
} }
int int ImagingOutlineCurve2(ImagingOutline outline, float cx, float cy,
ImagingOutlineCurve2(ImagingOutline outline, float cx, float cy, float x3, float y3) {
float x3, float y3)
{
/* add bezier curve based on three control points (as /* add bezier curve based on three control points (as
in the Flash file format) */ in the Flash file format) */
return ImagingOutlineCurve( return ImagingOutlineCurve(
outline, outline,
(outline->x + cx + cx)/3, (outline->y + cy + cy)/3, (outline->x + cx + cx) / 3, (outline->y + cy + cy) / 3,
(cx + cx + x3)/3, (cy + cy + y3)/3, (cx + cx + x3) / 3, (cy + cy + y3) / 3,
x3, y3); x3, y3);
} }
int int ImagingOutlineClose(ImagingOutline outline) {
ImagingOutlineClose(ImagingOutline outline)
{
if (outline->x == outline->x0 && outline->y == outline->y0) if (outline->x == outline->x0 && outline->y == outline->y0)
return 0; return 0;
return ImagingOutlineLine(outline, outline->x0, outline->y0); return ImagingOutlineLine(outline, outline->x0, outline->y0);
} }
int ImagingDrawOutline(Imaging im, ImagingOutline outline, const void* ink_,
int int fill, int op) {
ImagingDrawOutline(Imaging im, ImagingOutline outline, const void* ink_,
int fill, int op)
{
DRAW* draw; DRAW* draw;
INT32 ink; INT32 ink;

View File

@ -23,190 +23,179 @@
#endif #endif
bool block_class_is_subset( bool block_class_is_subset(
mc_block_t block, mc_block_t block,
const mc_block_t block_class[], const mc_block_t block_class[],
size_t block_class_len size_t block_class_len) {
) { size_t i = 0;
size_t i = 0;
#ifdef __SSE2__ #ifdef __SSE2__
for (; i / 8 < block_class_len / 8; i += 8) { for (; i / 8 < block_class_len / 8; i += 8) {
const __m128i block_class_vec = _mm_loadu_si128( const __m128i block_class_vec = _mm_loadu_si128(
(__m128i*)&block_class[i] (__m128i*)&block_class[i]);
); const __m128i block_vec = _mm_set1_epi16(block);
const __m128i block_vec = _mm_set1_epi16(block); const __m128i block_cmp = _mm_cmpeq_epi16(block_vec, block_class_vec);
const __m128i block_cmp = _mm_cmpeq_epi16(block_vec,block_class_vec); if (_mm_movemask_epi8(block_cmp)) {
if (_mm_movemask_epi8(block_cmp)) { return true;
return true; }
} }
}
#endif #endif
#ifdef __MMX__ #ifdef __MMX__
for (; i / 4 < block_class_len / 4; i += 4) { for (; i / 4 < block_class_len / 4; i += 4) {
const __m64 block_class_vec = _mm_cvtsi64_m64( const __m64 block_class_vec = _mm_cvtsi64_m64(
*(uint64_t*)&block_class[i] *(uint64_t*)&block_class[i]);
); const __m64 block_vec = _mm_set1_pi16(block);
const __m64 block_vec = _mm_set1_pi16(block); const __m64 block_cmp = _mm_cmpeq_pi16(block_vec, block_class_vec);
const __m64 block_cmp = _mm_cmpeq_pi16(block_vec,block_class_vec); if (_mm_cvtm64_si64(block_cmp)) {
if (_mm_cvtm64_si64(block_cmp)) { return true;
return true; }
} }
}
#endif #endif
for (; i < block_class_len; ++i) { for (; i < block_class_len; ++i) {
if (block == block_class[i]) { if (block == block_class[i]) {
return true; return true;
} }
} }
return false; return false;
} }
const mc_block_t block_class_stair[] = { const mc_block_t block_class_stair[] = {
block_oak_stairs, block_oak_stairs,
block_stone_stairs, block_stone_stairs,
block_brick_stairs, block_brick_stairs,
block_stone_brick_stairs, block_stone_brick_stairs,
block_nether_brick_stairs, block_nether_brick_stairs,
block_sandstone_stairs, block_sandstone_stairs,
block_spruce_stairs, block_spruce_stairs,
block_birch_stairs, block_birch_stairs,
block_jungle_stairs, block_jungle_stairs,
block_quartz_stairs, block_quartz_stairs,
block_acacia_stairs, block_acacia_stairs,
block_dark_oak_stairs, block_dark_oak_stairs,
block_red_sandstone_stairs, block_red_sandstone_stairs,
block_purpur_stairs, block_purpur_stairs,
block_prismarine_stairs, block_prismarine_stairs,
block_dark_prismarine_stairs, block_dark_prismarine_stairs,
block_prismarine_brick_stairs block_prismarine_brick_stairs};
};
const size_t block_class_stair_len = COUNT_OF(block_class_stair); const size_t block_class_stair_len = COUNT_OF(block_class_stair);
const mc_block_t block_class_door[] = { const mc_block_t block_class_door[] = {
block_wooden_door, block_wooden_door,
block_iron_door, block_iron_door,
block_spruce_door, block_spruce_door,
block_birch_door, block_birch_door,
block_jungle_door, block_jungle_door,
block_acacia_door, block_acacia_door,
block_dark_oak_door block_dark_oak_door};
};
const size_t block_class_door_len = COUNT_OF(block_class_door); const size_t block_class_door_len = COUNT_OF(block_class_door);
const mc_block_t block_class_fence[] = { const mc_block_t block_class_fence[] = {
block_fence, block_fence,
block_nether_brick_fence, block_nether_brick_fence,
block_spruce_fence, block_spruce_fence,
block_birch_fence, block_birch_fence,
block_jungle_fence, block_jungle_fence,
block_dark_oak_fence, block_dark_oak_fence,
block_acacia_fence block_acacia_fence};
};
const size_t block_class_fence_len = COUNT_OF(block_class_fence); const size_t block_class_fence_len = COUNT_OF(block_class_fence);
const mc_block_t block_class_fence_gate[] = { const mc_block_t block_class_fence_gate[] = {
block_fence_gate, block_fence_gate,
block_spruce_fence_gate, block_spruce_fence_gate,
block_birch_fence_gate, block_birch_fence_gate,
block_jungle_fence_gate, block_jungle_fence_gate,
block_dark_oak_fence_gate, block_dark_oak_fence_gate,
block_acacia_fence_gate block_acacia_fence_gate};
};
const size_t block_class_fence_gate_len = COUNT_OF(block_class_fence_gate); const size_t block_class_fence_gate_len = COUNT_OF(block_class_fence_gate);
const mc_block_t block_class_ancil[] = { const mc_block_t block_class_ancil[] = {
block_wooden_door, block_wooden_door,
block_iron_door, block_iron_door,
block_spruce_door, block_spruce_door,
block_birch_door, block_birch_door,
block_jungle_door, block_jungle_door,
block_acacia_door, block_acacia_door,
block_dark_oak_door, block_dark_oak_door,
block_oak_stairs, block_oak_stairs,
block_stone_stairs, block_stone_stairs,
block_brick_stairs, block_brick_stairs,
block_stone_brick_stairs, block_stone_brick_stairs,
block_nether_brick_stairs, block_nether_brick_stairs,
block_sandstone_stairs, block_sandstone_stairs,
block_spruce_stairs, block_spruce_stairs,
block_birch_stairs, block_birch_stairs,
block_jungle_stairs, block_jungle_stairs,
block_quartz_stairs, block_quartz_stairs,
block_acacia_stairs, block_acacia_stairs,
block_dark_oak_stairs, block_dark_oak_stairs,
block_red_sandstone_stairs, block_red_sandstone_stairs,
block_purpur_stairs, block_purpur_stairs,
block_prismarine_stairs, block_prismarine_stairs,
block_dark_prismarine_stairs, block_dark_prismarine_stairs,
block_prismarine_brick_stairs, block_prismarine_brick_stairs,
block_grass, block_grass,
block_flowing_water, block_flowing_water,
block_water, block_water,
block_glass, block_glass,
block_chest, block_chest,
block_redstone_wire, block_redstone_wire,
block_ice, block_ice,
block_fence, block_fence,
block_portal, block_portal,
block_iron_bars, block_iron_bars,
block_glass_pane, block_glass_pane,
block_waterlily, block_waterlily,
block_nether_brick_fence, block_nether_brick_fence,
block_cobblestone_wall, block_cobblestone_wall,
block_double_plant, block_double_plant,
block_stained_glass_pane, block_stained_glass_pane,
block_stained_glass, block_stained_glass,
block_trapped_chest, block_trapped_chest,
block_spruce_fence, block_spruce_fence,
block_birch_fence, block_birch_fence,
block_jungle_fence, block_jungle_fence,
block_dark_oak_fence, block_dark_oak_fence,
block_acacia_fence block_acacia_fence};
};
const size_t block_class_ancil_len = COUNT_OF(block_class_ancil); const size_t block_class_ancil_len = COUNT_OF(block_class_ancil);
const mc_block_t block_class_alt_height[] = { const mc_block_t block_class_alt_height[] = {
block_stone_slab, block_stone_slab,
block_oak_stairs, block_oak_stairs,
block_stone_stairs, block_stone_stairs,
block_brick_stairs, block_brick_stairs,
block_stone_brick_stairs, block_stone_brick_stairs,
block_nether_brick_stairs, block_nether_brick_stairs,
block_sandstone_stairs, block_sandstone_stairs,
block_spruce_stairs, block_spruce_stairs,
block_birch_stairs, block_birch_stairs,
block_jungle_stairs, block_jungle_stairs,
block_quartz_stairs, block_quartz_stairs,
block_acacia_stairs, block_acacia_stairs,
block_dark_oak_stairs, block_dark_oak_stairs,
block_red_sandstone_stairs, block_red_sandstone_stairs,
block_prismarine_stairs, block_prismarine_stairs,
block_dark_prismarine_stairs, block_dark_prismarine_stairs,
block_prismarine_brick_stairs, block_prismarine_brick_stairs,
block_prismarine_slab, block_prismarine_slab,
block_dark_prismarine_slab, block_dark_prismarine_slab,
block_prismarine_brick_slab, block_prismarine_brick_slab,
block_andesite_slab, block_andesite_slab,
block_diorite_slab, block_diorite_slab,
block_granite_slab, block_granite_slab,
block_polished_andesite_slab, block_polished_andesite_slab,
block_polished_diorite_slab, block_polished_diorite_slab,
block_polished_granite_slab, block_polished_granite_slab,
block_red_nether_brick_slab, block_red_nether_brick_slab,
block_smooth_sandstone_slab, block_smooth_sandstone_slab,
block_cut_sandstone_slab, block_cut_sandstone_slab,
block_smooth_red_sandstone_slab, block_smooth_red_sandstone_slab,
block_cut_red_sandstone_slab, block_cut_red_sandstone_slab,
block_end_stone_brick_slab, block_end_stone_brick_slab,
block_mossy_cobblestone_slab, block_mossy_cobblestone_slab,
block_mossy_stone_brick_slab, block_mossy_stone_brick_slab,
block_smooth_quartz_slab, block_smooth_quartz_slab,
block_smooth_stone_slab, block_smooth_stone_slab,
block_stone_slab2, block_stone_slab2,
block_purpur_stairs, block_purpur_stairs,
block_purpur_slab, block_purpur_slab,
block_wooden_slab block_wooden_slab};
};
const size_t block_class_alt_height_len = COUNT_OF(block_class_alt_height); const size_t block_class_alt_height_len = COUNT_OF(block_class_alt_height);

View File

@ -24,28 +24,26 @@
#include "mc_id.h" #include "mc_id.h"
bool block_class_is_subset( bool block_class_is_subset(
mc_block_t block, mc_block_t block,
const mc_block_t block_class[], const mc_block_t block_class[],
size_t block_class_len size_t block_class_len);
);
extern const mc_block_t block_class_stair[]; extern const mc_block_t block_class_stair[];
extern const size_t block_class_stair_len; extern const size_t block_class_stair_len;
extern const mc_block_t block_class_door[]; extern const mc_block_t block_class_door[];
extern const size_t block_class_door_len; extern const size_t block_class_door_len;
extern const mc_block_t block_class_fence[]; extern const mc_block_t block_class_fence[];
extern const size_t block_class_fence_len; extern const size_t block_class_fence_len;
extern const mc_block_t block_class_fence_gate[]; extern const mc_block_t block_class_fence_gate[];
extern const size_t block_class_fence_gate_len; extern const size_t block_class_fence_gate_len;
extern const mc_block_t block_class_ancil[]; extern const mc_block_t block_class_ancil[];
extern const size_t block_class_ancil_len; extern const size_t block_class_ancil_len;
extern const mc_block_t block_class_alt_height[]; extern const mc_block_t block_class_alt_height[];
extern const size_t block_class_alt_height_len; extern const size_t block_class_alt_height_len;
#endif #endif

View File

@ -26,13 +26,12 @@
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
Imaging image; Imaging image;
} ImagingObject; } ImagingObject;
inline Imaging inline Imaging
imaging_python_to_c(PyObject *obj) imaging_python_to_c(PyObject* obj) {
{ PyObject* im;
PyObject *im;
Imaging image; Imaging image;
/* first, get the 'im' attribute */ /* first, get the 'im' attribute */
@ -48,7 +47,7 @@ imaging_python_to_c(PyObject *obj)
return NULL; return NULL;
} }
image = ((ImagingObject *)im)->image; image = ((ImagingObject*)im)->image;
Py_DECREF(im); Py_DECREF(im);
return image; return image;
} }
@ -57,14 +56,13 @@ imaging_python_to_c(PyObject *obj)
in these composite functions -- even handles auto-sizing to src! */ in these composite functions -- even handles auto-sizing to src! */
static inline void static inline void
setup_source_destination(Imaging src, Imaging dest, setup_source_destination(Imaging src, Imaging dest,
int *sx, int *sy, int *dx, int *dy, int *xsize, int *ysize) int* sx, int* sy, int* dx, int* dy, int* xsize, int* ysize) {
{ /* handle negative/zero sizes appropriately */
/* handle negative/zero sizes appropriately */
if (*xsize <= 0 || *ysize <= 0) { if (*xsize <= 0 || *ysize <= 0) {
*xsize = src->xsize; *xsize = src->xsize;
*ysize = src->ysize; *ysize = src->ysize;
} }
/* set up the source position, size and destination position */ /* set up the source position, size and destination position */
/* handle negative dest pos */ /* handle negative dest pos */
if (*dx < 0) { if (*dx < 0) {
@ -93,7 +91,7 @@ setup_source_destination(Imaging src, Imaging dest,
} }
/* convenience alpha_over with 1.0 as overall_alpha */ /* convenience alpha_over with 1.0 as overall_alpha */
inline PyObject* alpha_over(PyObject *dest, PyObject *src, PyObject *mask, inline PyObject* alpha_over(PyObject* dest, PyObject* src, PyObject* mask,
int dx, int dy, int xsize, int ysize) { int dx, int dy, int xsize, int ysize) {
return alpha_over_full(dest, src, mask, 1.0f, dx, dy, xsize, ysize); return alpha_over_full(dest, src, mask, 1.0f, dx, dy, xsize, ysize);
} }
@ -103,8 +101,8 @@ inline PyObject* alpha_over(PyObject *dest, PyObject *src, PyObject *mask,
* if xsize, ysize are negative, they are instead set to the size of the image in src * if xsize, ysize are negative, they are instead set to the size of the image in src
* returns NULL on error, dest on success. You do NOT need to decref the return! * returns NULL on error, dest on success. You do NOT need to decref the return!
*/ */
inline PyObject * inline PyObject*
alpha_over_full(PyObject *dest, PyObject *src, PyObject *mask, float overall_alpha, alpha_over_full(PyObject* dest, PyObject* src, PyObject* mask, float overall_alpha,
int dx, int dy, int xsize, int ysize) { int dx, int dy, int xsize, int ysize) {
/* libImaging handles */ /* libImaging handles */
Imaging imDest, imSrc, imMask; Imaging imDest, imSrc, imMask;
@ -118,7 +116,7 @@ alpha_over_full(PyObject *dest, PyObject *src, PyObject *mask, float overall_alp
int tmp1, tmp2, tmp3; int tmp1, tmp2, tmp3;
/* integer [0, 255] version of overall_alpha */ /* integer [0, 255] version of overall_alpha */
UINT8 overall_alpha_int = 255 * overall_alpha; UINT8 overall_alpha_int = 255 * overall_alpha;
/* short-circuit this whole thing if overall_alpha is zero */ /* short-circuit this whole thing if overall_alpha is zero */
if (overall_alpha_int == 0) if (overall_alpha_int == 0)
return dest; return dest;
@ -173,21 +171,21 @@ alpha_over_full(PyObject *dest, PyObject *src, PyObject *mask, float overall_alp
} }
for (y = 0; y < ysize; y++) { for (y = 0; y < ysize; y++) {
UINT8 *out = (UINT8 *)imDest->image[dy + y] + dx * 4; UINT8* out = (UINT8*)imDest->image[dy + y] + dx * 4;
UINT8 *outmask = (UINT8 *)imDest->image[dy + y] + dx * 4 + 3; UINT8* outmask = (UINT8*)imDest->image[dy + y] + dx * 4 + 3;
UINT8 *in = (UINT8 *)imSrc->image[sy + y] + sx * (imSrc->pixelsize); UINT8* in = (UINT8*)imSrc->image[sy + y] + sx * (imSrc->pixelsize);
UINT8 *inmask = (UINT8 *)imMask->image[sy + y] + sx * mask_stride + mask_offset; UINT8* inmask = (UINT8*)imMask->image[sy + y] + sx * mask_stride + mask_offset;
for (x = 0; x < xsize; x++) { for (x = 0; x < xsize; x++) {
UINT8 in_alpha; UINT8 in_alpha;
/* apply overall_alpha */ /* apply overall_alpha */
if (overall_alpha_int != 255 && *inmask != 0) { if (overall_alpha_int != 255 && *inmask != 0) {
in_alpha = OV_MULDIV255(*inmask, overall_alpha_int, tmp1); in_alpha = OV_MULDIV255(*inmask, overall_alpha_int, tmp1);
} else { } else {
in_alpha = *inmask; in_alpha = *inmask;
} }
/* special cases */ /* special cases */
if (in_alpha == 255 || (*outmask == 0 && in_alpha > 0)) { if (in_alpha == 255 || (*outmask == 0 && in_alpha > 0)) {
*outmask = in_alpha; *outmask = in_alpha;
@ -208,8 +206,8 @@ alpha_over_full(PyObject *dest, PyObject *src, PyObject *mask, float overall_alp
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
/* general case */ /* general case */
*out = OV_MULDIV255(*in, in_alpha, tmp1) + *out = OV_MULDIV255(*in, in_alpha, tmp1) +
OV_MULDIV255(OV_MULDIV255(*out, *outmask, tmp2), 255 - in_alpha, tmp3); OV_MULDIV255(OV_MULDIV255(*out, *outmask, tmp2), 255 - in_alpha, tmp3);
*out = (*out * 255) / alpha; *out = (*out * 255) / alpha;
out++, in++; out++, in++;
} }
@ -230,22 +228,21 @@ alpha_over_full(PyObject *dest, PyObject *src, PyObject *mask, float overall_alp
/* wraps alpha_over so it can be called directly from python */ /* wraps alpha_over so it can be called directly from python */
/* properly refs the return value when needed: you DO need to decref the return */ /* properly refs the return value when needed: you DO need to decref the return */
PyObject * PyObject*
alpha_over_wrap(PyObject *self, PyObject *args) alpha_over_wrap(PyObject* self, PyObject* args) {
{
/* raw input python variables */ /* raw input python variables */
PyObject *dest, *src, *pos = NULL, *mask = NULL; PyObject *dest, *src, *pos = NULL, *mask = NULL;
/* destination position and size */ /* destination position and size */
int dx, dy, xsize, ysize; int dx, dy, xsize, ysize;
/* return value: dest image on success */ /* return value: dest image on success */
PyObject *ret; PyObject* ret;
if (!PyArg_ParseTuple(args, "OO|OO", &dest, &src, &pos, &mask)) if (!PyArg_ParseTuple(args, "OO|OO", &dest, &src, &pos, &mask))
return NULL; return NULL;
if (mask == NULL) if (mask == NULL)
mask = src; mask = src;
/* destination position read */ /* destination position read */
if (pos == NULL) { if (pos == NULL) {
xsize = 0; xsize = 0;
@ -277,10 +274,10 @@ alpha_over_wrap(PyObject *self, PyObject *args)
/* like alpha_over, but instead of src image it takes a source color /* like alpha_over, but instead of src image it takes a source color
* also, it multiplies instead of doing an over operation * also, it multiplies instead of doing an over operation
*/ */
PyObject * PyObject*
tint_with_mask(PyObject *dest, unsigned char sr, unsigned char sg, tint_with_mask(PyObject* dest, unsigned char sr, unsigned char sg,
unsigned char sb, unsigned char sa, unsigned char sb, unsigned char sa,
PyObject *mask, int dx, int dy, int xsize, int ysize) { PyObject* mask, int dx, int dy, int xsize, int ysize) {
/* libImaging handles */ /* libImaging handles */
Imaging imDest, imMask; Imaging imDest, imMask;
/* cached blend properties */ /* cached blend properties */
@ -326,8 +323,8 @@ tint_with_mask(PyObject *dest, unsigned char sr, unsigned char sg,
} }
for (y = 0; y < ysize; y++) { for (y = 0; y < ysize; y++) {
UINT8 *out = (UINT8 *)imDest->image[dy + y] + dx * 4; UINT8* out = (UINT8*)imDest->image[dy + y] + dx * 4;
UINT8 *inmask = (UINT8 *)imMask->image[sy + y] + sx * mask_stride + mask_offset; UINT8* inmask = (UINT8*)imMask->image[sy + y] + sx * mask_stride + mask_offset;
for (x = 0; x < xsize; x++) { for (x = 0; x < xsize; x++) {
/* special cases */ /* special cases */
@ -345,7 +342,7 @@ tint_with_mask(PyObject *dest, unsigned char sr, unsigned char sg,
out += 4; out += 4;
} else { } else {
/* general case */ /* general case */
/* TODO work out general case */ /* TODO work out general case */
*out = OV_MULDIV255(*out, (255 - *inmask) + OV_MULDIV255(sr, *inmask, tmp1), tmp2); *out = OV_MULDIV255(*out, (255 - *inmask) + OV_MULDIV255(sr, *inmask, tmp1), tmp2);
out++; out++;
@ -373,16 +370,16 @@ tint_with_mask(PyObject *dest, unsigned char sr, unsigned char sg,
* (or at least, the version poorly reproduced here: * (or at least, the version poorly reproduced here:
* http://www.gidforums.com/t-20838.html ) * http://www.gidforums.com/t-20838.html )
*/ */
PyObject * PyObject*
draw_triangle(PyObject *dest, int inclusive, draw_triangle(PyObject* dest, int inclusive,
int x0, int y0, int x0, int y0,
unsigned char r0, unsigned char g0, unsigned char b0, unsigned char r0, unsigned char g0, unsigned char b0,
int x1, int y1, int x1, int y1,
unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r1, unsigned char g1, unsigned char b1,
int x2, int y2, int x2, int y2,
unsigned char r2, unsigned char g2, unsigned char b2, unsigned char r2, unsigned char g2, unsigned char b2,
int tux, int tuy, int *touchups, unsigned int num_touchups) { int tux, int tuy, int* touchups, unsigned int num_touchups) {
/* destination image */ /* destination image */
Imaging imDest; Imaging imDest;
/* ranges of pixels that are affected */ /* ranges of pixels that are affected */
@ -397,7 +394,7 @@ draw_triangle(PyObject *dest, int inclusive,
int tmp; int tmp;
/* iteration variables */ /* iteration variables */
int x, y; int x, y;
imDest = imaging_python_to_c(dest); imDest = imaging_python_to_c(dest);
if (!imDest) if (!imDest)
return NULL; return NULL;
@ -408,48 +405,57 @@ draw_triangle(PyObject *dest, int inclusive,
"given destination image does not have mode \"RGBA\""); "given destination image does not have mode \"RGBA\"");
return NULL; return NULL;
} }
/* set up draw ranges */ /* set up draw ranges */
xmin = OV_MIN(x0, OV_MIN(x1, x2)); xmin = OV_MIN(x0, OV_MIN(x1, x2));
ymin = OV_MIN(y0, OV_MIN(y1, y2)); ymin = OV_MIN(y0, OV_MIN(y1, y2));
xmax = OV_MAX(x0, OV_MAX(x1, x2)) + 1; xmax = OV_MAX(x0, OV_MAX(x1, x2)) + 1;
ymax = OV_MAX(y0, OV_MAX(y1, y2)) + 1; ymax = OV_MAX(y0, OV_MAX(y1, y2)) + 1;
xmin = OV_MAX(xmin, 0); xmin = OV_MAX(xmin, 0);
ymin = OV_MAX(ymin, 0); ymin = OV_MAX(ymin, 0);
xmax = OV_MIN(xmax, imDest->xsize); xmax = OV_MIN(xmax, imDest->xsize);
ymax = OV_MIN(ymax, imDest->ysize); ymax = OV_MIN(ymax, imDest->ysize);
/* setup coefficients */ /* setup coefficients */
a12 = y1 - y2; b12 = x2 - x1; c12 = (x1 * y2) - (x2 * y1); a12 = y1 - y2;
a20 = y2 - y0; b20 = x0 - x2; c20 = (x2 * y0) - (x0 * y2); b12 = x2 - x1;
a01 = y0 - y1; b01 = x1 - x0; c01 = (x0 * y1) - (x1 * y0); c12 = (x1 * y2) - (x2 * y1);
a20 = y2 - y0;
b20 = x0 - x2;
c20 = (x2 * y0) - (x0 * y2);
a01 = y0 - y1;
b01 = x1 - x0;
c01 = (x0 * y1) - (x1 * y0);
/* setup normalizers */ /* setup normalizers */
alpha_norm = 1.0f / ((a12 * x0) + (b12 * y0) + c12); alpha_norm = 1.0f / ((a12 * x0) + (b12 * y0) + c12);
beta_norm = 1.0f / ((a20 * x1) + (b20 * y1) + c20); beta_norm = 1.0f / ((a20 * x1) + (b20 * y1) + c20);
gamma_norm = 1.0f / ((a01 * x2) + (b01 * y2) + c01); gamma_norm = 1.0f / ((a01 * x2) + (b01 * y2) + c01);
/* iterate over the destination rect */ /* iterate over the destination rect */
for (y = ymin; y < ymax; y++) { for (y = ymin; y < ymax; y++) {
UINT8 *out = (UINT8 *)imDest->image[y] + xmin * 4; UINT8* out = (UINT8*)imDest->image[y] + xmin * 4;
for (x = xmin; x < xmax; x++) { for (x = xmin; x < xmax; x++) {
float alpha, beta, gamma; float alpha, beta, gamma;
alpha = alpha_norm * ((a12 * x) + (b12 * y) + c12); alpha = alpha_norm * ((a12 * x) + (b12 * y) + c12);
beta = beta_norm * ((a20 * x) + (b20 * y) + c20); beta = beta_norm * ((a20 * x) + (b20 * y) + c20);
gamma = gamma_norm * ((a01 * x) + (b01 * y) + c01); gamma = gamma_norm * ((a01 * x) + (b01 * y) + c01);
if (alpha >= 0 && beta >= 0 && gamma >= 0 && if (alpha >= 0 && beta >= 0 && gamma >= 0 &&
(inclusive || (alpha * beta * gamma > 0))) { (inclusive || (alpha * beta * gamma > 0))) {
unsigned int r = alpha * r0 + beta * r1 + gamma * r2; unsigned int r = alpha * r0 + beta * r1 + gamma * r2;
unsigned int g = alpha * g0 + beta * g1 + gamma * g2; unsigned int g = alpha * g0 + beta * g1 + gamma * g2;
unsigned int b = alpha * b0 + beta * b1 + gamma * b2; unsigned int b = alpha * b0 + beta * b1 + gamma * b2;
*out = OV_MULDIV255(*out, r, tmp); out++; *out = OV_MULDIV255(*out, r, tmp);
*out = OV_MULDIV255(*out, g, tmp); out++; out++;
*out = OV_MULDIV255(*out, b, tmp); out++; *out = OV_MULDIV255(*out, g, tmp);
out++;
*out = OV_MULDIV255(*out, b, tmp);
out++;
/* keep alpha the same */ /* keep alpha the same */
out++; out++;
} else { } else {
@ -458,42 +464,45 @@ draw_triangle(PyObject *dest, int inclusive,
} }
} }
} }
while (num_touchups > 0) { while (num_touchups > 0) {
float alpha, beta, gamma; float alpha, beta, gamma;
unsigned int r, g, b; unsigned int r, g, b;
UINT8 *out; UINT8* out;
x = touchups[0] + tux; x = touchups[0] + tux;
y = touchups[1] + tuy; y = touchups[1] + tuy;
touchups += 2; touchups += 2;
num_touchups--; num_touchups--;
if (x < 0 || x >= imDest->xsize || y < 0 || y >= imDest->ysize) if (x < 0 || x >= imDest->xsize || y < 0 || y >= imDest->ysize)
continue; continue;
out = (UINT8 *)imDest->image[y] + x * 4; out = (UINT8*)imDest->image[y] + x * 4;
alpha = alpha_norm * ((a12 * x) + (b12 * y) + c12); alpha = alpha_norm * ((a12 * x) + (b12 * y) + c12);
beta = beta_norm * ((a20 * x) + (b20 * y) + c20); beta = beta_norm * ((a20 * x) + (b20 * y) + c20);
gamma = gamma_norm * ((a01 * x) + (b01 * y) + c01); gamma = gamma_norm * ((a01 * x) + (b01 * y) + c01);
r = alpha * r0 + beta * r1 + gamma * r2; r = alpha * r0 + beta * r1 + gamma * r2;
g = alpha * g0 + beta * g1 + gamma * g2; g = alpha * g0 + beta * g1 + gamma * g2;
b = alpha * b0 + beta * b1 + gamma * b2; b = alpha * b0 + beta * b1 + gamma * b2;
*out = OV_MULDIV255(*out, r, tmp); out++; *out = OV_MULDIV255(*out, r, tmp);
*out = OV_MULDIV255(*out, g, tmp); out++; out++;
*out = OV_MULDIV255(*out, b, tmp); out++; *out = OV_MULDIV255(*out, g, tmp);
out++;
*out = OV_MULDIV255(*out, b, tmp);
out++;
} }
return dest; return dest;
} }
/* scales the image to half size /* scales the image to half size
*/ */
inline PyObject * inline PyObject*
resize_half(PyObject *dest, PyObject *src) { resize_half(PyObject* dest, PyObject* src) {
/* libImaging handles */ /* libImaging handles */
Imaging imDest, imSrc; Imaging imDest, imSrc;
/* alpha properties */ /* alpha properties */
@ -501,138 +510,134 @@ resize_half(PyObject *dest, PyObject *src) {
/* iteration variables */ /* iteration variables */
unsigned int x, y; unsigned int x, y;
/* temp color variables */ /* temp color variables */
unsigned int r, g, b, a; unsigned int r, g, b, a;
/* size values for source and destination */ /* size values for source and destination */
int src_width, src_height, dest_width, dest_height; int src_width, src_height, dest_width, dest_height;
imDest = imaging_python_to_c(dest); imDest = imaging_python_to_c(dest);
imSrc = imaging_python_to_c(src); imSrc = imaging_python_to_c(src);
if (!imDest || !imSrc) if (!imDest || !imSrc)
return NULL; return NULL;
/* check the various image modes, make sure they make sense */ /* check the various image modes, make sure they make sense */
if (strcmp(imDest->mode, "RGBA") != 0) { if (strcmp(imDest->mode, "RGBA") != 0) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"given destination image does not have mode \"RGBA\""); "given destination image does not have mode \"RGBA\"");
return NULL; return NULL;
} }
if (strcmp(imSrc->mode, "RGBA") != 0 && strcmp(imSrc->mode, "RGB") != 0) { if (strcmp(imSrc->mode, "RGBA") != 0 && strcmp(imSrc->mode, "RGB") != 0) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"given source image does not have mode \"RGBA\" or \"RGB\""); "given source image does not have mode \"RGBA\" or \"RGB\"");
return NULL; return NULL;
} }
src_width = imSrc->xsize; src_width = imSrc->xsize;
src_height = imSrc->ysize; src_height = imSrc->ysize;
dest_width = imDest->xsize; dest_width = imDest->xsize;
dest_height = imDest->ysize; dest_height = imDest->ysize;
/* make sure destination size is 1/2 src size */ /* make sure destination size is 1/2 src size */
if (src_width / 2 != dest_width || src_height / 2 != dest_height) { if (src_width / 2 != dest_width || src_height / 2 != dest_height) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"destination image size is not one-half source image size"); "destination image size is not one-half source image size");
return NULL; return NULL;
} }
/* set up flags for the src/mask type */ /* set up flags for the src/mask type */
src_has_alpha = (imSrc->pixelsize == 4 ? 1 : 0); src_has_alpha = (imSrc->pixelsize == 4 ? 1 : 0);
dest_has_alpha = (imDest->pixelsize == 4 ? 1 : 0); dest_has_alpha = (imDest->pixelsize == 4 ? 1 : 0);
/* check that there remains anything to resize */ /* check that there remains anything to resize */
if (dest_width <= 0 || dest_height <= 0) { if (dest_width <= 0 || dest_height <= 0) {
/* nothing to do, return */ /* nothing to do, return */
return dest; return dest;
} }
/* set to fully opaque if source has no alpha channel */ /* set to fully opaque if source has no alpha channel */
if(!src_has_alpha) if (!src_has_alpha)
a = 0xFF << 2; a = 0xFF << 2;
for (y = 0; y < dest_height; y++) { for (y = 0; y < dest_height; y++) {
UINT8 *out = (UINT8 *)imDest->image[y]; UINT8* out = (UINT8*)imDest->image[y];
UINT8 *in_row1 = (UINT8 *)imSrc->image[y * 2]; UINT8* in_row1 = (UINT8*)imSrc->image[y * 2];
UINT8 *in_row2 = (UINT8 *)imSrc->image[y * 2 + 1]; UINT8* in_row2 = (UINT8*)imSrc->image[y * 2 + 1];
for (x = 0; x < dest_width; x++) { for (x = 0; x < dest_width; x++) {
// read first column // read first column
r = *in_row1; r = *in_row1;
r += *in_row2; r += *in_row2;
in_row1++; in_row1++;
in_row2++; in_row2++;
g = *in_row1; g = *in_row1;
g += *in_row2; g += *in_row2;
in_row1++; in_row1++;
in_row2++; in_row2++;
b = *in_row1; b = *in_row1;
b += *in_row2; b += *in_row2;
in_row1++; in_row1++;
in_row2++; in_row2++;
if (src_has_alpha) if (src_has_alpha) {
{ a = *in_row1;
a = *in_row1;
a += *in_row2; a += *in_row2;
in_row1++; in_row1++;
in_row2++; in_row2++;
} }
// read second column // read second column
r += *in_row1; r += *in_row1;
r += *in_row2; r += *in_row2;
in_row1++; in_row1++;
in_row2++; in_row2++;
g += *in_row1; g += *in_row1;
g += *in_row2; g += *in_row2;
in_row1++; in_row1++;
in_row2++; in_row2++;
b += *in_row1; b += *in_row1;
b += *in_row2; b += *in_row2;
in_row1++; in_row1++;
in_row2++; in_row2++;
if (src_has_alpha) if (src_has_alpha) {
{ a += *in_row1;
a += *in_row1;
a += *in_row2; a += *in_row2;
in_row1++; in_row1++;
in_row2++; in_row2++;
} }
// write blended color // write blended color
*out = (UINT8)(r >> 2); *out = (UINT8)(r >> 2);
out++; out++;
*out = (UINT8)(g >> 2); *out = (UINT8)(g >> 2);
out++; out++;
*out = (UINT8)(b >> 2); *out = (UINT8)(b >> 2);
out++; out++;
if (dest_has_alpha) if (dest_has_alpha) {
{
*out = (UINT8)(a >> 2); *out = (UINT8)(a >> 2);
out++; out++;
} }
} }
} }
return dest; return dest;
} }
/* wraps resize_half so it can be called directly from python */ /* wraps resize_half so it can be called directly from python */
PyObject * PyObject*
resize_half_wrap(PyObject *self, PyObject *args) resize_half_wrap(PyObject* self, PyObject* args) {
{
/* raw input python variables */ /* raw input python variables */
PyObject *dest, *src; PyObject *dest, *src;
/* return value: dest image on success */ /* return value: dest image on success */
PyObject *ret; PyObject* ret;
if (!PyArg_ParseTuple(args, "OO", &dest, &src)) if (!PyArg_ParseTuple(args, "OO", &dest, &src))
return NULL; return NULL;
ret = resize_half(dest, src); ret = resize_half(dest, src);
if (ret == dest) { if (ret == dest) {
/* Python needs us to own our return value */ /* Python needs us to own our return value */

View File

@ -15,39 +15,39 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "overviewer.h"
#include "mc_id.h"
#include "block_class.h" #include "block_class.h"
#include "mc_id.h"
#include "overviewer.h"
static PyObject *textures = NULL; static PyObject* textures = NULL;
unsigned int max_blockid = 0; unsigned int max_blockid = 0;
unsigned int max_data = 0; unsigned int max_data = 0;
unsigned char *block_properties = NULL; unsigned char* block_properties = NULL;
static PyObject *known_blocks = NULL; static PyObject* known_blocks = NULL;
static PyObject *transparent_blocks = NULL; static PyObject* transparent_blocks = NULL;
static PyObject *solid_blocks = NULL; static PyObject* solid_blocks = NULL;
static PyObject *fluid_blocks = NULL; static PyObject* fluid_blocks = NULL;
static PyObject *nospawn_blocks = NULL; static PyObject* nospawn_blocks = NULL;
static PyObject *nodata_blocks = NULL; static PyObject* nodata_blocks = NULL;
PyObject *init_chunk_render(void) { PyObject* init_chunk_render(void) {
PyObject *tmp = NULL; PyObject* tmp = NULL;
unsigned int i; 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 (textures) { if (textures) {
Py_RETURN_NONE; Py_RETURN_NONE;
} }
textures = PyImport_ImportModule("overviewer_core.textures"); textures = PyImport_ImportModule("overviewer_core.textures");
/* ensure none of these pointers are NULL */ /* ensure none of these pointers are NULL */
if ((!textures)) { if ((!textures)) {
return NULL; return NULL;
} }
tmp = PyObject_GetAttrString(textures, "max_blockid"); tmp = PyObject_GetAttrString(textures, "max_blockid");
if (!tmp) if (!tmp)
return NULL; return NULL;
@ -79,11 +79,11 @@ PyObject *init_chunk_render(void) {
nodata_blocks = PyObject_GetAttrString(textures, "nodata_blocks"); nodata_blocks = PyObject_GetAttrString(textures, "nodata_blocks");
if (!nodata_blocks) if (!nodata_blocks)
return NULL; return NULL;
block_properties = calloc(max_blockid, sizeof(unsigned char)); block_properties = calloc(max_blockid, sizeof(unsigned char));
for (i = 0; i < max_blockid; i++) { for (i = 0; i < max_blockid; i++) {
PyObject *block = PyLong_FromLong(i); PyObject* block = PyLong_FromLong(i);
if (PySequence_Contains(known_blocks, block)) if (PySequence_Contains(known_blocks, block))
block_properties[i] |= 1 << KNOWN; block_properties[i] |= 1 << KNOWN;
if (PySequence_Contains(transparent_blocks, block)) if (PySequence_Contains(transparent_blocks, block))
@ -96,19 +96,19 @@ PyObject *init_chunk_render(void) {
block_properties[i] |= 1 << NOSPAWN; block_properties[i] |= 1 << NOSPAWN;
if (PySequence_Contains(nodata_blocks, block)) if (PySequence_Contains(nodata_blocks, block))
block_properties[i] |= 1 << NODATA; block_properties[i] |= 1 << NODATA;
Py_DECREF(block); Py_DECREF(block);
} }
Py_RETURN_NONE; Py_RETURN_NONE;
} }
/* helper for load_chunk, loads a section into a chunk */ /* helper for load_chunk, loads a section into a chunk */
static inline void load_chunk_section(ChunkData *dest, int i, PyObject *section) { static inline void load_chunk_section(ChunkData* dest, int i, PyObject* section) {
dest->sections[i].blocks = (PyArrayObject*) PyDict_GetItemString(section, "Blocks"); dest->sections[i].blocks = (PyArrayObject*)PyDict_GetItemString(section, "Blocks");
dest->sections[i].data = (PyArrayObject*) PyDict_GetItemString(section, "Data"); dest->sections[i].data = (PyArrayObject*)PyDict_GetItemString(section, "Data");
dest->sections[i].skylight = (PyArrayObject*) PyDict_GetItemString(section, "SkyLight"); dest->sections[i].skylight = (PyArrayObject*)PyDict_GetItemString(section, "SkyLight");
dest->sections[i].blocklight = (PyArrayObject*) PyDict_GetItemString(section, "BlockLight"); dest->sections[i].blocklight = (PyArrayObject*)PyDict_GetItemString(section, "BlockLight");
Py_INCREF(dest->sections[i].blocks); Py_INCREF(dest->sections[i].blocks);
Py_INCREF(dest->sections[i].data); Py_INCREF(dest->sections[i].data);
Py_INCREF(dest->sections[i].skylight); Py_INCREF(dest->sections[i].skylight);
@ -122,25 +122,24 @@ static inline void load_chunk_section(ChunkData *dest, int i, PyObject *section)
* exception and return true. * exception and return true.
*/ */
int load_chunk(RenderState* state, int x, int z, unsigned char required) { int load_chunk(RenderState* state, int x, int z, unsigned char required) {
ChunkData *dest = &(state->chunks[1 + x][1 + z]); ChunkData* dest = &(state->chunks[1 + x][1 + z]);
int i; int i;
PyObject *chunk = NULL; PyObject* chunk = NULL;
PyObject *sections = NULL; PyObject* sections = NULL;
if (dest->loaded) if (dest->loaded)
return 0; return 0;
/* set up reasonable defaults */ /* set up reasonable defaults */
dest->biomes = NULL; dest->biomes = NULL;
for (i = 0; i < SECTIONS_PER_CHUNK; i++) for (i = 0; i < SECTIONS_PER_CHUNK; i++) {
{
dest->sections[i].blocks = NULL; dest->sections[i].blocks = NULL;
dest->sections[i].data = NULL; dest->sections[i].data = NULL;
dest->sections[i].skylight = NULL; dest->sections[i].skylight = NULL;
dest->sections[i].blocklight = NULL; dest->sections[i].blocklight = NULL;
} }
dest->loaded = 1; dest->loaded = 1;
x += state->chunkx; x += state->chunkx;
z += state->chunkz; z += state->chunkz;
@ -166,31 +165,31 @@ int load_chunk(RenderState* state, int x, int z, unsigned char required) {
} }
return 1; return 1;
} }
dest->biomes = (PyArrayObject*) PyDict_GetItemString(chunk, "Biomes"); dest->biomes = (PyArrayObject*)PyDict_GetItemString(chunk, "Biomes");
Py_INCREF(dest->biomes); Py_INCREF(dest->biomes);
for (i = 0; i < PySequence_Fast_GET_SIZE(sections); i++) { for (i = 0; i < PySequence_Fast_GET_SIZE(sections); i++) {
PyObject *ycoord = NULL; PyObject* ycoord = NULL;
int sectiony = 0; int sectiony = 0;
PyObject *section = PySequence_Fast_GET_ITEM(sections, i); PyObject* section = PySequence_Fast_GET_ITEM(sections, i);
ycoord = PyDict_GetItemString(section, "Y"); ycoord = PyDict_GetItemString(section, "Y");
if (!ycoord) if (!ycoord)
continue; continue;
sectiony = PyLong_AsLong(ycoord); sectiony = PyLong_AsLong(ycoord);
if (sectiony >= 0 && sectiony < SECTIONS_PER_CHUNK) if (sectiony >= 0 && sectiony < SECTIONS_PER_CHUNK)
load_chunk_section(dest, sectiony, section); load_chunk_section(dest, sectiony, section);
} }
Py_DECREF(sections); Py_DECREF(sections);
Py_DECREF(chunk); Py_DECREF(chunk);
return 0; return 0;
} }
/* helper to unload all loaded chunks */ /* helper to unload all loaded chunks */
static void static void
unload_all_chunks(RenderState *state) { unload_all_chunks(RenderState* state) {
unsigned int i, j, k; unsigned int i, j, k;
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) { for (j = 0; j < 3; j++) {
@ -209,7 +208,7 @@ unload_all_chunks(RenderState *state) {
} }
unsigned short unsigned short
check_adjacent_blocks(RenderState *state, int x,int y,int z, unsigned short blockid) { check_adjacent_blocks(RenderState* state, int x, int y, int z, unsigned short blockid) {
/* /*
* Generates a pseudo ancillary data for blocks that depend of * Generates a pseudo ancillary data for blocks that depend of
* what are surrounded and don't have ancillary data. This * what are surrounded and don't have ancillary data. This
@ -225,27 +224,27 @@ check_adjacent_blocks(RenderState *state, int x,int y,int z, unsigned short bloc
* Example: if the bit1 is 1 that means that there is a block with * Example: if the bit1 is 1 that means that there is a block with
* blockid in the side of the +x direction. * blockid in the side of the +x direction.
*/ */
unsigned char pdata=0; unsigned char pdata = 0;
if (get_data(state, BLOCKS, x + 1, y, z) == blockid) { if (get_data(state, BLOCKS, x + 1, y, z) == blockid) {
pdata = pdata|(1 << 3); pdata = pdata | (1 << 3);
} }
if (get_data(state, BLOCKS, x, y, z + 1) == blockid) { if (get_data(state, BLOCKS, x, y, z + 1) == blockid) {
pdata = pdata|(1 << 2); pdata = pdata | (1 << 2);
} }
if (get_data(state, BLOCKS, x - 1, y, z) == blockid) { if (get_data(state, BLOCKS, x - 1, y, z) == blockid) {
pdata = pdata|(1 << 1); pdata = pdata | (1 << 1);
} }
if (get_data(state, BLOCKS, x, y, z - 1) == blockid) { if (get_data(state, BLOCKS, x, y, z - 1) == blockid) {
pdata = pdata|(1 << 0); pdata = pdata | (1 << 0);
} }
return pdata; return pdata;
} }
unsigned short unsigned short
generate_pseudo_data(RenderState *state, unsigned short ancilData) { generate_pseudo_data(RenderState* state, unsigned short ancilData) {
/* /*
* Generates a fake ancillary data for blocks that are drawn * Generates a fake ancillary data for blocks that are drawn
* depending on what are surrounded. * depending on what are surrounded.
@ -255,23 +254,23 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
if (state->block == block_grass) { /* grass */ if (state->block == block_grass) { /* grass */
/* return 0x10 if grass is covered in snow */ /* return 0x10 if grass is covered in snow */
if (get_data(state, BLOCKS, x, y+1, z) == 78) if (get_data(state, BLOCKS, x, y + 1, z) == 78)
return 0x10; return 0x10;
return ancilData; return ancilData;
} else if (block_class_is_subset(state->block, (mc_block_t[]){block_flowing_water,block_water}, 2)) { /* water */ } else if (block_class_is_subset(state->block, (mc_block_t[]){block_flowing_water, block_water}, 2)) { /* water */
data = check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f; data = check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f;
/* an aditional bit for top is added to the 4 bits of check_adjacent_blocks */ /* an aditional bit for top is added to the 4 bits of check_adjacent_blocks */
if (get_data(state, BLOCKS, x, y+1, z) != state->block) if (get_data(state, BLOCKS, x, y + 1, z) != state->block)
data |= 0x10; data |= 0x10;
return data; return data;
} else if (block_class_is_subset(state->block, (mc_block_t[]){block_glass,block_ice,block_stained_glass}, 3)) { /* glass and ice and stained glass*/ } else if (block_class_is_subset(state->block, (mc_block_t[]){block_glass, block_ice, block_stained_glass}, 3)) { /* glass and ice and stained glass*/
/* an aditional bit for top is added to the 4 bits of check_adjacent_blocks /* an aditional bit for top is added to the 4 bits of check_adjacent_blocks
* Note that stained glass encodes 16 colors using 4 bits. this pushes us over the 8-bits of an unsigned char, * Note that stained glass encodes 16 colors using 4 bits. this pushes us over the 8-bits of an unsigned char,
* forcing us to use an unsigned short to hold 16 bits of pseudo ancil data * forcing us to use an unsigned short to hold 16 bits of pseudo ancil data
* */ * */
if ((get_data(state, BLOCKS, x, y+1, z) == 20) || (get_data(state, BLOCKS, x, y+1, z) == 95)) { if ((get_data(state, BLOCKS, x, y + 1, z) == 20) || (get_data(state, BLOCKS, x, y + 1, z) == 95)) {
data = 0; data = 0;
} else { } else {
data = 16; data = 16;
} }
data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f) | data; data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f) | data;
@ -279,8 +278,8 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
} else if (block_class_is_subset(state->block, block_class_fence, block_class_fence_len)) { /* fences */ } else if (block_class_is_subset(state->block, block_class_fence, block_class_fence_len)) { /* fences */
/* check for fences AND fence gates */ /* check for fences AND fence gates */
return check_adjacent_blocks(state, x, y, z, state->block) | check_adjacent_blocks(state, x, y, z, block_fence_gate) | return check_adjacent_blocks(state, x, y, z, state->block) | check_adjacent_blocks(state, x, y, z, block_fence_gate) |
check_adjacent_blocks(state, x, y, z, block_fence_gate) | check_adjacent_blocks(state, x, y, z, block_birch_fence_gate) | check_adjacent_blocks(state, x, y, z, block_jungle_fence_gate) | check_adjacent_blocks(state, x, y, z, block_fence_gate) | check_adjacent_blocks(state, x, y, z, block_birch_fence_gate) | check_adjacent_blocks(state, x, y, z, block_jungle_fence_gate) |
check_adjacent_blocks(state, x, y, z, block_dark_oak_fence_gate) | check_adjacent_blocks(state, x, y, z, block_acacia_fence_gate); check_adjacent_blocks(state, x, y, z, block_dark_oak_fence_gate) | check_adjacent_blocks(state, x, y, z, block_acacia_fence_gate);
} else if (state->block == block_redstone_wire) { /* redstone */ } else if (state->block == block_redstone_wire) { /* redstone */
/* three addiotional bit are added, one for on/off state, and /* three addiotional bit are added, one for on/off state, and
@ -288,22 +287,22 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
* (connection with the level y+1) */ * (connection with the level y+1) */
unsigned char above_level_data = 0, same_level_data = 0, below_level_data = 0, possibly_connected = 0, final_data = 0; unsigned char above_level_data = 0, same_level_data = 0, below_level_data = 0, possibly_connected = 0, final_data = 0;
/* check for air in y+1, no air = no connection with upper level */ /* check for air in y+1, no air = no connection with upper level */
if (get_data(state, BLOCKS, x, y+1, z) == 0) { if (get_data(state, BLOCKS, x, y + 1, z) == 0) {
above_level_data = check_adjacent_blocks(state, x, y+1, z, state->block); above_level_data = check_adjacent_blocks(state, x, y + 1, z, state->block);
} /* else above_level_data = 0 */ } /* else above_level_data = 0 */
/* check connection with same level (other redstone and trapped chests */ /* check connection with same level (other redstone and trapped chests */
same_level_data = check_adjacent_blocks(state, x, y, z, 55) | check_adjacent_blocks(state, x, y, z, 146); same_level_data = check_adjacent_blocks(state, x, y, z, 55) | check_adjacent_blocks(state, x, y, z, 146);
/* check the posibility of connection with y-1 level, check for air */ /* check the posibility of connection with y-1 level, check for air */
possibly_connected = check_adjacent_blocks(state, x, y, z, 0); possibly_connected = check_adjacent_blocks(state, x, y, z, 0);
/* check connection with y-1 level */ /* check connection with y-1 level */
below_level_data = check_adjacent_blocks(state, x, y-1, z, state->block); below_level_data = check_adjacent_blocks(state, x, y - 1, z, state->block);
final_data = above_level_data | same_level_data | (below_level_data & possibly_connected); final_data = above_level_data | same_level_data | (below_level_data & possibly_connected);
/* add the three bits */ /* add the three bits */
if (ancilData > 0) { /* powered redstone wire */ if (ancilData > 0) { /* powered redstone wire */
final_data = final_data | 0x40; final_data = final_data | 0x40;
@ -316,12 +315,12 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
} }
return final_data; return final_data;
} else if (block_class_is_subset(state->block, (mc_block_t[]){block_chest,block_trapped_chest}, 2)) { } else if (block_class_is_subset(state->block, (mc_block_t[]){block_chest, block_trapped_chest}, 2)) {
/* Orientation is given by ancilData, pseudo data needed to /* Orientation is given by ancilData, pseudo data needed to
* choose from single or double chest and the correct half of * choose from single or double chest and the correct half of
* the chest. */ * the chest. */
/* Add two bits to ancilData to store single or double chest /* Add two bits to ancilData to store single or double chest
* and which half of the chest it is: bit 0x10 = second half * and which half of the chest it is: bit 0x10 = second half
* bit 0x8 = first half */ * bit 0x8 = first half */
@ -353,7 +352,7 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
} }
return final_data; return final_data;
} else if (block_class_is_subset(state->block, (mc_block_t[]){block_iron_bars,block_glass_pane, block_stained_glass_pane},3)) { } else if (block_class_is_subset(state->block, (mc_block_t[]){block_iron_bars, block_glass_pane, block_stained_glass_pane}, 3)) {
/* iron bars and glass panes: /* iron bars and glass panes:
* they seem to stick to almost everything but air, * they seem to stick to almost everything but air,
* not sure yet! Still a TODO! */ * not sure yet! Still a TODO! */
@ -362,7 +361,7 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
data = (check_adjacent_blocks(state, x, y, z, 0) ^ 0x0f); data = (check_adjacent_blocks(state, x, y, z, 0) ^ 0x0f);
return (data << 4) | (ancilData & 0xf); return (data << 4) | (ancilData & 0xf);
} else if (block_class_is_subset(state->block, (mc_block_t[]){block_portal,block_nether_brick_fence}, 2)) { } else if (block_class_is_subset(state->block, (mc_block_t[]){block_portal, block_nether_brick_fence}, 2)) {
/* portal and nether brick fences */ /* 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);
@ -373,7 +372,7 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
unsigned char data = 0; unsigned char data = 0;
if ((ancilData & 0x8) == 0x8) { if ((ancilData & 0x8) == 0x8) {
/* top door block */ /* top door block */
unsigned char b_data = get_data(state, DATA, x, y-1, z); unsigned char b_data = get_data(state, DATA, x, y - 1, z);
if ((ancilData & 0x1) == 0x1) { if ((ancilData & 0x1) == 0x1) {
/* hinge on the left */ /* hinge on the left */
data = b_data | 0x8 | 0x10; data = b_data | 0x8 | 0x10;
@ -382,14 +381,13 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
} }
} else { } else {
/* bottom door block */ /* bottom door block */
unsigned char t_data = get_data(state, DATA, x, y+1, z); unsigned char t_data = get_data(state, DATA, x, y + 1, z);
if ((t_data & 0x1) == 0x1) { if ((t_data & 0x1) == 0x1) {
/* hinge on the left */ /* hinge on the left */
data = ancilData | 0x10; data = ancilData | 0x10;
} else { } else {
data = ancilData; data = ancilData;
} }
} }
return data; return data;
} else if (state->block == block_cobblestone_wall) { } else if (state->block == block_cobblestone_wall) {
@ -400,7 +398,7 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
return check_adjacent_blocks(state, x, y, z, state->block); return check_adjacent_blocks(state, x, y, z, state->block);
} }
} else if (state->block == block_waterlily) { } else if (state->block == block_waterlily) {
int wx,wz,wy,rotation; int wx, wz, wy, rotation;
long pr; long pr;
/* calculate the global block coordinates of this position */ /* calculate the global block coordinates of this position */
wx = (state->chunkx * 16) + x; wx = (state->chunkx * 16) + x;
@ -430,39 +428,39 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
/* keep track of whether neighbors are stairs, and their data */ /* keep track of whether neighbors are stairs, and their data */
unsigned char stairs_base[8]; unsigned char stairs_base[8];
unsigned char neigh_base[8]; unsigned char neigh_base[8];
unsigned char *stairs = stairs_base; unsigned char* stairs = stairs_base;
unsigned char *neigh = neigh_base; unsigned char* neigh = neigh_base;
/* amount to rotate/roll to get to east, west, south, north */ /* amount to rotate/roll to get to east, west, south, north */
size_t rotations[] = {0,2,3,1}; size_t rotations[] = {0, 2, 3, 1};
/* masks for the filled (ridge) stair quarters: */ /* masks for the filled (ridge) stair quarters: */
/* Example: the ridge for an east-ascending stair are the two east quarters */ /* Example: the ridge for an east-ascending stair are the two east quarters */
/* ascending: east west south north */ /* ascending: east west south north */
unsigned char ridge_mask[] = { 0x30, 0x48, 0x60, 0x18 }; unsigned char ridge_mask[] = {0x30, 0x48, 0x60, 0x18};
/* masks for the open (trench) stair quarters: */ /* masks for the open (trench) stair quarters: */
unsigned char trench_mask[] = { 0x48, 0x30, 0x18, 0x60 }; unsigned char trench_mask[] = {0x48, 0x30, 0x18, 0x60};
/* boat analogy! up the stairs is toward the bow of the boat */ /* boat analogy! up the stairs is toward the bow of the boat */
/* masks for port and starboard, i.e. left and right sides while ascending: */ /* masks for port and starboard, i.e. left and right sides while ascending: */
unsigned char port_mask[] = { 0x18, 0x60, 0x30, 0x48 }; unsigned char port_mask[] = {0x18, 0x60, 0x30, 0x48};
unsigned char starboard_mask[] = { 0x60, 0x18, 0x48, 0x30 }; unsigned char starboard_mask[] = {0x60, 0x18, 0x48, 0x30};
/* we may need to lock some quarters into place depending on neighbors */ /* we may need to lock some quarters into place depending on neighbors */
unsigned char lock_mask = 0; unsigned char lock_mask = 0;
unsigned char repair_rot[] = { 0, 1, 2, 3, 2, 3, 1, 0, 1, 0, 3, 2, 3, 2, 0, 1 }; unsigned char repair_rot[] = {0, 1, 2, 3, 2, 3, 1, 0, 1, 0, 3, 2, 3, 2, 0, 1};
/* need to get northdirection of the render */ /* need to get northdirection of the render */
/* TODO: get this just once? store in state? */ /* TODO: get this just once? store in state? */
PyObject *texrot; PyObject* texrot;
int northdir; int northdir;
texrot = PyObject_GetAttrString(state->textures, "rotation"); texrot = PyObject_GetAttrString(state->textures, "rotation");
northdir = PyLong_AsLong(texrot); northdir = PyLong_AsLong(texrot);
/* fix the rotation value for different northdirections */ /* fix the rotation value for different northdirections */
#define FIX_ROT(x) (((x) & ~0x3) | repair_rot[((x) & 0x3) | (northdir << 2)]) #define FIX_ROT(x) (((x) & ~0x3) | repair_rot[((x)&0x3) | (northdir << 2)])
ancilData = FIX_ROT(ancilData); ancilData = FIX_ROT(ancilData);
/* fill the ancillary bits assuming normal stairs with no corner yet */ /* fill the ancillary bits assuming normal stairs with no corner yet */
@ -470,16 +468,16 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
/* get block & data for neighbors in this order: east, north, west, south */ /* get block & data for neighbors in this order: east, north, west, south */
/* so we can rotate things easily */ /* so we can rotate things easily */
stairs[0] = stairs[4] = block_class_is_subset(get_data(state, BLOCKS, x+1, y, z), block_class_stair, block_class_stair_len); stairs[0] = stairs[4] = block_class_is_subset(get_data(state, BLOCKS, x + 1, y, z), block_class_stair, block_class_stair_len);
stairs[1] = stairs[5] = block_class_is_subset(get_data(state, BLOCKS, x, y, z-1), block_class_stair, block_class_stair_len); stairs[1] = stairs[5] = block_class_is_subset(get_data(state, BLOCKS, x, y, z - 1), block_class_stair, block_class_stair_len);
stairs[2] = stairs[6] = block_class_is_subset(get_data(state, BLOCKS, x-1, y, z), block_class_stair, block_class_stair_len); stairs[2] = stairs[6] = block_class_is_subset(get_data(state, BLOCKS, x - 1, y, z), block_class_stair, block_class_stair_len);
stairs[3] = stairs[7] = block_class_is_subset(get_data(state, BLOCKS, x, y, z+1), block_class_stair, block_class_stair_len); stairs[3] = stairs[7] = block_class_is_subset(get_data(state, BLOCKS, x, y, z + 1), block_class_stair, block_class_stair_len);
neigh[0] = neigh[4] = FIX_ROT(get_data(state, DATA, x+1, y, z)); neigh[0] = neigh[4] = FIX_ROT(get_data(state, DATA, x + 1, y, z));
neigh[1] = neigh[5] = FIX_ROT(get_data(state, DATA, x, y, z-1)); neigh[1] = neigh[5] = FIX_ROT(get_data(state, DATA, x, y, z - 1));
neigh[2] = neigh[6] = FIX_ROT(get_data(state, DATA, x-1, y, z)); neigh[2] = neigh[6] = FIX_ROT(get_data(state, DATA, x - 1, y, z));
neigh[3] = neigh[7] = FIX_ROT(get_data(state, DATA, x, y, z+1)); neigh[3] = neigh[7] = FIX_ROT(get_data(state, DATA, x, y, z + 1));
#undef FIX_ROT #undef FIX_ROT
/* Rotate the neighbors so we only have to worry about one orientation /* Rotate the neighbors so we only have to worry about one orientation
* No matter which way the boat is facing, the the neighbors will be: * No matter which way the boat is facing, the the neighbors will be:
@ -523,8 +521,8 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
/* use bottom block data format plus one bit for top /* use bottom block data format plus one bit for top
* block (0x8) * block (0x8)
*/ */
if( get_data(state, BLOCKS, x, y-1, z) == block_double_plant ) { if (get_data(state, BLOCKS, x, y - 1, z) == block_double_plant) {
data = get_data(state, DATA, x, y-1, z) | 0x8; data = get_data(state, DATA, x, y - 1, z) | 0x8;
} else { } else {
data = ancilData; data = ancilData;
} }
@ -535,34 +533,33 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
return 0; return 0;
} }
/* TODO triple check this to make sure reference counting is correct */ /* TODO triple check this to make sure reference counting is correct */
PyObject* PyObject*
chunk_render(PyObject *self, PyObject *args) { chunk_render(PyObject* self, PyObject* args) {
RenderState state; RenderState state;
PyObject *modeobj; PyObject* modeobj;
PyObject *blockmap; PyObject* blockmap;
int xoff, yoff; int xoff, yoff;
PyObject *imgsize, *imgsize0_py, *imgsize1_py; PyObject *imgsize, *imgsize0_py, *imgsize1_py;
int imgsize0, imgsize1; int imgsize0, imgsize1;
PyArrayObject *blocks_py;
PyArrayObject *left_blocks_py;
PyArrayObject *right_blocks_py;
PyArrayObject *up_left_blocks_py;
PyArrayObject *up_right_blocks_py;
RenderMode *rendermode; PyArrayObject* blocks_py;
PyArrayObject* left_blocks_py;
PyArrayObject* right_blocks_py;
PyArrayObject* up_left_blocks_py;
PyArrayObject* up_right_blocks_py;
RenderMode* rendermode;
int i, j; int i, j;
PyObject *t = NULL; PyObject* t = NULL;
if (!PyArg_ParseTuple(args, "OOiiiOiiOO", &state.world, &state.regionset, &state.chunkx, &state.chunky, &state.chunkz, &state.img, &xoff, &yoff, &modeobj, &state.textures)) if (!PyArg_ParseTuple(args, "OOiiiOiiOO", &state.world, &state.regionset, &state.chunkx, &state.chunky, &state.chunkz, &state.img, &xoff, &yoff, &modeobj, &state.textures))
return NULL; return NULL;
/* set up the render mode */ /* set up the render mode */
state.rendermode = rendermode = render_mode_create(modeobj, &state); state.rendermode = rendermode = render_mode_create(modeobj, &state);
if (rendermode == NULL) { if (rendermode == NULL) {
@ -581,7 +578,7 @@ chunk_render(PyObject *self, PyObject *args) {
PyErr_SetString(PyExc_RuntimeError, "you must call Textures.generate()"); PyErr_SetString(PyExc_RuntimeError, "you must call Textures.generate()");
return NULL; return NULL;
} }
/* get the image size */ /* get the image size */
imgsize = PyObject_GetAttrString(state.img, "size"); imgsize = PyObject_GetAttrString(state.img, "size");
@ -593,14 +590,14 @@ chunk_render(PyObject *self, PyObject *args) {
imgsize1 = PyLong_AsLong(imgsize1_py); imgsize1 = PyLong_AsLong(imgsize1_py);
Py_DECREF(imgsize0_py); Py_DECREF(imgsize0_py);
Py_DECREF(imgsize1_py); Py_DECREF(imgsize1_py);
/* set all block data to unloaded */ /* set all block data to unloaded */
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) { for (j = 0; j < 3; j++) {
state.chunks[i][j].loaded = 0; state.chunks[i][j].loaded = 0;
} }
} }
/* get the block data for the center column, erroring out if needed */ /* get the block data for the center column, erroring out if needed */
if (load_chunk(&state, 0, 0, 1)) { if (load_chunk(&state, 0, 0, 1)) {
render_mode_destroy(rendermode); render_mode_destroy(rendermode);
@ -614,7 +611,7 @@ chunk_render(PyObject *self, PyObject *args) {
unload_all_chunks(&state); unload_all_chunks(&state);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
/* set blocks_py, state.blocks, and state.blockdatas as convenience */ /* set blocks_py, state.blocks, and state.blockdatas as convenience */
blocks_py = state.blocks = state.chunks[1][1].sections[state.chunky].blocks; blocks_py = state.blocks = state.chunks[1][1].sections[state.chunky].blocks;
state.blockdatas = state.chunks[1][1].sections[state.chunky].data; state.blockdatas = state.chunks[1][1].sections[state.chunky].data;
@ -622,25 +619,25 @@ chunk_render(PyObject *self, PyObject *args) {
/* set up the random number generator again for each chunk /* set up the random number generator again for each chunk
so tallgrass is in the same place, no matter what mode is used */ so tallgrass is in the same place, no matter what mode is used */
srand(1); srand(1);
for (state.x = 15; state.x > -1; state.x--) { for (state.x = 15; state.x > -1; state.x--) {
for (state.z = 0; state.z < 16; state.z++) { for (state.z = 0; state.z < 16; state.z++) {
/* set up the render coordinates */ /* set up the render coordinates */
state.imgx = xoff + state.x*12 + state.z*12; state.imgx = xoff + state.x * 12 + state.z * 12;
/* 16*12 -- offset for y direction, 15*6 -- offset for x */ /* 16*12 -- offset for y direction, 15*6 -- offset for x */
state.imgy = yoff - state.x*6 + state.z*6 + 16*12 + 15*6; state.imgy = yoff - state.x * 6 + state.z * 6 + 16 * 12 + 15 * 6;
for (state.y = 0; state.y < 16; state.y++) { for (state.y = 0; state.y < 16; state.y++) {
unsigned short ancilData; unsigned short ancilData;
state.imgy -= 12; state.imgy -= 12;
/* get blockid */ /* get blockid */
state.block = getArrayShort3D(blocks_py, state.x, state.y, state.z); state.block = getArrayShort3D(blocks_py, state.x, state.y, state.z);
if (state.block == block_air || render_mode_hidden(rendermode, state.x, state.y, state.z)) { if (state.block == block_air || render_mode_hidden(rendermode, state.x, state.y, state.z)) {
continue; continue;
} }
/* make sure we're rendering inside the image boundaries */ /* make sure we're rendering inside the image boundaries */
if ((state.imgx >= imgsize0 + 24) || (state.imgx <= -24)) { if ((state.imgx >= imgsize0 + 24) || (state.imgx <= -24)) {
continue; continue;
@ -648,14 +645,14 @@ chunk_render(PyObject *self, PyObject *args) {
if ((state.imgy >= imgsize1 + 24) || (state.imgy <= -24)) { if ((state.imgy >= imgsize1 + 24) || (state.imgy <= -24)) {
continue; continue;
} }
/* check for occlusion */ /* 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 */
if (block_has_property(state.block, NODATA)) { if (block_has_property(state.block, NODATA)) {
/* block shouldn't have data associated with it, set it to 0 */ /* block shouldn't have data associated with it, set it to 0 */
ancilData = 0; ancilData = 0;
@ -676,20 +673,19 @@ chunk_render(PyObject *self, PyObject *args) {
state.block_pdata = 0; state.block_pdata = 0;
} }
} }
/* make sure our block info is in-bounds */ /* make sure our block info is in-bounds */
if (state.block >= max_blockid || ancilData >= max_data) if (state.block >= max_blockid || ancilData >= max_data)
continue; continue;
/* get the texture */ /* get the texture */
t = PyList_GET_ITEM(blockmap, max_data * state.block + ancilData); t = PyList_GET_ITEM(blockmap, max_data * state.block + ancilData);
/* if we don't get a texture, try it again with 0 data */ /* if we don't get a texture, try it again with 0 data */
if ((t == NULL || t == Py_None) && ancilData != 0) if ((t == NULL || t == Py_None) && ancilData != 0)
t = PyList_GET_ITEM(blockmap, max_data * state.block); t = PyList_GET_ITEM(blockmap, max_data * state.block);
/* 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) {
{
PyObject *src, *mask, *mask_light; PyObject *src, *mask, *mask_light;
int do_rand = (state.block == block_tallgrass /*|| state.block == block_red_flower || state.block == block_double_plant*/); int do_rand = (state.block == block_tallgrass /*|| state.block == block_red_flower || state.block == block_double_plant*/);
int randx = 0, randy = 0; int randx = 0, randy = 0;
@ -707,9 +703,9 @@ chunk_render(PyObject *self, PyObject *args) {
state.imgx += randx; state.imgx += randx;
state.imgy += randy; state.imgy += randy;
} }
render_mode_draw(rendermode, src, mask, mask_light); render_mode_draw(rendermode, src, mask, mask_light);
if (do_rand) { if (do_rand) {
/* undo the random offsets */ /* undo the random offsets */
state.imgx -= randx; state.imgx -= randx;
@ -722,7 +718,7 @@ chunk_render(PyObject *self, PyObject *args) {
/* free up the rendermode info */ /* free up the rendermode info */
render_mode_destroy(rendermode); render_mode_destroy(rendermode);
Py_DECREF(blockmap); Py_DECREF(blockmap);
unload_all_chunks(&state); unload_all_chunks(&state);

View File

@ -17,7 +17,7 @@
#include "overviewer.h" #include "overviewer.h"
PyObject *get_extension_version(PyObject *self, PyObject *args) { PyObject* get_extension_version(PyObject* self, PyObject* args) {
return Py_BuildValue("i", OVERVIEWER_EXTENSION_VERSION); return Py_BuildValue("i", OVERVIEWER_EXTENSION_VERSION);
} }
@ -25,31 +25,28 @@ PyObject *get_extension_version(PyObject *self, PyObject *args) {
static PyMethodDef COverviewerMethods[] = { static PyMethodDef COverviewerMethods[] = {
{"alpha_over", alpha_over_wrap, METH_VARARGS, {"alpha_over", alpha_over_wrap, METH_VARARGS,
"alpha over composite function"}, "alpha over composite function"},
{"resize_half", resize_half_wrap, METH_VARARGS, {"resize_half", resize_half_wrap, METH_VARARGS,
"downscale image to half size"}, "downscale image to half size"},
{"render_loop", chunk_render, METH_VARARGS, {"render_loop", chunk_render, METH_VARARGS,
"Renders stuffs"}, "Renders stuffs"},
{"extension_version", get_extension_version, METH_VARARGS, {"extension_version", get_extension_version, METH_VARARGS,
"Returns the extension version"}, "Returns the extension version"},
{NULL, NULL, 0, NULL} /* Sentinel */ {NULL, NULL, 0, NULL} /* Sentinel */
}; };
static PyModuleDef COverviewerModule = { static PyModuleDef COverviewerModule = {
PyModuleDef_HEAD_INIT, PyModuleDef_HEAD_INIT,
"c_overviewer", "c_overviewer",
"", // TODO: Add documentation here. "", // TODO: Add documentation here.
-1, -1,
COverviewerMethods COverviewerMethods};
};
PyMODINIT_FUNC PyMODINIT_FUNC
PyInit_c_overviewer(void) PyInit_c_overviewer(void) {
{
PyObject *mod, *numpy; PyObject *mod, *numpy;
mod = PyModule_Create(&COverviewerModule); mod = PyModule_Create(&COverviewerModule);

View File

@ -3,8 +3,7 @@
#include <stdint.h> #include <stdint.h>
enum mc_block_id enum mc_block_id {
{
block_air = 0, block_air = 0,
block_stone = 1, block_stone = 1,
block_grass = 2, block_grass = 2,
@ -261,9 +260,9 @@ enum mc_block_id
block_prismarine_stairs = 11337, block_prismarine_stairs = 11337,
block_dark_prismarine_stairs = 11338, block_dark_prismarine_stairs = 11338,
block_prismarine_brick_stairs = 11339, block_prismarine_brick_stairs = 11339,
block_prismarine_slab = 11340, block_prismarine_slab = 11340,
block_dark_prismarine_slab = 11341, block_dark_prismarine_slab = 11341,
block_prismarine_brick_slab = 11342, block_prismarine_brick_slab = 11342,
block_andesite_slab = 11343, block_andesite_slab = 11343,
block_diorite_slab = 11344, block_diorite_slab = 11344,
block_granite_slab = 11345, block_granite_slab = 11345,
@ -284,9 +283,7 @@ enum mc_block_id
typedef uint16_t mc_block_t; typedef uint16_t mc_block_t;
enum mc_item_id {
enum mc_item_id
{
item_iron_shovel = 256, item_iron_shovel = 256,
item_iron_pickaxe = 257, item_iron_pickaxe = 257,
item_iron_axe = 258, item_iron_axe = 258,

View File

@ -24,55 +24,51 @@
#ifndef __OVERVIEWER_H_INCLUDED__ #ifndef __OVERVIEWER_H_INCLUDED__
#define __OVERVIEWER_H_INCLUDED__ #define __OVERVIEWER_H_INCLUDED__
#define WINVER 0x0601 #define WINVER 0x0601
#define _WIN32_WINNT 0x0601 #define _WIN32_WINNT 0x0601
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
// 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 65 #define OVERVIEWER_EXTENSION_VERSION 65
/* Python PIL, and numpy headers */ /* Python PIL, and numpy headers */
#include <Imaging.h>
#include <Python.h> #include <Python.h>
#include <numpy/arrayobject.h> #include <numpy/arrayobject.h>
#include <Imaging.h>
/* Fix Pillow on mingw-w64 which includes windows.h in Imaging.h */ /* Fix Pillow on mingw-w64 which includes windows.h in Imaging.h */
#undef TRANSPARENT #undef TRANSPARENT
/* Utility macros */ /* Utility macros */
#include "utils.h" #include "utils.h"
/* macro for getting a value out of various numpy arrays the 3D arrays have /* macro for getting a value out of various numpy arrays the 3D arrays have
interesting, swizzled coordinates because minecraft (anvil) stores blocks interesting, swizzled coordinates because minecraft (anvil) stores blocks
in y/z/x order for 3D, z/x order for 2D */ 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 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 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)))) #define getArrayByte2D(array, x, y) (*(unsigned char*)(PyArray_GETPTR2((array), (y), (x))))
/* in composite.c */ /* in composite.c */
Imaging imaging_python_to_c(PyObject *obj); Imaging imaging_python_to_c(PyObject* obj);
PyObject *alpha_over(PyObject *dest, PyObject *src, PyObject *mask, PyObject* alpha_over(PyObject* dest, PyObject* src, PyObject* mask,
int dx, int dy, int xsize, int ysize); int dx, int dy, int xsize, int ysize);
PyObject *alpha_over_full(PyObject *dest, PyObject *src, PyObject *mask, float overall_alpha, PyObject* alpha_over_full(PyObject* dest, PyObject* src, PyObject* mask, float overall_alpha,
int dx, int dy, int xsize, int ysize); int dx, int dy, int xsize, int ysize);
PyObject *alpha_over_wrap(PyObject *self, PyObject *args); PyObject* alpha_over_wrap(PyObject* self, PyObject* args);
PyObject *tint_with_mask(PyObject *dest, unsigned char sr, unsigned char sg, PyObject* tint_with_mask(PyObject* dest, unsigned char sr, unsigned char sg,
unsigned char sb, unsigned char sa, unsigned char sb, unsigned char sa,
PyObject *mask, int dx, int dy, int xsize, int ysize); PyObject* mask, int dx, int dy, int xsize, int ysize);
PyObject *draw_triangle(PyObject *dest, int inclusive, PyObject* draw_triangle(PyObject* dest, int inclusive,
int x0, int y0, int x0, int y0,
unsigned char r0, unsigned char g0, unsigned char b0, unsigned char r0, unsigned char g0, unsigned char b0,
int x1, int y1, int x1, int y1,
unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r1, unsigned char g1, unsigned char b1,
int x2, int y2, int x2, int y2,
unsigned char r2, unsigned char g2, unsigned char b2, unsigned char r2, unsigned char g2, unsigned char b2,
int tux, int tuy, int *touchups, unsigned int num_touchups); int tux, int tuy, int* touchups, unsigned int num_touchups);
PyObject *resize_half(PyObject *dest, PyObject *src); PyObject* resize_half(PyObject* dest, PyObject* src);
PyObject *resize_half_wrap(PyObject *self, PyObject *args); PyObject* resize_half_wrap(PyObject* self, PyObject* args);
/* forward declaration of RenderMode object */ /* forward declaration of RenderMode object */
typedef struct _RenderMode RenderMode; typedef struct _RenderMode RenderMode;
@ -83,7 +79,7 @@ typedef struct {
/* whether this chunk is loaded: use load_chunk to load */ /* whether this chunk is loaded: use load_chunk to load */
int loaded; int loaded;
/* chunk biome array */ /* chunk biome array */
PyArrayObject *biomes; PyArrayObject* biomes;
/* all the sections in a given chunk */ /* all the sections in a given chunk */
struct { struct {
/* all there is to know about each section */ /* all there is to know about each section */
@ -92,20 +88,20 @@ typedef struct {
} ChunkData; } ChunkData;
typedef struct { typedef struct {
/* the regionset object, and chunk coords */ /* the regionset object, and chunk coords */
PyObject *world; PyObject* world;
PyObject *regionset; PyObject* regionset;
int chunkx, chunky, chunkz; int chunkx, chunky, chunkz;
/* the tile image and destination */ /* the tile image and destination */
PyObject *img; PyObject* img;
int imgx, imgy; int imgx, imgy;
/* the current render mode in use */ /* the current render mode in use */
RenderMode *rendermode; RenderMode* rendermode;
/* the Texture object */ /* the Texture object */
PyObject *textures; PyObject* textures;
/* the block position and type, and the block array */ /* the block position and type, and the block array */
int x, y, z; int x, y, z;
unsigned short block; unsigned short block;
@ -113,18 +109,17 @@ typedef struct {
unsigned short block_pdata; unsigned short block_pdata;
/* useful information about this, and neighboring, chunks */ /* useful information about this, and neighboring, chunks */
PyArrayObject *blockdatas; PyArrayObject* blockdatas;
PyArrayObject *blocks; PyArrayObject* blocks;
/* 3x3 array of this and neighboring chunk columns */ /* 3x3 array of this and neighboring chunk columns */
ChunkData chunks[3][3]; ChunkData chunks[3][3];
} RenderState; } RenderState;
PyObject *init_chunk_render(void); PyObject* init_chunk_render(void);
/* returns true on error, x,z relative */ /* returns true on error, x,z relative */
int load_chunk(RenderState* state, int x, int z, unsigned char required); int load_chunk(RenderState* state, int x, int z, unsigned char required);
PyObject *chunk_render(PyObject *self, PyObject *args); PyObject* chunk_render(PyObject* self, PyObject* args);
typedef enum typedef enum {
{
KNOWN, KNOWN,
TRANSPARENT, TRANSPARENT,
SOLID, SOLID,
@ -136,7 +131,7 @@ typedef enum
in block_has_property */ in block_has_property */
extern unsigned int max_blockid; extern unsigned int max_blockid;
extern unsigned int max_data; extern unsigned int max_data;
extern unsigned char *block_properties; extern unsigned char* block_properties;
static inline int static inline int
block_has_property(unsigned short b, BlockProperty prop) { block_has_property(unsigned short b, BlockProperty prop) {
if (b >= max_blockid || !(block_properties[b] & (1 << KNOWN))) { if (b >= max_blockid || !(block_properties[b] & (1 << KNOWN))) {
@ -145,29 +140,27 @@ block_has_property(unsigned short b, BlockProperty prop) {
return 1; return 1;
return 0; return 0;
} }
return block_properties[b] & (1 << prop); return block_properties[b] & (1 << prop);
} }
#define is_transparent(b) block_has_property((b), TRANSPARENT) #define is_transparent(b) block_has_property((b), TRANSPARENT)
#define is_known_transparent(b) block_has_property((b), TRANSPARENT) && block_has_property((b), KNOWN) #define is_known_transparent(b) block_has_property((b), TRANSPARENT) && block_has_property((b), KNOWN)
/* helper for indexing section data possibly across section boundaries */ /* helper for indexing section data possibly across section boundaries */
typedef enum typedef enum {
{
BLOCKS, BLOCKS,
DATA, DATA,
BLOCKLIGHT, BLOCKLIGHT,
SKYLIGHT, SKYLIGHT,
BIOMES, BIOMES,
} DataType; } DataType;
static inline unsigned int get_data(RenderState *state, DataType type, int x, int y, int z) static inline unsigned int get_data(RenderState* state, DataType type, int x, int y, int z) {
{
int chunkx = 1, chunky = state->chunky, chunkz = 1; int chunkx = 1, chunky = state->chunky, chunkz = 1;
PyArrayObject *data_array = NULL; PyArrayObject* data_array = NULL;
unsigned int def = 0; unsigned int def = 0;
if (type == SKYLIGHT) if (type == SKYLIGHT)
def = 15; def = 15;
if (x >= 16) { if (x >= 16) {
x -= 16; x -= 16;
chunkx++; chunkx++;
@ -193,15 +186,13 @@ static inline unsigned int get_data(RenderState *state, DataType type, int x, in
} }
if (chunky < 0 || chunky >= SECTIONS_PER_CHUNK) if (chunky < 0 || chunky >= SECTIONS_PER_CHUNK)
return def; return def;
if (!(state->chunks[chunkx][chunkz].loaded)) if (!(state->chunks[chunkx][chunkz].loaded)) {
{
if (load_chunk(state, chunkx - 1, chunkz - 1, 0)) if (load_chunk(state, chunkx - 1, chunkz - 1, 0))
return def; return def;
} }
switch (type) switch (type) {
{
case BLOCKS: case BLOCKS:
data_array = state->chunks[chunkx][chunkz].sections[chunky].blocks; data_array = state->chunks[chunkx][chunkz].sections[chunky].blocks;
break; break;
@ -217,10 +208,10 @@ static inline unsigned int get_data(RenderState *state, DataType type, int x, in
case BIOMES: case BIOMES:
data_array = state->chunks[chunkx][chunkz].biomes; data_array = state->chunks[chunkx][chunkz].biomes;
}; };
if (data_array == NULL) if (data_array == NULL)
return def; return def;
if (type == BLOCKS) if (type == BLOCKS)
return getArrayShort3D(data_array, x, y, z); return getArrayShort3D(data_array, x, y, z);
if (type == BIOMES) if (type == BIOMES)

View File

@ -15,9 +15,9 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "../overviewer.h"
#include "../mc_id.h"
#include "../block_class.h" #include "../block_class.h"
#include "../mc_id.h"
#include "../overviewer.h"
#include "biomes.h" #include "biomes.h"
typedef struct { typedef struct {
@ -25,32 +25,31 @@ typedef struct {
/* grasscolor and foliagecolor lookup tables */ /* grasscolor and foliagecolor lookup tables */
PyObject *grasscolor, *foliagecolor, *watercolor; PyObject *grasscolor, *foliagecolor, *watercolor;
/* biome-compatible grass/leaf textures */ /* biome-compatible grass/leaf textures */
PyObject *grass_texture; PyObject* grass_texture;
} PrimitiveBase; } PrimitiveBase;
static int static int
base_start(void *data, RenderState *state, PyObject *support) { base_start(void* data, RenderState* state, PyObject* support) {
PrimitiveBase *self = (PrimitiveBase *)data; PrimitiveBase* self = (PrimitiveBase*)data;
if (!render_mode_parse_option(support, "biomes", "i", &(self->use_biomes))) if (!render_mode_parse_option(support, "biomes", "i", &(self->use_biomes)))
return 1; return 1;
/* biome-compliant grass mask (includes sides!) */ /* biome-compliant grass mask (includes sides!) */
self->grass_texture = PyObject_GetAttrString(state->textures, "biome_grass_texture"); self->grass_texture = PyObject_GetAttrString(state->textures, "biome_grass_texture");
/* color lookup tables */ /* color lookup tables */
self->foliagecolor = PyObject_CallMethod(state->textures, "load_foliage_color", ""); self->foliagecolor = PyObject_CallMethod(state->textures, "load_foliage_color", "");
self->grasscolor = PyObject_CallMethod(state->textures, "load_grass_color", ""); self->grasscolor = PyObject_CallMethod(state->textures, "load_grass_color", "");
self->watercolor = PyObject_CallMethod(state->textures, "load_water_color", ""); self->watercolor = PyObject_CallMethod(state->textures, "load_water_color", "");
return 0; return 0;
} }
static void static void
base_finish(void *data, RenderState *state) { base_finish(void* data, RenderState* state) {
PrimitiveBase *self = (PrimitiveBase *)data; PrimitiveBase* self = (PrimitiveBase*)data;
Py_DECREF(self->foliagecolor); Py_DECREF(self->foliagecolor);
Py_DECREF(self->grasscolor); Py_DECREF(self->grasscolor);
Py_DECREF(self->watercolor); Py_DECREF(self->watercolor);
@ -58,14 +57,14 @@ base_finish(void *data, RenderState *state) {
} }
static int static int
base_occluded(void *data, RenderState *state, int x, int y, int z) { base_occluded(void* data, RenderState* state, int x, int y, int z) {
if ( (x != 0) && (y != 15) && (z != 15) && if ((x != 0) && (y != 15) && (z != 15) &&
!render_mode_hidden(state->rendermode, x-1, y, z) && !render_mode_hidden(state->rendermode, x - 1, y, z) &&
!render_mode_hidden(state->rendermode, x, y, z+1) && !render_mode_hidden(state->rendermode, x, y, z + 1) &&
!render_mode_hidden(state->rendermode, x, y+1, z) && !render_mode_hidden(state->rendermode, x, y + 1, z) &&
!is_transparent(getArrayShort3D(state->blocks, x-1, y, z)) && !is_transparent(getArrayShort3D(state->blocks, x - 1, y, z)) &&
!is_transparent(getArrayShort3D(state->blocks, x, y, z+1)) && !is_transparent(getArrayShort3D(state->blocks, x, y, z + 1)) &&
!is_transparent(getArrayShort3D(state->blocks, x, y+1, z))) { !is_transparent(getArrayShort3D(state->blocks, x, y + 1, z))) {
return 1; return 1;
} }
@ -73,16 +72,16 @@ base_occluded(void *data, RenderState *state, int x, int y, int z) {
} }
static void static void
base_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { base_draw(void* data, RenderState* state, PyObject* src, PyObject* mask, PyObject* mask_light) {
PrimitiveBase *self = (PrimitiveBase *)data; PrimitiveBase* self = (PrimitiveBase*)data;
/* in order to detect top parts of doublePlant grass & ferns */ /* in order to detect top parts of doublePlant grass & ferns */
unsigned short below_block = get_data(state, BLOCKS, state->x, state->y-1, state->z); unsigned short below_block = get_data(state, BLOCKS, state->x, state->y - 1, state->z);
unsigned char below_data = get_data(state, DATA, state->x, state->y-1, state->z); unsigned char below_data = get_data(state, DATA, state->x, state->y - 1, state->z);
/* draw the block! */ /* draw the block! */
alpha_over(state->img, src, mask, state->imgx, state->imgy, 0, 0); alpha_over(state->img, src, mask, state->imgx, state->imgy, 0, 0);
/* check for biome-compatible blocks /* check for biome-compatible blocks
* *
* NOTES for maintainers: * NOTES for maintainers:
@ -95,16 +94,9 @@ base_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObjec
* biome-compliant ones! The tinting is now all done here. * biome-compliant ones! The tinting is now all done here.
*/ */
if (/* grass, but not snowgrass */ if (/* grass, but not snowgrass */
(state->block == block_grass && get_data(state, BLOCKS, state->x, state->y+1, state->z) != 78) || (state->block == block_grass && get_data(state, BLOCKS, state->x, state->y + 1, state->z) != 78) ||
block_class_is_subset(state->block, (mc_block_t[]){ block_class_is_subset(state->block, (mc_block_t[]){block_vine, block_waterlily, block_flowing_water, block_water, block_leaves, block_leaves2},
block_vine, 6) ||
block_waterlily,
block_flowing_water,
block_water,
block_leaves,
block_leaves2
},
6) ||
/* tallgrass, but not dead shrubs */ /* tallgrass, but not dead shrubs */
(state->block == block_tallgrass && state->block_data != 0) || (state->block == block_tallgrass && state->block_data != 0) ||
/* pumpkin/melon stem, not fully grown. Fully grown stems /* pumpkin/melon stem, not fully grown. Fully grown stems
@ -113,46 +105,30 @@ base_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObjec
/* doublePlant grass & ferns */ /* doublePlant grass & ferns */
(state->block == block_double_plant && (state->block_data == 2 || state->block_data == 3)) || (state->block == block_double_plant && (state->block_data == 2 || state->block_data == 3)) ||
/* doublePlant grass & ferns tops */ /* doublePlant grass & ferns tops */
(state->block == block_double_plant && below_block == block_double_plant && (below_data == 2 || below_data == 3)) ) (state->block == block_double_plant && below_block == block_double_plant && (below_data == 2 || below_data == 3))) {
{
/* do the biome stuff! */ /* do the biome stuff! */
PyObject *facemask = mask; PyObject* facemask = mask;
unsigned char r = 255, g = 255, b = 255; unsigned char r = 255, g = 255, b = 255;
PyObject *color_table = NULL; PyObject* color_table = NULL;
unsigned char flip_xy = 0; unsigned char flip_xy = 0;
if (state->block == block_grass) { if (state->block == block_grass) {
/* grass needs a special facemask */ /* grass needs a special facemask */
facemask = self->grass_texture; facemask = self->grass_texture;
} }
if(block_class_is_subset(state->block, (mc_block_t[]){ if (block_class_is_subset(state->block, (mc_block_t[]){block_grass, block_tallgrass, block_pumpkin_stem, block_melon_stem, block_vine, block_waterlily, block_double_plant}, 7)) {
block_grass,
block_tallgrass,
block_pumpkin_stem,
block_melon_stem,
block_vine,
block_waterlily,
block_double_plant
},7)) {
color_table = self->grasscolor; color_table = self->grasscolor;
} } else if (block_class_is_subset(state->block, (mc_block_t[]){block_flowing_water, block_water}, 2)) {
else if(block_class_is_subset(state->block, (mc_block_t[]){
block_flowing_water,block_water
},2)) {
color_table = self->watercolor; color_table = self->watercolor;
} } else if (block_class_is_subset(state->block, (mc_block_t[]){block_leaves, block_leaves2}, 2)) {
else if(block_class_is_subset(state->block, (mc_block_t[]){
block_leaves,block_leaves2
},2)) {
color_table = self->foliagecolor; color_table = self->foliagecolor;
if (state->block_data == 2) if (state->block_data == 2) {
{
/* birch! /* birch!
birch foliage color is flipped XY-ways */ birch foliage color is flipped XY-ways */
flip_xy = 1; flip_xy = 1;
} }
} }
if (color_table) { if (color_table) {
unsigned char biome; unsigned char biome;
int dx, dz; int dx, dz;
@ -160,8 +136,8 @@ base_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObjec
float temp = 0.0, rain = 0.0; float temp = 0.0, rain = 0.0;
unsigned int multr = 0, multg = 0, multb = 0; unsigned int multr = 0, multg = 0, multb = 0;
int tmp; int tmp;
PyObject *color = NULL; PyObject* color = NULL;
if (self->use_biomes) { if (self->use_biomes) {
/* average over all neighbors */ /* average over all neighbors */
for (dx = -1; dx <= 1; dx++) { for (dx = -1; dx <= 1; dx++) {
@ -173,7 +149,7 @@ base_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObjec
*/ */
biome = DEFAULT_BIOME; /* forest -- reasonable default */ biome = DEFAULT_BIOME; /* forest -- reasonable default */
} }
temp += biome_table[biome].temperature; temp += biome_table[biome].temperature;
rain += biome_table[biome].rainfall; rain += biome_table[biome].rainfall;
multr += biome_table[biome].r; multr += biome_table[biome].r;
@ -181,7 +157,7 @@ base_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObjec
multb += biome_table[biome].b; multb += biome_table[biome].b;
} }
} }
temp /= 9.0; temp /= 9.0;
rain /= 9.0; rain /= 9.0;
multr /= 9; multr /= 9;
@ -195,15 +171,15 @@ base_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObjec
multg = biome_table[DEFAULT_BIOME].g; multg = biome_table[DEFAULT_BIOME].g;
multb = biome_table[DEFAULT_BIOME].b; multb = biome_table[DEFAULT_BIOME].b;
} }
/* second coordinate is actually scaled to fit inside the triangle /* second coordinate is actually scaled to fit inside the triangle
so store it in rain */ so store it in rain */
rain *= temp; rain *= temp;
/* make sure they're sane */ /* make sure they're sane */
temp = OV_CLAMP(temp, 0.0, 1.0); temp = OV_CLAMP(temp, 0.0, 1.0);
rain = OV_CLAMP(rain, 0.0, 1.0); rain = OV_CLAMP(rain, 0.0, 1.0);
/* convert to x/y coordinates in color table */ /* convert to x/y coordinates in color table */
tablex = 255 - (255 * temp); tablex = 255 - (255 * temp);
tabley = 255 - (255 * rain); tabley = 255 - (255 * rain);
@ -212,27 +188,28 @@ base_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObjec
tablex = 255 - tabley; tablex = 255 - tabley;
tabley = tmp; tabley = tmp;
} }
/* look up color! */ /* look up color! */
color = PySequence_GetItem(color_table, tabley * 256 + tablex); color = PySequence_GetItem(color_table, tabley * 256 + tablex);
r = PyLong_AsLong(PyTuple_GET_ITEM(color, 0)); r = PyLong_AsLong(PyTuple_GET_ITEM(color, 0));
g = PyLong_AsLong(PyTuple_GET_ITEM(color, 1)); g = PyLong_AsLong(PyTuple_GET_ITEM(color, 1));
b = PyLong_AsLong(PyTuple_GET_ITEM(color, 2)); b = PyLong_AsLong(PyTuple_GET_ITEM(color, 2));
Py_DECREF(color); Py_DECREF(color);
/* do the after-coloration */ /* do the after-coloration */
r = OV_MULDIV255(r, multr, tmp); r = OV_MULDIV255(r, multr, tmp);
g = OV_MULDIV255(g, multg, tmp); g = OV_MULDIV255(g, multg, tmp);
b = OV_MULDIV255(b, multb, tmp); b = OV_MULDIV255(b, multb, tmp);
} }
/* final coloration */ /* final coloration */
tint_with_mask(state->img, r, g, b, 255, facemask, state->imgx, state->imgy, 0, 0); tint_with_mask(state->img, r, g, b, 255, facemask, state->imgx, state->imgy, 0, 0);
} }
} }
RenderPrimitiveInterface primitive_base = { RenderPrimitiveInterface primitive_base = {
"base", sizeof(PrimitiveBase), "base",
sizeof(PrimitiveBase),
base_start, base_start,
base_finish, base_finish,
base_occluded, base_occluded,

View File

@ -15,7 +15,6 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define DEFAULT_BIOME 4 /* forest, nice and green */ #define DEFAULT_BIOME 4 /* forest, nice and green */
typedef struct { typedef struct {
@ -65,7 +64,7 @@ static Biome biome_table[] = {
{"TaigaHills", 0.05, 0.8, 255, 255, 255}, {"TaigaHills", 0.05, 0.8, 255, 255, 255},
/* 20 */ /* 20 */
{"Extreme Hills Edge", 0.2, 0.3, 255, 255, 255}, {"Extreme Hills Edge", 0.2, 0.3, 255, 255, 255},
/* Values below are guesses */ /* Values below are guesses */
{"Jungle", 2.0, 0.45, 255, 255, 255}, {"Jungle", 2.0, 0.45, 255, 255, 255},
{"JungleHills", 2.0, 0.45, 255, 255, 255}, {"JungleHills", 2.0, 0.45, 255, 255, 255},
{"JungleEdge", 2.0, 0.45, 255, 255, 255}, {"JungleEdge", 2.0, 0.45, 255, 255, 255},
@ -245,4 +244,3 @@ static Biome biome_table[] = {
}; };
#define NUM_BIOMES (sizeof(biome_table) / sizeof(Biome)) #define NUM_BIOMES (sizeof(biome_table) / sizeof(Biome))

View File

@ -15,40 +15,40 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "../overviewer.h"
#include <math.h> #include <math.h>
#include "../overviewer.h"
typedef struct { typedef struct {
int only_lit; int only_lit;
} RenderPrimitiveCave; } RenderPrimitiveCave;
static inline int static inline int
touches_light(RenderState *state, DataType type, unsigned int x, unsigned int y, unsigned int z) { touches_light(RenderState* state, DataType type, unsigned int x, unsigned int y, unsigned int z) {
if (get_data(state, type, x, y+1, z)) if (get_data(state, type, x, y + 1, z))
return 1; return 1;
if (get_data(state, type, x+1, y, z)) if (get_data(state, type, x + 1, y, z))
return 1; return 1;
if (get_data(state, type, x-1, y, z)) if (get_data(state, type, x - 1, y, z))
return 1; return 1;
if (get_data(state, type, x, y, z+1)) if (get_data(state, type, x, y, z + 1))
return 1; return 1;
if (get_data(state, type, x, y, z-1)) if (get_data(state, type, x, y, z - 1))
return 1; return 1;
return 0; return 0;
} }
static int static int
cave_occluded(void *data, RenderState *state, int x, int y, int z) { cave_occluded(void* data, RenderState* state, int x, int y, int z) {
/* check for normal occlusion */ /* check for normal occlusion */
/* use ajacent chunks, if not you get blocks spreaded in chunk edges */ /* use ajacent chunks, if not you get blocks spreaded in chunk edges */
if (!is_known_transparent(get_data(state, BLOCKS, x-1, y, z)) && if (!is_known_transparent(get_data(state, BLOCKS, x - 1, y, z)) &&
!is_known_transparent(get_data(state, BLOCKS, x, y, z+1)) && !is_known_transparent(get_data(state, BLOCKS, x, y, z + 1)) &&
!is_known_transparent(get_data(state, BLOCKS, x, y+1, z))) { !is_known_transparent(get_data(state, BLOCKS, x, y + 1, z))) {
return 1; return 1;
} }
/* special handling for section boundaries */ /* special handling for section boundaries */
if (x == 0 && (!(state->chunks[0][1].loaded) || state->chunks[0][1].sections[state->chunky].blocks == NULL)) if (x == 0 && (!(state->chunks[0][1].loaded) || state->chunks[0][1].sections[state->chunky].blocks == NULL))
return 1; return 1;
@ -56,21 +56,21 @@ cave_occluded(void *data, RenderState *state, int x, int y, int z) {
return 1; return 1;
if (z == 15 && (!(state->chunks[1][2].loaded) || state->chunks[1][2].sections[state->chunky].blocks == NULL)) if (z == 15 && (!(state->chunks[1][2].loaded) || state->chunks[1][2].sections[state->chunky].blocks == NULL))
return 1; return 1;
return 0; return 0;
} }
static int static int
cave_hidden(void *data, RenderState *state, int x, int y, int z) { cave_hidden(void* data, RenderState* state, int x, int y, int z) {
RenderPrimitiveCave* self; RenderPrimitiveCave* self;
int dy = 0; int dy = 0;
self = (RenderPrimitiveCave *)data; self = (RenderPrimitiveCave*)data;
/* check if the block is touching skylight */ /* check if the block is touching skylight */
if (touches_light(state, SKYLIGHT, x, y, z)) { if (touches_light(state, SKYLIGHT, x, y, z)) {
return 1; return 1;
} }
if (self->only_lit && !touches_light(state, BLOCKLIGHT, x, y, z)) { if (self->only_lit && !touches_light(state, BLOCKLIGHT, x, y, z)) {
return 1; return 1;
} }
@ -80,9 +80,9 @@ cave_hidden(void *data, RenderState *state, int x, int y, int z) {
* but a deep sea can be completely dark * but a deep sea can be completely dark
*/ */
if ((getArrayShort3D(state->blocks, x, y, z) == 9) || if ((getArrayShort3D(state->blocks, x, y, z) == 9) ||
(get_data(state, BLOCKS, x, y+1, z) == 9)) { (get_data(state, BLOCKS, x, y + 1, z) == 9)) {
for (dy = y+1; dy < (SECTIONS_PER_CHUNK - state->chunky) * 16; dy++) { for (dy = y + 1; dy < (SECTIONS_PER_CHUNK - state->chunky) * 16; dy++) {
/* go up and check for skylight */ /* go up and check for skylight */
if (get_data(state, SKYLIGHT, x, dy, z) != 0) { if (get_data(state, SKYLIGHT, x, dy, z) != 0) {
return 1; return 1;
@ -94,7 +94,7 @@ cave_hidden(void *data, RenderState *state, int x, int y, int z) {
} }
} }
} }
/* unfortunate side-effect of lit cave mode: we need to count occluded /* unfortunate side-effect of lit cave mode: we need to count occluded
* blocks as hidden for the lighting to look right, since technically our * blocks as hidden for the lighting to look right, since technically our
* hiding depends on occlusion as well * hiding depends on occlusion as well
@ -103,18 +103,19 @@ cave_hidden(void *data, RenderState *state, int x, int y, int z) {
} }
static int static int
cave_start(void *data, RenderState *state, PyObject *support) { cave_start(void* data, RenderState* state, PyObject* support) {
RenderPrimitiveCave* self; RenderPrimitiveCave* self;
self = (RenderPrimitiveCave *)data; self = (RenderPrimitiveCave*)data;
if (!render_mode_parse_option(support, "only_lit", "i", &(self->only_lit))) if (!render_mode_parse_option(support, "only_lit", "i", &(self->only_lit)))
return 1; return 1;
return 0; return 0;
} }
RenderPrimitiveInterface primitive_cave = { RenderPrimitiveInterface primitive_cave = {
"cave", sizeof(RenderPrimitiveCave), "cave",
sizeof(RenderPrimitiveCave),
cave_start, cave_start,
NULL, NULL,
cave_occluded, cave_occluded,

View File

@ -18,22 +18,22 @@
#include "../overviewer.h" #include "../overviewer.h"
static int static int
clear_base_occluded(void *data, RenderState *state, int x, int y, int z) { clear_base_occluded(void* data, RenderState* state, int x, int y, int z) {
if ( (x != 0) && (y != 15) && (z != 127) && if ((x != 0) && (y != 15) && (z != 127) &&
!render_mode_hidden(state->rendermode, x-1, y, z) && !render_mode_hidden(state->rendermode, x - 1, y, z) &&
!render_mode_hidden(state->rendermode, x, y, z+1) && !render_mode_hidden(state->rendermode, x, y, z + 1) &&
!render_mode_hidden(state->rendermode, x, y+1, z) && !render_mode_hidden(state->rendermode, x, y + 1, z) &&
!is_transparent(getArrayShort3D(state->blocks, x-1, y, z)) && !is_transparent(getArrayShort3D(state->blocks, x - 1, y, z)) &&
!is_transparent(getArrayShort3D(state->blocks, x, y, z+1)) && !is_transparent(getArrayShort3D(state->blocks, x, y, z + 1)) &&
!is_transparent(getArrayShort3D(state->blocks, x, y+1, z))) { !is_transparent(getArrayShort3D(state->blocks, x, y + 1, z))) {
return 1; return 1;
} }
return 0; return 0;
} }
static void static void
clear_base_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { clear_base_draw(void* data, RenderState* state, PyObject* src, PyObject* mask, PyObject* mask_light) {
/* clear the draw space -- set alpha to 0 within mask */ /* clear the draw space -- set alpha to 0 within mask */
tint_with_mask(state->img, 255, 255, 255, 0, mask, state->imgx, state->imgy, 0, 0); tint_with_mask(state->img, 255, 255, 255, 0, mask, state->imgx, state->imgy, 0, 0);
} }

View File

@ -15,18 +15,18 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "../overviewer.h"
#include <math.h> #include <math.h>
#include "../overviewer.h"
typedef struct { typedef struct {
/* list of colors used for tinting */ /* list of colors used for tinting */
PyObject *depth_colors; PyObject* depth_colors;
} RenderPrimitiveDepthTinting; } RenderPrimitiveDepthTinting;
static int static int
depth_tinting_start(void *data, RenderState *state, PyObject *support) { depth_tinting_start(void* data, RenderState* state, PyObject* support) {
RenderPrimitiveDepthTinting* self; RenderPrimitiveDepthTinting* self;
self = (RenderPrimitiveDepthTinting *)data; self = (RenderPrimitiveDepthTinting*)data;
self->depth_colors = PyObject_GetAttrString(support, "depth_colors"); self->depth_colors = PyObject_GetAttrString(support, "depth_colors");
if (self->depth_colors == NULL) if (self->depth_colors == NULL)
@ -36,35 +36,36 @@ depth_tinting_start(void *data, RenderState *state, PyObject *support) {
} }
static void static void
depth_tinting_finish(void *data, RenderState *state) { depth_tinting_finish(void* data, RenderState* state) {
RenderPrimitiveDepthTinting* self; RenderPrimitiveDepthTinting* self;
self = (RenderPrimitiveDepthTinting *)data; self = (RenderPrimitiveDepthTinting*)data;
Py_DECREF(self->depth_colors); Py_DECREF(self->depth_colors);
} }
static void static void
depth_tinting_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { depth_tinting_draw(void* data, RenderState* state, PyObject* src, PyObject* mask, PyObject* mask_light) {
RenderPrimitiveDepthTinting* self; RenderPrimitiveDepthTinting* self;
int y, r, g, b; int y, r, g, b;
self = (RenderPrimitiveDepthTinting *)data; self = (RenderPrimitiveDepthTinting*)data;
y = state->chunky * 16 + state->y; y = state->chunky * 16 + state->y;
r = 0, g = 0, b = 0; r = 0, g = 0, b = 0;
/* the colors array assumes y is between 0 and 127, so we scale it */ /* the colors array assumes y is between 0 and 127, so we scale it */
y = (y * 128) / (16 * SECTIONS_PER_CHUNK); y = (y * 128) / (16 * SECTIONS_PER_CHUNK);
/* get the colors and tint and tint */ /* get the colors and tint and tint */
r = PyLong_AsLong(PyList_GetItem(self->depth_colors, 0 + y*3)); r = PyLong_AsLong(PyList_GetItem(self->depth_colors, 0 + y * 3));
g = PyLong_AsLong(PyList_GetItem(self->depth_colors, 1 + y*3)); g = PyLong_AsLong(PyList_GetItem(self->depth_colors, 1 + y * 3));
b = PyLong_AsLong(PyList_GetItem(self->depth_colors, 2 + y*3)); b = PyLong_AsLong(PyList_GetItem(self->depth_colors, 2 + y * 3));
tint_with_mask(state->img, r, g, b, 255, mask, state->imgx, state->imgy, 0, 0); tint_with_mask(state->img, r, g, b, 255, mask, state->imgx, state->imgy, 0, 0);
} }
RenderPrimitiveInterface primitive_depth_tinting = { RenderPrimitiveInterface primitive_depth_tinting = {
"depth-tinting", sizeof(RenderPrimitiveDepthTinting), "depth-tinting",
sizeof(RenderPrimitiveDepthTinting),
depth_tinting_start, depth_tinting_start,
depth_tinting_finish, depth_tinting_finish,
NULL, NULL,

View File

@ -23,9 +23,9 @@ typedef struct {
} PrimitiveDepth; } PrimitiveDepth;
static int static int
depth_start(void *data, RenderState *state, PyObject *support) { depth_start(void* data, RenderState* state, PyObject* support) {
PrimitiveDepth *self = (PrimitiveDepth *)data; PrimitiveDepth* self = (PrimitiveDepth*)data;
if (!render_mode_parse_option(support, "min", "I", &(self->min))) if (!render_mode_parse_option(support, "min", "I", &(self->min)))
return 1; return 1;
if (!render_mode_parse_option(support, "max", "I", &(self->max))) if (!render_mode_parse_option(support, "max", "I", &(self->max)))
@ -35,8 +35,8 @@ depth_start(void *data, RenderState *state, PyObject *support) {
} }
static int static int
depth_hidden(void *data, RenderState *state, int x, int y, int z) { depth_hidden(void* data, RenderState* state, int x, int y, int z) {
PrimitiveDepth *self = (PrimitiveDepth *)data; PrimitiveDepth* self = (PrimitiveDepth*)data;
y += 16 * state->chunky; y += 16 * state->chunky;
if (y > self->max || y < self->min) { if (y > self->max || y < self->min) {
return 1; return 1;
@ -45,7 +45,8 @@ depth_hidden(void *data, RenderState *state, int x, int y, int z) {
} }
RenderPrimitiveInterface primitive_depth = { RenderPrimitiveInterface primitive_depth = {
"depth", sizeof(PrimitiveDepth), "depth",
sizeof(PrimitiveDepth),
depth_start, depth_start,
NULL, NULL,
NULL, NULL,

View File

@ -15,69 +15,65 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "../overviewer.h"
#include "../mc_id.h"
#include "../block_class.h" #include "../block_class.h"
#include "../mc_id.h"
#include "../overviewer.h"
typedef struct { typedef struct {
float opacity; float opacity;
} PrimitiveEdgeLines; } PrimitiveEdgeLines;
static int static int
edge_lines_start(void *data, RenderState *state, PyObject *support) { edge_lines_start(void* data, RenderState* state, PyObject* support) {
PrimitiveEdgeLines *self = (PrimitiveEdgeLines *)data; PrimitiveEdgeLines* self = (PrimitiveEdgeLines*)data;
if (!render_mode_parse_option(support, "opacity", "f", &(self->opacity))) if (!render_mode_parse_option(support, "opacity", "f", &(self->opacity)))
return 1; return 1;
return 0; return 0;
} }
static void static void
edge_lines_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { edge_lines_draw(void* data, RenderState* state, PyObject* src, PyObject* mask, PyObject* mask_light) {
PrimitiveEdgeLines *self = (PrimitiveEdgeLines *)data; PrimitiveEdgeLines* self = (PrimitiveEdgeLines*)data;
/* Draw some edge lines! */ /* Draw some edge lines! */
if (block_class_is_subset(state->block, (mc_block_t[]){block_stone_slab,block_snow_layer}, 2) if (block_class_is_subset(state->block, (mc_block_t[]){block_stone_slab, block_snow_layer}, 2) || !is_transparent(state->block)) {
|| !is_transparent(state->block)) {
Imaging img_i = imaging_python_to_c(state->img); Imaging img_i = imaging_python_to_c(state->img);
unsigned char ink[] = {0, 0, 0, 255 * self->opacity}; unsigned char ink[] = {0, 0, 0, 255 * self->opacity};
unsigned short side_block; unsigned short side_block;
int x = state->x, y = state->y, z = state->z; int x = state->x, y = state->y, z = state->z;
int increment=0; int increment = 0;
if (block_class_is_subset(state->block, (mc_block_t[]){block_wooden_slab,block_stone_slab}, 2) && ((state->block_data & 0x8) == 0 )) // half-steps BUT no upsidown half-steps if (block_class_is_subset(state->block, (mc_block_t[]){block_wooden_slab, block_stone_slab}, 2) && ((state->block_data & 0x8) == 0)) // half-steps BUT no upsidown half-steps
increment=6; increment = 6;
else if (block_class_is_subset(state->block, (mc_block_t[]){block_snow_layer,block_unpowered_repeater,block_powered_repeater}, 3)) // snow, redstone repeaters (on and off) else if (block_class_is_subset(state->block, (mc_block_t[]){block_snow_layer, block_unpowered_repeater, block_powered_repeater}, 3)) // snow, redstone repeaters (on and off)
increment=9; increment = 9;
/* +X side */ /* +X side */
side_block = get_data(state, BLOCKS, x+1, y, z); side_block = get_data(state, BLOCKS, x + 1, y, z);
if (side_block != state->block && (is_transparent(side_block) || render_mode_hidden(state->rendermode, x+1, y, z)) && if (side_block != state->block && (is_transparent(side_block) || render_mode_hidden(state->rendermode, x + 1, y, z)) &&
/* WARNING: ugly special case approaching */ /* WARNING: ugly special case approaching */
/* if the block is a slab and the side block is a stair don't draw anything, it can give very ugly results */ /* if the block is a slab and the side block is a stair don't draw anything, it can give very ugly results */
!(block_class_is_subset(state->block, (mc_block_t[]){block_wooden_slab, block_stone_slab}, 2) !(block_class_is_subset(state->block, (mc_block_t[]){block_wooden_slab, block_stone_slab}, 2) && (block_class_is_subset(side_block, block_class_stair, block_class_stair_len)))) {
&& (block_class_is_subset(side_block, block_class_stair, block_class_stair_len)) ImagingDrawLine(img_i, state->imgx + 12, state->imgy + 1 + increment, state->imgx + 22 + 1, state->imgy + 5 + 1 + increment, &ink, 1);
)) { ImagingDrawLine(img_i, state->imgx + 12, state->imgy + increment, state->imgx + 22 + 1, state->imgy + 5 + increment, &ink, 1);
ImagingDrawLine(img_i, state->imgx+12, state->imgy+1+increment, state->imgx+22+1, state->imgy+5+1+increment, &ink, 1);
ImagingDrawLine(img_i, state->imgx+12, state->imgy+increment, state->imgx+22+1, state->imgy+5+increment, &ink, 1);
} }
/* -Z side */ /* -Z side */
side_block = get_data(state, BLOCKS, x, y, z-1); side_block = get_data(state, BLOCKS, x, y, z - 1);
if (side_block != state->block && (is_transparent(side_block) || render_mode_hidden(state->rendermode, x, y, z-1)) && if (side_block != state->block && (is_transparent(side_block) || render_mode_hidden(state->rendermode, x, y, z - 1)) &&
/* WARNING: ugly special case approaching */ /* WARNING: ugly special case approaching */
/* if the block is a slab and the side block is a stair don't draw anything, it can give very ugly results */ /* if the block is a slab and the side block is a stair don't draw anything, it can give very ugly results */
!( !(
block_class_is_subset(state->block, (mc_block_t[]){block_stone_slab,block_wooden_slab}, 2) block_class_is_subset(state->block, (mc_block_t[]){block_stone_slab, block_wooden_slab}, 2) && (block_class_is_subset(side_block, block_class_stair, block_class_stair_len)))) {
&& (block_class_is_subset(side_block, block_class_stair, block_class_stair_len)) ImagingDrawLine(img_i, state->imgx, state->imgy + 6 + 1 + increment, state->imgx + 12 + 1, state->imgy + 1 + increment, &ink, 1);
)) { ImagingDrawLine(img_i, state->imgx, state->imgy + 6 + increment, state->imgx + 12 + 1, state->imgy + increment, &ink, 1);
ImagingDrawLine(img_i, state->imgx, state->imgy+6+1+increment, state->imgx+12+1, state->imgy+1+increment, &ink, 1);
ImagingDrawLine(img_i, state->imgx, state->imgy+6+increment, state->imgx+12+1, state->imgy+increment, &ink, 1);
} }
} }
} }
RenderPrimitiveInterface primitive_edge_lines = { RenderPrimitiveInterface primitive_edge_lines = {
"edge-lines", sizeof(PrimitiveEdgeLines), "edge-lines",
sizeof(PrimitiveEdgeLines),
edge_lines_start, edge_lines_start,
NULL, NULL,
NULL, NULL,

View File

@ -22,19 +22,19 @@ typedef struct {
} PrimitiveExposed; } PrimitiveExposed;
static int static int
exposed_start(void *data, RenderState *state, PyObject *support) { exposed_start(void* data, RenderState* state, PyObject* support) {
PrimitiveExposed *self = (PrimitiveExposed *)data; PrimitiveExposed* self = (PrimitiveExposed*)data;
if (!render_mode_parse_option(support, "mode", "I", &(self->mode))) if (!render_mode_parse_option(support, "mode", "I", &(self->mode)))
return 1; return 1;
return 0; return 0;
} }
static int static int
exposed_hidden(void *data, RenderState *state, int x, int y, int z) { exposed_hidden(void* data, RenderState* state, int x, int y, int z) {
PrimitiveExposed *self = (PrimitiveExposed *)data; PrimitiveExposed* self = (PrimitiveExposed*)data;
/* Unset these flags if seeming exposure from any of these directions would /* Unset these flags if seeming exposure from any of these directions would
* be due to not having data there. * be due to not having data there.
*/ */
@ -53,54 +53,54 @@ exposed_hidden(void *data, RenderState *state, int x, int y, int z) {
/* No data in -x direction */ /* No data in -x direction */
validMinusX = 0; validMinusX = 0;
} }
if (x == 15 && (!(state->chunks[2][1].loaded) || state->chunks[2][1].sections[state->chunky].blocks == NULL)) { if (x == 15 && (!(state->chunks[2][1].loaded) || state->chunks[2][1].sections[state->chunky].blocks == NULL)) {
/* No data in +x direction */ /* No data in +x direction */
validPlusX = 0; validPlusX = 0;
} }
if (y == 0 && (state->chunky - 1 < 0 || state->chunks[1][1].sections[state->chunky - 1].blocks == NULL)) { if (y == 0 && (state->chunky - 1 < 0 || state->chunks[1][1].sections[state->chunky - 1].blocks == NULL)) {
/* No data in -y direction */ /* No data in -y direction */
validMinusY = 0; validMinusY = 0;
} }
if (y == 15 && (state->chunky + 1 >= SECTIONS_PER_CHUNK || state->chunks[1][1].sections[state->chunky + 1].blocks == NULL)) { if (y == 15 && (state->chunky + 1 >= SECTIONS_PER_CHUNK || state->chunks[1][1].sections[state->chunky + 1].blocks == NULL)) {
/* No data in +y direction */ /* No data in +y direction */
validPlusY = 0; validPlusY = 0;
} }
if (z == 0 && (!(state->chunks[1][0].loaded) || state->chunks[1][0].sections[state->chunky].blocks == NULL)) { if (z == 0 && (!(state->chunks[1][0].loaded) || state->chunks[1][0].sections[state->chunky].blocks == NULL)) {
/* No data in -z direction */ /* No data in -z direction */
validMinusZ = 0; validMinusZ = 0;
} }
if (z == 15 && (!(state->chunks[1][2].loaded) || state->chunks[1][2].sections[state->chunky].blocks == NULL)) { if (z == 15 && (!(state->chunks[1][2].loaded) || state->chunks[1][2].sections[state->chunky].blocks == NULL)) {
/* No data in +z direction */ /* No data in +z direction */
validPlusZ = 0; validPlusZ = 0;
} }
/* If any of the 6 blocks adjacent to us are transparent, we're exposed */ /* If any of the 6 blocks adjacent to us are transparent, we're exposed */
if( (validMinusX && is_transparent(get_data(state, BLOCKS, x-1, y, z))) || if ((validMinusX && is_transparent(get_data(state, BLOCKS, x - 1, y, z))) ||
(validPlusX && is_transparent(get_data(state, BLOCKS, x+1, y, z))) || (validPlusX && is_transparent(get_data(state, BLOCKS, x + 1, y, z))) ||
(validMinusY && is_transparent(get_data(state, BLOCKS, x, y-1, z))) || (validMinusY && is_transparent(get_data(state, BLOCKS, x, y - 1, z))) ||
(validPlusY && is_transparent(get_data(state, BLOCKS, x, y+1, z))) || (validPlusY && is_transparent(get_data(state, BLOCKS, x, y + 1, z))) ||
(validMinusZ && is_transparent(get_data(state, BLOCKS, x, y, z-1))) || (validMinusZ && is_transparent(get_data(state, BLOCKS, x, y, z - 1))) ||
(validPlusZ && is_transparent(get_data(state, BLOCKS, x, y, z+1 ))) ) { (validPlusZ && is_transparent(get_data(state, BLOCKS, x, y, z + 1)))) {
/* Block is exposed */ /* Block is exposed */
/* Returns 1 and hides us if we're rendering unexposed blocks, 0 and /* Returns 1 and hides us if we're rendering unexposed blocks, 0 and
* shows us if we're rendering exposed blocks * shows us if we're rendering exposed blocks
*/ */
return self->mode; return self->mode;
} }
/* We have no valid evidence that the block is exposed */ /* We have no valid evidence that the block is exposed */
return !(self->mode); /* Hide in normal mode, reveal in inverted mode */ return !(self->mode); /* Hide in normal mode, reveal in inverted mode */
} }
RenderPrimitiveInterface primitive_exposed = { RenderPrimitiveInterface primitive_exposed = {
"exposed", sizeof(PrimitiveExposed), "exposed",
sizeof(PrimitiveExposed),
exposed_start, exposed_start,
NULL, NULL,
NULL, NULL,

View File

@ -18,57 +18,58 @@
#include "../overviewer.h" #include "../overviewer.h"
typedef struct { typedef struct {
PyObject *black_color; PyObject* black_color;
PyObject *white_color; PyObject* white_color;
unsigned int sealevel; unsigned int sealevel;
} PrimitiveHeightFading; } PrimitiveHeightFading;
static int static int
height_fading_start(void *data, RenderState *state, PyObject *support) { height_fading_start(void* data, RenderState* state, PyObject* support) {
PrimitiveHeightFading *self = (PrimitiveHeightFading *)data; PrimitiveHeightFading* self = (PrimitiveHeightFading*)data;
if (!render_mode_parse_option(support, "sealevel", "I", &(self->sealevel))) if (!render_mode_parse_option(support, "sealevel", "I", &(self->sealevel)))
return 1; return 1;
self->black_color = PyObject_GetAttrString(support, "black_color"); self->black_color = PyObject_GetAttrString(support, "black_color");
self->white_color = PyObject_GetAttrString(support, "white_color"); self->white_color = PyObject_GetAttrString(support, "white_color");
return 0; return 0;
} }
static void static void
height_fading_finish(void *data, RenderState *state) { height_fading_finish(void* data, RenderState* state) {
PrimitiveHeightFading *self = (PrimitiveHeightFading *)data; PrimitiveHeightFading* self = (PrimitiveHeightFading*)data;
Py_DECREF(self->black_color); Py_DECREF(self->black_color);
Py_DECREF(self->white_color); Py_DECREF(self->white_color);
} }
static void static void
height_fading_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { height_fading_draw(void* data, RenderState* state, PyObject* src, PyObject* mask, PyObject* mask_light) {
float alpha; float alpha;
PrimitiveHeightFading *self = (PrimitiveHeightFading *)data; PrimitiveHeightFading* self = (PrimitiveHeightFading*)data;
int y = 16 * state->chunky + state->y; int y = 16 * state->chunky + state->y;
/* do some height fading */ /* do some height fading */
PyObject *height_color = self->white_color; PyObject* height_color = self->white_color;
/* current formula requires y to be between 0 and 127, so scale it */ /* current formula requires y to be between 0 and 127, so scale it */
y = (y * 128) / (2 * self->sealevel); y = (y * 128) / (2 * self->sealevel);
/* negative alpha => darkness, positive => light */ /* negative alpha => darkness, positive => light */
alpha = (1.0 / (1 + expf((70 - y) / 11.0))) * 0.6 - 0.55; alpha = (1.0 / (1 + expf((70 - y) / 11.0))) * 0.6 - 0.55;
if (alpha < 0.0) { if (alpha < 0.0) {
alpha *= -1; alpha *= -1;
height_color = self->black_color; height_color = self->black_color;
} }
alpha_over_full(state->img, height_color, mask_light, alpha, state->imgx, state->imgy, 0, 0); alpha_over_full(state->img, height_color, mask_light, alpha, state->imgx, state->imgy, 0, 0);
} }
RenderPrimitiveInterface primitive_height_fading = { RenderPrimitiveInterface primitive_height_fading = {
"height-fading", sizeof(PrimitiveHeightFading), "height-fading",
sizeof(PrimitiveHeightFading),
height_fading_start, height_fading_start,
height_fading_finish, height_fading_finish,
NULL, NULL,

View File

@ -15,8 +15,8 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "../overviewer.h"
#include "../mc_id.h" #include "../mc_id.h"
#include "../overviewer.h"
struct HideRule { struct HideRule {
unsigned short blockid; unsigned short blockid;
@ -29,21 +29,21 @@ typedef struct {
} RenderPrimitiveHide; } RenderPrimitiveHide;
static int static int
hide_start(void *data, RenderState *state, PyObject *support) { hide_start(void* data, RenderState* state, PyObject* support) {
PyObject *opt; PyObject* opt;
RenderPrimitiveHide* self = (RenderPrimitiveHide *)data; RenderPrimitiveHide* self = (RenderPrimitiveHide*)data;
self->rules = NULL; self->rules = NULL;
if (!render_mode_parse_option(support, "blocks", "O", &(opt))) if (!render_mode_parse_option(support, "blocks", "O", &(opt)))
return 1; return 1;
if (opt && opt != Py_None) { if (opt && opt != Py_None) {
Py_ssize_t blocks_size = 0, i; Py_ssize_t blocks_size = 0, i;
if (!PyList_Check(opt)) { if (!PyList_Check(opt)) {
PyErr_SetString(PyExc_TypeError, "'blocks' must be a list"); PyErr_SetString(PyExc_TypeError, "'blocks' must be a list");
return 1; return 1;
} }
blocks_size = PyList_GET_SIZE(opt); blocks_size = PyList_GET_SIZE(opt);
self->rules = calloc(blocks_size + 1, sizeof(struct HideRule)); self->rules = calloc(blocks_size + 1, sizeof(struct HideRule));
if (self->rules == NULL) { if (self->rules == NULL) {
@ -51,8 +51,8 @@ hide_start(void *data, RenderState *state, PyObject *support) {
} }
for (i = 0; i < blocks_size; i++) { for (i = 0; i < blocks_size; i++) {
PyObject *block = PyList_GET_ITEM(opt, i); PyObject* block = PyList_GET_ITEM(opt, i);
if (PyLong_Check(block)) { if (PyLong_Check(block)) {
/* format 1: just a block id */ /* format 1: just a block id */
self->rules[i].blockid = PyLong_AsLong(block); self->rules[i].blockid = PyLong_AsLong(block);
@ -68,42 +68,42 @@ hide_start(void *data, RenderState *state, PyObject *support) {
} }
} }
} }
return 0; return 0;
} }
static void static void
hide_finish(void *data, RenderState *state) { hide_finish(void* data, RenderState* state) {
RenderPrimitiveHide *self = (RenderPrimitiveHide *)data; RenderPrimitiveHide* self = (RenderPrimitiveHide*)data;
if (self->rules) { if (self->rules) {
free(self->rules); free(self->rules);
} }
} }
static int static int
hide_hidden(void *data, RenderState *state, int x, int y, int z) { hide_hidden(void* data, RenderState* state, int x, int y, int z) {
RenderPrimitiveHide *self = (RenderPrimitiveHide *)data; RenderPrimitiveHide* self = (RenderPrimitiveHide*)data;
unsigned int i; unsigned int i;
unsigned short block; unsigned short block;
if (self->rules == NULL) if (self->rules == NULL)
return 0; return 0;
block = get_data(state, BLOCKS, x, y, z); block = get_data(state, BLOCKS, x, y, z);
for (i = 0; self->rules[i].blockid != block_air; i++) { for (i = 0; self->rules[i].blockid != block_air; i++) {
if (block == self->rules[i].blockid) { if (block == self->rules[i].blockid) {
unsigned char data; unsigned char data;
if (!(self->rules[i].has_data)) if (!(self->rules[i].has_data))
return 1; return 1;
data = get_data(state, DATA, x, y, z); data = get_data(state, DATA, x, y, z);
if (data == self->rules[i].data) if (data == self->rules[i].data)
return 1; return 1;
} }
} }
return 0; return 0;
} }

View File

@ -15,18 +15,18 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "../overviewer.h"
#include "../mc_id.h"
#include "../block_class.h"
#include "lighting.h"
#include <math.h> #include <math.h>
#include "lighting.h"
#include "../block_class.h"
#include "../mc_id.h"
#include "../overviewer.h"
/* figures out the color from a given skylight and blocklight, /* figures out the color from a given skylight and blocklight,
used in lighting calculations */ used in lighting calculations */
static void static void
calculate_light_color(void *data, calculate_light_color(void* data,
unsigned char skylight, unsigned char blocklight, unsigned char skylight, unsigned char blocklight,
unsigned char *r, unsigned char *g, unsigned char *b) { unsigned char* r, unsigned char* g, unsigned char* b) {
unsigned char v = 255 * powf(0.8f, 15.0 - OV_MAX(blocklight, skylight)); unsigned char v = 255 * powf(0.8f, 15.0 - OV_MAX(blocklight, skylight));
*r = v; *r = v;
*g = v; *g = v;
@ -35,22 +35,22 @@ calculate_light_color(void *data,
/* fancy version that uses the colored light texture */ /* fancy version that uses the colored light texture */
static void static void
calculate_light_color_fancy(void *data, calculate_light_color_fancy(void* data,
unsigned char skylight, unsigned char blocklight, unsigned char skylight, unsigned char blocklight,
unsigned char *r, unsigned char *g, unsigned char *b) { unsigned char* r, unsigned char* g, unsigned char* b) {
RenderPrimitiveLighting *mode = (RenderPrimitiveLighting *)(data); RenderPrimitiveLighting* mode = (RenderPrimitiveLighting*)(data);
unsigned int index; unsigned int index;
PyObject *color; PyObject* color;
blocklight = OV_MAX(blocklight, skylight); blocklight = OV_MAX(blocklight, skylight);
index = skylight + blocklight * 16; index = skylight + blocklight * 16;
color = PySequence_GetItem(mode->lightcolor, index); color = PySequence_GetItem(mode->lightcolor, index);
*r = PyLong_AsLong(PyTuple_GET_ITEM(color, 0)); *r = PyLong_AsLong(PyTuple_GET_ITEM(color, 0));
*g = PyLong_AsLong(PyTuple_GET_ITEM(color, 1)); *g = PyLong_AsLong(PyTuple_GET_ITEM(color, 1));
*b = PyLong_AsLong(PyTuple_GET_ITEM(color, 2)); *b = PyLong_AsLong(PyTuple_GET_ITEM(color, 2));
Py_DECREF(color); Py_DECREF(color);
} }
@ -59,9 +59,9 @@ calculate_light_color_fancy(void *data,
(the "skylight - 11" part) (the "skylight - 11" part)
*/ */
static void static void
calculate_light_color_night(void *data, calculate_light_color_night(void* data,
unsigned char skylight, unsigned char blocklight, unsigned char skylight, unsigned char blocklight,
unsigned char *r, unsigned char *g, unsigned char *b) { unsigned char* r, unsigned char* g, unsigned char* b) {
unsigned char v = 255 * powf(0.8f, 15.0 - OV_MAX(blocklight, skylight - 11)); unsigned char v = 255 * powf(0.8f, 15.0 - OV_MAX(blocklight, skylight - 11));
*r = v; *r = v;
*g = v; *g = v;
@ -70,20 +70,20 @@ calculate_light_color_night(void *data,
/* fancy night version that uses the colored light texture */ /* fancy night version that uses the colored light texture */
static void static void
calculate_light_color_fancy_night(void *data, calculate_light_color_fancy_night(void* data,
unsigned char skylight, unsigned char blocklight, unsigned char skylight, unsigned char blocklight,
unsigned char *r, unsigned char *g, unsigned char *b) { unsigned char* r, unsigned char* g, unsigned char* b) {
RenderPrimitiveLighting *mode = (RenderPrimitiveLighting *)(data); RenderPrimitiveLighting* mode = (RenderPrimitiveLighting*)(data);
unsigned int index; unsigned int index;
PyObject *color; PyObject* color;
index = skylight + blocklight * 16; index = skylight + blocklight * 16;
color = PySequence_GetItem(mode->lightcolor, index); color = PySequence_GetItem(mode->lightcolor, index);
*r = PyLong_AsLong(PyTuple_GET_ITEM(color, 0)); *r = PyLong_AsLong(PyTuple_GET_ITEM(color, 0));
*g = PyLong_AsLong(PyTuple_GET_ITEM(color, 1)); *g = PyLong_AsLong(PyTuple_GET_ITEM(color, 1));
*b = PyLong_AsLong(PyTuple_GET_ITEM(color, 2)); *b = PyLong_AsLong(PyTuple_GET_ITEM(color, 2));
Py_DECREF(color); Py_DECREF(color);
} }
@ -98,8 +98,8 @@ calculate_light_color_fancy_night(void *data,
*/ */
unsigned char unsigned char
estimate_blocklevel(RenderPrimitiveLighting *self, RenderState *state, estimate_blocklevel(RenderPrimitiveLighting* self, RenderState* state,
int x, int y, int z, int *authoratative) { int x, int y, int z, int* authoratative) {
/* placeholders for later data arrays, coordinates */ /* placeholders for later data arrays, coordinates */
unsigned short block; unsigned short block;
@ -109,19 +109,19 @@ estimate_blocklevel(RenderPrimitiveLighting *self, RenderState *state,
/* defaults to "guess" until told otherwise */ /* defaults to "guess" until told otherwise */
if (authoratative) if (authoratative)
*authoratative = 0; *authoratative = 0;
block = get_data(state, BLOCKS, x, y, z); block = get_data(state, BLOCKS, x, y, z);
if (authoratative == NULL) { if (authoratative == NULL) {
int auth; int auth;
/* iterate through all surrounding blocks to take an average */ /* iterate through all surrounding blocks to take an average */
int dx, dy, dz, local_block; int dx, dy, dz, local_block;
for (dx = -1; dx <= 1; dx += 2) { for (dx = -1; dx <= 1; dx += 2) {
for (dy = -1; dy <= 1; dy += 2) { for (dy = -1; dy <= 1; dy += 2) {
for (dz = -1; dz <= 1; dz += 2) { for (dz = -1; dz <= 1; dz += 2) {
coeff = estimate_blocklevel(self, state, x+dx, y+dy, z+dz, &auth); coeff = estimate_blocklevel(self, state, x + dx, y + dy, z + dz, &auth);
local_block = get_data(state, BLOCKS, x+dx, y+dy, z+dz); local_block = get_data(state, BLOCKS, x + dx, y + dy, z + dz);
/* only add if the block is transparent, this seems to look better than /* only add if the block is transparent, this seems to look better than
using every block */ using every block */
if (auth && is_transparent(local_block)) { if (auth && is_transparent(local_block)) {
@ -132,45 +132,45 @@ estimate_blocklevel(RenderPrimitiveLighting *self, RenderState *state,
} }
} }
} }
/* only return the average if at least one was authoratative */ /* only return the average if at least one was authoratative */
if (average_count > 0) { if (average_count > 0) {
return average_gather / average_count; return average_gather / average_count;
} }
blocklevel = get_data(state, BLOCKLIGHT, x, y, z); blocklevel = get_data(state, BLOCKLIGHT, x, y, z);
/* no longer a guess */ /* no longer a guess */
if (!block_class_is_subset(block, block_class_alt_height, block_class_alt_height_len) && authoratative) { if (!block_class_is_subset(block, block_class_alt_height, block_class_alt_height_len) && authoratative) {
*authoratative = 1; *authoratative = 1;
} }
return blocklevel; return blocklevel;
} }
inline void inline void
get_lighting_color(RenderPrimitiveLighting *self, RenderState *state, get_lighting_color(RenderPrimitiveLighting* self, RenderState* state,
int x, int y, int z, int x, int y, int z,
unsigned char *r, unsigned char *g, unsigned char *b) { unsigned char* r, unsigned char* g, unsigned char* b) {
/* placeholders for later data arrays, coordinates */ /* placeholders for later data arrays, coordinates */
unsigned short block; unsigned short block;
unsigned char skylevel, blocklevel; unsigned char skylevel, blocklevel;
block = get_data(state, BLOCKS, x, y, z); block = get_data(state, BLOCKS, x, y, z);
skylevel = get_data(state, SKYLIGHT, x, y, z); skylevel = get_data(state, SKYLIGHT, x, y, z);
blocklevel = get_data(state, BLOCKLIGHT, x, y, z); blocklevel = get_data(state, BLOCKLIGHT, x, y, z);
/* special half-step handling, stairs handling */ /* special half-step handling, stairs handling */
/* Anvil also needs to be here, blockid 145 */ /* Anvil also needs to be here, blockid 145 */
if ( block_class_is_subset(block, block_class_alt_height, block_class_alt_height_len) || block == block_anvil) { if (block_class_is_subset(block, block_class_alt_height, block_class_alt_height_len) || block == block_anvil) {
unsigned int upper_block; unsigned int upper_block;
/* stairs and half-blocks take the skylevel from the upper block if it's transparent */ /* stairs and half-blocks take the skylevel from the upper block if it's transparent */
int upper_counter = 0; int upper_counter = 0;
/* but if the upper_block is one of these special half-steps, we need to look at *its* upper_block */ /* but if the upper_block is one of these special half-steps, we need to look at *its* upper_block */
do { do {
upper_counter++; upper_counter++;
upper_block = get_data(state, BLOCKS, x, y + upper_counter, z); upper_block = get_data(state, BLOCKS, x, y + upper_counter, z);
} while (block_class_is_subset(upper_block, block_class_alt_height, block_class_alt_height_len)); } while (block_class_is_subset(upper_block, block_class_alt_height, block_class_alt_height_len));
if (is_transparent(upper_block)) { if (is_transparent(upper_block)) {
@ -178,31 +178,30 @@ get_lighting_color(RenderPrimitiveLighting *self, RenderState *state,
} else { } else {
skylevel = 15; skylevel = 15;
} }
/* the block has a bad blocklevel, estimate it from neigborhood /* the block has a bad blocklevel, estimate it from neigborhood
* use given coordinates, no local ones! */ * use given coordinates, no local ones! */
blocklevel = estimate_blocklevel(self, state, x, y, z, NULL); blocklevel = estimate_blocklevel(self, state, x, y, z, NULL);
} }
if (block_class_is_subset(block, (mc_block_t[]){block_flowing_lava,block_lava}, 2)) { if (block_class_is_subset(block, (mc_block_t[]){block_flowing_lava, block_lava}, 2)) {
/* lava blocks should always be lit! */ /* lava blocks should always be lit! */
*r = 255; *r = 255;
*g = 255; *g = 255;
*b = 255; *b = 255;
return; return;
} }
self->calculate_light_color(self, OV_MIN(skylevel, 15), OV_MIN(blocklevel, 15), r, g, b); self->calculate_light_color(self, OV_MIN(skylevel, 15), OV_MIN(blocklevel, 15), r, g, b);
} }
/* does per-face occlusion checking for do_shading_with_mask */ /* does per-face occlusion checking for do_shading_with_mask */
inline int inline int
lighting_is_face_occluded(RenderState *state, int skip_sides, int x, int y, int z) { lighting_is_face_occluded(RenderState* state, int skip_sides, int x, int y, int z) {
/* first, check for occlusion if the block is in the local chunk */ /* first, check for occlusion if the block is in the local chunk */
if (x >= 0 && x < 16 && y >= 0 && y < 16 && z >= 0 && z < 16) { if (x >= 0 && x < 16 && y >= 0 && y < 16 && z >= 0 && z < 16) {
unsigned short block = getArrayShort3D(state->blocks, x, y, z); unsigned short block = getArrayShort3D(state->blocks, x, y, z);
if (!is_transparent(block) && !render_mode_hidden(state->rendermode, x, y, z)) { if (!is_transparent(block) && !render_mode_hidden(state->rendermode, x, y, z)) {
/* this face isn't visible, so don't draw anything */ /* this face isn't visible, so don't draw anything */
return 1; return 1;
@ -214,7 +213,7 @@ lighting_is_face_occluded(RenderState *state, int skip_sides, int x, int y, int
ugly black doted line between chunks in night rendermode. ugly black doted line between chunks in night rendermode.
This wouldn't be necessary if the textures were truly This wouldn't be necessary if the textures were truly
tessellate-able */ tessellate-able */
return 1; return 1;
} }
} }
return 0; return 0;
@ -223,30 +222,30 @@ lighting_is_face_occluded(RenderState *state, int skip_sides, int x, int y, int
/* shades the drawn block with the given facemask, based on the /* shades the drawn block with the given facemask, based on the
lighting results from (x, y, z) */ lighting results from (x, y, z) */
static inline void static inline void
do_shading_with_mask(RenderPrimitiveLighting *self, RenderState *state, do_shading_with_mask(RenderPrimitiveLighting* self, RenderState* state,
int x, int y, int z, PyObject *mask) { int x, int y, int z, PyObject* mask) {
unsigned char r, g, b; unsigned char r, g, b;
float comp_strength; float comp_strength;
/* check occlusion */ /* check occlusion */
if (lighting_is_face_occluded(state, self->skip_sides, x, y, z)) if (lighting_is_face_occluded(state, self->skip_sides, x, y, z))
return; return;
get_lighting_color(self, state, x, y, z, &r, &g, &b); get_lighting_color(self, state, x, y, z, &r, &g, &b);
comp_strength = 1.0 - self->strength; comp_strength = 1.0 - self->strength;
r += (255 - r) * comp_strength; r += (255 - r) * comp_strength;
g += (255 - g) * comp_strength; g += (255 - g) * comp_strength;
b += (255 - b) * comp_strength; b += (255 - b) * comp_strength;
tint_with_mask(state->img, r, g, b, 255, mask, state->imgx, state->imgy, 0, 0); tint_with_mask(state->img, r, g, b, 255, mask, state->imgx, state->imgy, 0, 0);
} }
static int static int
lighting_start(void *data, RenderState *state, PyObject *support) { lighting_start(void* data, RenderState* state, PyObject* support) {
RenderPrimitiveLighting* self; RenderPrimitiveLighting* self;
self = (RenderPrimitiveLighting *)data; self = (RenderPrimitiveLighting*)data;
/* don't skip sides by default */ /* don't skip sides by default */
self->skip_sides = 0; self->skip_sides = 0;
@ -256,19 +255,19 @@ lighting_start(void *data, RenderState *state, PyObject *support) {
return 1; return 1;
if (!render_mode_parse_option(support, "color", "i", &(self->color))) if (!render_mode_parse_option(support, "color", "i", &(self->color)))
return 1; return 1;
self->facemasks_py = PyObject_GetAttrString(support, "facemasks"); self->facemasks_py = PyObject_GetAttrString(support, "facemasks");
// borrowed references, don't need to be decref'd // borrowed references, don't need to be decref'd
self->facemasks[0] = PyTuple_GetItem(self->facemasks_py, 0); self->facemasks[0] = PyTuple_GetItem(self->facemasks_py, 0);
self->facemasks[1] = PyTuple_GetItem(self->facemasks_py, 1); self->facemasks[1] = PyTuple_GetItem(self->facemasks_py, 1);
self->facemasks[2] = PyTuple_GetItem(self->facemasks_py, 2); self->facemasks[2] = PyTuple_GetItem(self->facemasks_py, 2);
if (self->night) { if (self->night) {
self->calculate_light_color = calculate_light_color_night; self->calculate_light_color = calculate_light_color_night;
} else { } else {
self->calculate_light_color = calculate_light_color; self->calculate_light_color = calculate_light_color;
} }
if (self->color) { if (self->color) {
self->lightcolor = PyObject_CallMethod(state->textures, "load_light_color", ""); self->lightcolor = PyObject_CallMethod(state->textures, "load_light_color", "");
if (self->lightcolor == Py_None) { if (self->lightcolor == Py_None) {
@ -285,37 +284,37 @@ lighting_start(void *data, RenderState *state, PyObject *support) {
} else { } else {
self->lightcolor = NULL; self->lightcolor = NULL;
} }
return 0; return 0;
} }
static void static void
lighting_finish(void *data, RenderState *state) { lighting_finish(void* data, RenderState* state) {
RenderPrimitiveLighting *self = (RenderPrimitiveLighting *)data; RenderPrimitiveLighting* self = (RenderPrimitiveLighting*)data;
Py_DECREF(self->facemasks_py); Py_DECREF(self->facemasks_py);
} }
static void static void
lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { lighting_draw(void* data, RenderState* state, PyObject* src, PyObject* mask, PyObject* mask_light) {
RenderPrimitiveLighting* self; RenderPrimitiveLighting* self;
int x, y, z; int x, y, z;
self = (RenderPrimitiveLighting *)data; self = (RenderPrimitiveLighting*)data;
x = state->x, y = state->y, z = state->z; x = state->x, y = state->y, z = state->z;
if (block_class_is_subset(state->block, (mc_block_t[]){block_flowing_water,block_water}, 2)) { /* special case for water */ if (block_class_is_subset(state->block, (mc_block_t[]){block_flowing_water, block_water}, 2)) { /* special case for water */
/* looks like we need a new case for lighting, there are /* looks like we need a new case for lighting, there are
* blocks that are transparent for occlusion calculations and * blocks that are transparent for occlusion calculations and
* need per-face shading if the face is drawn. */ * need per-face shading if the face is drawn. */
if ((state->block_pdata & 16) == 16) { if ((state->block_pdata & 16) == 16) {
do_shading_with_mask(self, state, x, y+1, z, self->facemasks[0]); do_shading_with_mask(self, state, x, y + 1, z, self->facemasks[0]);
} }
if ((state->block_pdata & 2) == 2) { /* bottom left */ if ((state->block_pdata & 2) == 2) { /* bottom left */
do_shading_with_mask(self, state, x-1, y, z, self->facemasks[1]); do_shading_with_mask(self, state, x - 1, y, z, self->facemasks[1]);
} }
if ((state->block_pdata & 4) == 4) { /* bottom right */ if ((state->block_pdata & 4) == 4) { /* bottom right */
do_shading_with_mask(self, state, x, y, z+1, self->facemasks[2]); do_shading_with_mask(self, state, x, y, z + 1, self->facemasks[2]);
} }
/* leaves and ice are transparent for occlusion calculations but they /* leaves and ice are transparent for occlusion calculations but they
* per face-shading to look as in game */ * per face-shading to look as in game */
@ -324,14 +323,15 @@ lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyO
do_shading_with_mask(self, state, x, y, z, mask_light); do_shading_with_mask(self, state, x, y, z, mask_light);
} else { } else {
/* opaque: do per-face shading */ /* opaque: do per-face shading */
do_shading_with_mask(self, state, x, y+1, z, self->facemasks[0]); do_shading_with_mask(self, state, x, y + 1, z, self->facemasks[0]);
do_shading_with_mask(self, state, x-1, y, z, self->facemasks[1]); do_shading_with_mask(self, state, x - 1, y, z, self->facemasks[1]);
do_shading_with_mask(self, state, x, y, z+1, self->facemasks[2]); do_shading_with_mask(self, state, x, y, z + 1, self->facemasks[2]);
} }
} }
RenderPrimitiveInterface primitive_lighting = { RenderPrimitiveInterface primitive_lighting = {
"lighting", sizeof(RenderPrimitiveLighting), "lighting",
sizeof(RenderPrimitiveLighting),
lighting_start, lighting_start,
lighting_finish, lighting_finish,
NULL, NULL,

View File

@ -18,21 +18,21 @@
#include "../overviewer.h" #include "../overviewer.h"
typedef struct { typedef struct {
PyObject *facemasks_py; PyObject* facemasks_py;
PyObject *facemasks[3]; PyObject* facemasks[3];
/* light color image, loaded if color_light is True */ /* light color image, loaded if color_light is True */
PyObject *lightcolor; PyObject* lightcolor;
/* can be overridden in derived rendermodes to control lighting /* can be overridden in derived rendermodes to control lighting
arguments are data, skylight, blocklight, return RGB */ arguments are data, skylight, blocklight, return RGB */
void (*calculate_light_color)(void *, unsigned char, unsigned char, unsigned char *, unsigned char *, unsigned char *); void (*calculate_light_color)(void*, unsigned char, unsigned char, unsigned char*, unsigned char*, unsigned char*);
/* can be set to 0 in derived modes to indicate that lighting the chunk /* can be set to 0 in derived modes to indicate that lighting the chunk
* sides is actually important. Right now, this is used in cave mode * sides is actually important. Right now, this is used in cave mode
*/ */
int skip_sides; int skip_sides;
float strength; float strength;
int color; int color;
int night; int night;
@ -40,7 +40,7 @@ typedef struct {
/* exposed so that smooth-lighting can use them */ /* exposed so that smooth-lighting can use them */
extern RenderPrimitiveInterface primitive_lighting; extern RenderPrimitiveInterface primitive_lighting;
int lighting_is_face_occluded(RenderState *state, int skip_sides, int x, int y, int z); int lighting_is_face_occluded(RenderState* state, int skip_sides, int x, int y, int z);
void get_lighting_color(RenderPrimitiveLighting *self, RenderState *state, void get_lighting_color(RenderPrimitiveLighting* self, RenderState* state,
int x, int y, int z, int x, int y, int z,
unsigned char *r, unsigned char *g, unsigned char *b); unsigned char* r, unsigned char* g, unsigned char* b);

View File

@ -15,13 +15,13 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "../overviewer.h"
#include "../mc_id.h"
#include "../block_class.h"
#include "nether.h" #include "nether.h"
#include "../block_class.h"
#include "../mc_id.h"
#include "../overviewer.h"
static void static void
walk_chunk(RenderState *state, RenderPrimitiveNether *data) { walk_chunk(RenderState* state, RenderPrimitiveNether* data) {
int x, y, z; int x, y, z;
int id; int id;
@ -29,16 +29,16 @@ walk_chunk(RenderState *state, RenderPrimitiveNether *data) {
for (z = -1; z < DEPTH + 1; z++) { for (z = -1; z < DEPTH + 1; z++) {
id = get_data(state, BLOCKS, x, NETHER_ROOF - (state->chunky * 16), z); id = get_data(state, BLOCKS, x, NETHER_ROOF - (state->chunky * 16), z);
if (id == block_bedrock) { if (id == block_bedrock) {
data->remove_block[x+1][NETHER_ROOF][z+1] = 1; data->remove_block[x + 1][NETHER_ROOF][z + 1] = 1;
id = get_data(state, BLOCKS, x, (NETHER_ROOF + 1) - (state->chunky * 16), z); id = get_data(state, BLOCKS, x, (NETHER_ROOF + 1) - (state->chunky * 16), z);
if (id == block_brown_mushroom || id == block_red_mushroom) if (id == block_brown_mushroom || id == block_red_mushroom)
data->remove_block[x+1][NETHER_ROOF + 1][z+1] = 1; data->remove_block[x + 1][NETHER_ROOF + 1][z + 1] = 1;
} }
for (y = NETHER_ROOF-1; y>=0; y--) { for (y = NETHER_ROOF - 1; y >= 0; y--) {
id = get_data(state, BLOCKS, x, y - (state->chunky * 16), z); id = get_data(state, BLOCKS, x, y - (state->chunky * 16), z);
if (block_class_is_subset(id, (mc_block_t[]){block_bedrock,block_netherrack,block_quartz_ore,block_lava}, 4)) if (block_class_is_subset(id, (mc_block_t[]){block_bedrock, block_netherrack, block_quartz_ore, block_lava}, 4))
data->remove_block[x+1][y][z+1] = 1; data->remove_block[x + 1][y][z + 1] = 1;
else else
break; break;
} }
@ -48,21 +48,22 @@ walk_chunk(RenderState *state, RenderPrimitiveNether *data) {
} }
static int static int
nether_hidden(void *data, RenderState *state, int x, int y, int z) { nether_hidden(void* data, RenderState* state, int x, int y, int z) {
RenderPrimitiveNether* self; RenderPrimitiveNether* self;
int real_y; int real_y;
self = (RenderPrimitiveNether *)data; self = (RenderPrimitiveNether*)data;
if (!(self->walked_chunk)) if (!(self->walked_chunk))
walk_chunk(state, self); walk_chunk(state, self);
real_y = y + (state->chunky * 16); real_y = y + (state->chunky * 16);
return self->remove_block[x+1][real_y][z+1]; return self->remove_block[x + 1][real_y][z + 1];
} }
RenderPrimitiveInterface primitive_nether = { RenderPrimitiveInterface primitive_nether = {
"nether", sizeof(RenderPrimitiveNether), "nether",
sizeof(RenderPrimitiveNether),
NULL, NULL,
NULL, NULL,
NULL, NULL,

View File

@ -27,6 +27,6 @@
typedef struct { typedef struct {
int walked_chunk; int walked_chunk;
int remove_block[WIDTH+2][HEIGHT][DEPTH+2]; int remove_block[WIDTH + 2][HEIGHT][DEPTH + 2];
} RenderPrimitiveNether; } RenderPrimitiveNether;

View File

@ -18,15 +18,14 @@
#include "../overviewer.h" #include "../overviewer.h"
static int static int
netherold_hidden(void *data, RenderState *state, int x, int y, int z) { netherold_hidden(void* data, RenderState* state, int x, int y, int z) {
/* hide all blocks above all air blocks /* hide all blocks above all air blocks
due to how the nether is currently generated, this will also count due to how the nether is currently generated, this will also count
empty sections as 'solid' empty sections as 'solid'
*/ */
unsigned char missing_section = 0; unsigned char missing_section = 0;
while (y < (SECTIONS_PER_CHUNK - state->chunky) * 16) while (y < (SECTIONS_PER_CHUNK - state->chunky) * 16) {
{
if (state->chunks[1][1].sections[state->chunky + (y / 16)].blocks == NULL) { if (state->chunks[1][1].sections[state->chunky + (y / 16)].blocks == NULL) {
missing_section = 1; missing_section = 1;
y += 16; y += 16;
@ -38,18 +37,18 @@ netherold_hidden(void *data, RenderState *state, int x, int y, int z) {
return 0; return 0;
missing_section = 0; missing_section = 0;
} }
if (!missing_section && get_data(state, BLOCKS, x, y, z) == 0) if (!missing_section && get_data(state, BLOCKS, x, y, z) == 0) {
{ return 0;
return 0; }
}
y++; y++;
} }
return 1; return 1;
} }
RenderPrimitiveInterface primitive_nether_old = { RenderPrimitiveInterface primitive_nether_old = {
"netherold", 0, "netherold",
0,
NULL, NULL,
NULL, NULL,
NULL, NULL,

View File

@ -18,17 +18,18 @@
#include "../overviewer.h" #include "../overviewer.h"
static int static int
no_fluids_start(void *data, RenderState *state, PyObject *support) { no_fluids_start(void* data, RenderState* state, PyObject* support) {
return 0; return 0;
} }
static int static int
no_fluids_hidden(void *data, RenderState *state, int x, int y, int z) { no_fluids_hidden(void* data, RenderState* state, int x, int y, int z) {
return block_has_property(state->block, FLUID); return block_has_property(state->block, FLUID);
} }
RenderPrimitiveInterface primitive_no_fluids = { RenderPrimitiveInterface primitive_no_fluids = {
"no-fluids", 0, "no-fluids",
0,
no_fluids_start, no_fluids_start,
NULL, NULL,
NULL, NULL,

View File

@ -15,14 +15,14 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "overlay.h"
#include "biomes.h" #include "biomes.h"
#include "overlay.h"
typedef struct { typedef struct {
/* inherits from overlay */ /* inherits from overlay */
RenderPrimitiveOverlay parent; RenderPrimitiveOverlay parent;
void *biomes; void* biomes;
} RenderPrimitiveBiomes; } RenderPrimitiveBiomes;
struct BiomeColor { struct BiomeColor {
@ -31,65 +31,64 @@ struct BiomeColor {
}; };
static struct BiomeColor default_biomes[] = { static struct BiomeColor default_biomes[] = {
{0, 135, 106, 150}, /* Ocean */ {0, 135, 106, 150}, /* Ocean */
{1, 98, 238, 240}, /* Plains */ {1, 98, 238, 240}, /* Plains */
{2, 227, 107, 0}, /* Desert */ {2, 227, 107, 0}, /* Desert */
{3, 255, 55, 55}, /* Extreme Hills */ {3, 255, 55, 55}, /* Extreme Hills */
{4, 10, 200, 200}, /* Forest */ {4, 10, 200, 200}, /* Forest */
{5, 10, 100, 240}, /* Taiga */ {5, 10, 100, 240}, /* Taiga */
{6, 200, 100, 100}, /* Swampland */ {6, 200, 100, 100}, /* Swampland */
{7, 70, 170, 0}, /* River */ {7, 70, 170, 0}, /* River */
{8, 255, 0, 0}, /* Hell */ {8, 255, 0, 0}, /* Hell */
{9, 255, 255, 255}, /* Sky */ {9, 255, 255, 255}, /* Sky */
{10, 155, 55, 255}, /* FrozenOcean */ {10, 155, 55, 255}, /* FrozenOcean */
{11, 255, 55, 255}, /* FrozenRiver */ {11, 255, 55, 255}, /* FrozenRiver */
{12, 155, 255, 255}, /* Ice Plains */ {12, 155, 255, 255}, /* Ice Plains */
{13, 205, 205, 255}, /* Ice Mountains */ {13, 205, 205, 255}, /* Ice Mountains */
{14, 255, 0, 155}, /* MushroomIsland */ {14, 255, 0, 155}, /* MushroomIsland */
{15, 255, 75, 175}, /* MushroomIslandShore */ {15, 255, 75, 175}, /* MushroomIslandShore */
{16, 255, 255, 0}, /* Beach */ {16, 255, 255, 0}, /* Beach */
{17, 240, 155, 0}, /* DesertHills */ {17, 240, 155, 0}, /* DesertHills */
{18, 100, 200, 200}, /* ForestHills */ {18, 100, 200, 200}, /* ForestHills */
{19, 100, 100, 240}, /* TaigaHills */ {19, 100, 100, 240}, /* TaigaHills */
{20, 255, 25, 15}, /* Extreme Hills Edge */ {20, 255, 25, 15}, /* Extreme Hills Edge */
{21, 155, 155, 55}, /* Jungle */ {21, 155, 155, 55}, /* Jungle */
{22, 175, 255, 55}, /* Jungle Hills */ {22, 175, 255, 55}, /* Jungle Hills */
{23, 135, 255, 55}, /* Jungle Edge */ {23, 135, 255, 55}, /* Jungle Edge */
{24, 135, 106, 150}, /* Deep Ocean */ {24, 135, 106, 150}, /* Deep Ocean */
{25, 255, 25, 15}, /* Stone Beach */ {25, 255, 25, 15}, /* Stone Beach */
{26, 155, 255, 255}, /* Cold Beach */ {26, 155, 255, 255}, /* Cold Beach */
{27, 10, 200, 200}, /* Birch Forest */ {27, 10, 200, 200}, /* Birch Forest */
{28, 10, 200, 200}, /* Birch Forest Edge */ {28, 10, 200, 200}, /* Birch Forest Edge */
{29, 10, 200, 200}, /* Roofed Forest */ {29, 10, 200, 200}, /* Roofed Forest */
{30, 155, 255, 255}, /* Cold Taiga */ {30, 155, 255, 255}, /* Cold Taiga */
{31, 155, 200, 255}, /* Cold Taiga Hills */ {31, 155, 200, 255}, /* Cold Taiga Hills */
{32, 10, 100, 240}, /* Mega Taiga */ {32, 10, 100, 240}, /* Mega Taiga */
{33, 10, 100, 240}, /* Mega Taiga Hills*/ {33, 10, 100, 240}, /* Mega Taiga Hills*/
{34, 255, 55, 55}, /* Extreme Hills+ */ {34, 255, 55, 55}, /* Extreme Hills+ */
{35, 227, 107, 0}, /* Savanna */ {35, 227, 107, 0}, /* Savanna */
{36, 227, 107, 0}, /* Savanna Plateau */ {36, 227, 107, 0}, /* Savanna Plateau */
{37, 255, 100, 100}, /* Mesa */ {37, 255, 100, 100}, /* Mesa */
{38, 255, 100, 100}, /* Mesa Plateau F */ {38, 255, 100, 100}, /* Mesa Plateau F */
{39, 255, 100, 100}, /* Mesa Plateau */ {39, 255, 100, 100}, /* Mesa Plateau */
/* end of list marker */ /* end of list marker */
{255, 0, 0, 0} {255, 0, 0, 0}};
};
static void get_color(void *data, RenderState *state, static void get_color(void* data, RenderState* state,
unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) { unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a) {
unsigned char biome; unsigned char biome;
int x = state->x, z = state->z, y_max, y; int x = state->x, z = state->z, y_max, y;
int max_i = -1; int max_i = -1;
RenderPrimitiveBiomes* self = (RenderPrimitiveBiomes *)data; RenderPrimitiveBiomes* self = (RenderPrimitiveBiomes*)data;
struct BiomeColor *biomes = (struct BiomeColor *)(self->biomes); struct BiomeColor* biomes = (struct BiomeColor*)(self->biomes);
*a = 0; *a = 0;
y_max = state->y + 1; y_max = state->y + 1;
for (y = state->chunky * -16; y <= y_max; y++) { for (y = state->chunky * -16; y <= y_max; y++) {
int i, tmp; int i, tmp;
biome = get_data(state, BIOMES, x, y, z); biome = get_data(state, BIOMES, x, y, z);
if (biome >= NUM_BIOMES) { if (biome >= NUM_BIOMES) {
biome = DEFAULT_BIOME; biome = DEFAULT_BIOME;
@ -97,7 +96,7 @@ static void get_color(void *data, RenderState *state,
for (i = 0; (max_i == -1 || i < max_i) && biomes[i].biome != 255; i++) { for (i = 0; (max_i == -1 || i < max_i) && biomes[i].biome != 255; i++) {
if (biomes[i].biome == biome) { if (biomes[i].biome == biome) {
//printf("(%d, %d, %d), %d, %s\n", x, y, z, biomes[i].biome, biome_table[biomes[i].biome].name); //printf("(%d, %d, %d), %d, %s\n", x, y, z, biomes[i].biome, biome_table[biomes[i].biome].name);
*r = biomes[i].r; *r = biomes[i].r;
*g = biomes[i].g; *g = biomes[i].g;
*b = biomes[i].b; *b = biomes[i].b;
@ -112,10 +111,10 @@ static void get_color(void *data, RenderState *state,
} }
static int static int
overlay_biomes_start(void *data, RenderState *state, PyObject *support) { overlay_biomes_start(void* data, RenderState* state, PyObject* support) {
PyObject *opt; PyObject* opt;
RenderPrimitiveBiomes* self; RenderPrimitiveBiomes* self;
unsigned char alpha_tmp=0; unsigned char alpha_tmp = 0;
/* first, chain up */ /* first, chain up */
int ret = primitive_overlay.start(data, state, support); int ret = primitive_overlay.start(data, state, support);
@ -123,13 +122,13 @@ overlay_biomes_start(void *data, RenderState *state, PyObject *support) {
return ret; return ret;
/* now do custom initializations */ /* now do custom initializations */
self = (RenderPrimitiveBiomes *)data; self = (RenderPrimitiveBiomes*)data;
// opt is a borrowed reference. do not deref // opt is a borrowed reference. do not deref
if (!render_mode_parse_option(support, "biomes", "O", &(opt))) if (!render_mode_parse_option(support, "biomes", "O", &(opt)))
return 1; return 1;
if (opt && opt != Py_None) { if (opt && opt != Py_None) {
struct BiomeColor *biomes = NULL; struct BiomeColor* biomes = NULL;
Py_ssize_t biomes_size = 0, i; Py_ssize_t biomes_size = 0, i;
/* create custom biomes */ /* create custom biomes */
@ -145,8 +144,8 @@ overlay_biomes_start(void *data, RenderState *state, PyObject *support) {
} }
for (i = 0; i < biomes_size; i++) { for (i = 0; i < biomes_size; i++) {
PyObject *biome = PyList_GET_ITEM(opt, i); PyObject* biome = PyList_GET_ITEM(opt, i);
char *tmpname = NULL; char* tmpname = NULL;
int j = 0; int j = 0;
if (!PyArg_ParseTuple(biome, "s(bbb)", &tmpname, &(biomes[i].r), &(biomes[i].g), &(biomes[i].b))) { if (!PyArg_ParseTuple(biome, "s(bbb)", &tmpname, &(biomes[i].r), &(biomes[i].g), &(biomes[i].b))) {
@ -157,15 +156,15 @@ overlay_biomes_start(void *data, RenderState *state, PyObject *support) {
//printf("%s, (%d, %d, %d) ->", tmpname, biomes[i].r, biomes[i].g, biomes[i].b); //printf("%s, (%d, %d, %d) ->", tmpname, biomes[i].r, biomes[i].g, biomes[i].b);
for (j = 0; j < NUM_BIOMES; j++) { for (j = 0; j < NUM_BIOMES; j++) {
if (strncmp(biome_table[j].name, tmpname, strlen(tmpname))==0) { if (strncmp(biome_table[j].name, tmpname, strlen(tmpname)) == 0) {
//printf("biome_table index=%d", j); //printf("biome_table index=%d", j);
biomes[i].biome = j; biomes[i].biome = j;
break; break;
} }
} }
//printf("\n"); //printf("\n");
} }
biomes[biomes_size].biome = 255; //Because 0 is a valid biome, have to use 255 as the end of list marker instead. Fragile! biomes[biomes_size].biome = 255; //Because 0 is a valid biome, have to use 255 as the end of list marker instead. Fragile!
} else { } else {
self->biomes = default_biomes; self->biomes = default_biomes;
@ -174,10 +173,10 @@ overlay_biomes_start(void *data, RenderState *state, PyObject *support) {
if (!render_mode_parse_option(support, "alpha", "b", &(alpha_tmp))) { if (!render_mode_parse_option(support, "alpha", "b", &(alpha_tmp))) {
if (PyErr_Occurred()) { if (PyErr_Occurred()) {
PyErr_Clear(); PyErr_Clear();
alpha_tmp = 240; alpha_tmp = 240;
} }
self->parent.color->a = alpha_tmp; self->parent.color->a = alpha_tmp;
} }
/* setup custom color */ /* setup custom color */
self->parent.get_color = get_color; self->parent.get_color = get_color;
@ -186,9 +185,9 @@ overlay_biomes_start(void *data, RenderState *state, PyObject *support) {
} }
static void static void
overlay_biomes_finish(void *data, RenderState *state) { overlay_biomes_finish(void* data, RenderState* state) {
/* first free all *our* stuff */ /* first free all *our* stuff */
RenderPrimitiveBiomes* self = (RenderPrimitiveBiomes *)data; RenderPrimitiveBiomes* self = (RenderPrimitiveBiomes*)data;
if (self->biomes && self->biomes != default_biomes) { if (self->biomes && self->biomes != default_biomes) {
free(self->biomes); free(self->biomes);

View File

@ -15,14 +15,14 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "overlay.h"
#include "../mc_id.h" #include "../mc_id.h"
#include "overlay.h"
typedef struct { typedef struct {
/* inherits from overlay */ /* inherits from overlay */
RenderPrimitiveOverlay parent; RenderPrimitiveOverlay parent;
void *minerals; void* minerals;
} RenderPrimitiveMineral; } RenderPrimitiveMineral;
struct MineralColor { struct MineralColor {
@ -33,7 +33,7 @@ struct MineralColor {
/* put more valuable ores first -- they take precedence */ /* put more valuable ores first -- they take precedence */
static struct MineralColor default_minerals[] = { static struct MineralColor default_minerals[] = {
{block_mossy_cobblestone, 31, 153, 9}, {block_mossy_cobblestone, 31, 153, 9},
{block_diamond_ore, 32, 230, 220}, {block_diamond_ore, 32, 230, 220},
{block_lapis_ore, 0, 23, 176}, {block_lapis_ore, 0, 23, 176},
@ -43,34 +43,33 @@ static struct MineralColor default_minerals[] = {
{block_redstone_ore, 186, 0, 0}, {block_redstone_ore, 186, 0, 0},
{block_lit_redstone_ore, 186, 0, 0}, {block_lit_redstone_ore, 186, 0, 0},
{block_coal_ore, 54, 54, 54}, {block_coal_ore, 54, 54, 54},
/* end of list marker */
{0, 0, 0, 0}
};
static void get_color(void *data, RenderState *state, /* end of list marker */
unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) { {0, 0, 0, 0}};
static void get_color(void* data, RenderState* state,
unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a) {
int x = state->x, z = state->z, y_max, y; int x = state->x, z = state->z, y_max, y;
int max_i = -1; int max_i = -1;
RenderPrimitiveMineral* self = (RenderPrimitiveMineral *)data; RenderPrimitiveMineral* self = (RenderPrimitiveMineral*)data;
struct MineralColor *minerals = (struct MineralColor *)(self->minerals); struct MineralColor* minerals = (struct MineralColor*)(self->minerals);
*a = 0; *a = 0;
y_max = state->y + 1; y_max = state->y + 1;
for (y = state->chunky * -16; y <= y_max; y++) { for (y = state->chunky * -16; y <= y_max; y++) {
int i, tmp; int i, tmp;
unsigned short blockid = get_data(state, BLOCKS, x, y, z); unsigned short blockid = get_data(state, BLOCKS, x, y, z);
for (i = 0; (max_i == -1 || i < max_i) && minerals[i].blockid != block_air; i++) { for (i = 0; (max_i == -1 || i < max_i) && minerals[i].blockid != block_air; i++) {
if (minerals[i].blockid == blockid) { if (minerals[i].blockid == blockid) {
*r = minerals[i].r; *r = minerals[i].r;
*g = minerals[i].g; *g = minerals[i].g;
*b = minerals[i].b; *b = minerals[i].b;
tmp = (128 - y_max + y) * 2 - 40; tmp = (128 - y_max + y) * 2 - 40;
*a = OV_MIN(OV_MAX(0, tmp), 255); *a = OV_MIN(OV_MAX(0, tmp), 255);
max_i = i; max_i = i;
break; break;
} }
@ -79,39 +78,39 @@ static void get_color(void *data, RenderState *state,
} }
static int static int
overlay_mineral_start(void *data, RenderState *state, PyObject *support) { overlay_mineral_start(void* data, RenderState* state, PyObject* support) {
PyObject *opt; PyObject* opt;
RenderPrimitiveMineral* self; RenderPrimitiveMineral* self;
/* first, chain up */ /* first, chain up */
int ret = primitive_overlay.start(data, state, support); int ret = primitive_overlay.start(data, state, support);
if (ret != 0) if (ret != 0)
return ret; return ret;
/* now do custom initializations */ /* now do custom initializations */
self = (RenderPrimitiveMineral *)data; self = (RenderPrimitiveMineral*)data;
// opt is a borrowed reference. do not deref // opt is a borrowed reference. do not deref
if (!render_mode_parse_option(support, "minerals", "O", &(opt))) if (!render_mode_parse_option(support, "minerals", "O", &(opt)))
return 1; return 1;
if (opt && opt != Py_None) { if (opt && opt != Py_None) {
struct MineralColor *minerals = NULL; struct MineralColor* minerals = NULL;
Py_ssize_t minerals_size = 0, i; Py_ssize_t minerals_size = 0, i;
/* create custom minerals */ /* create custom minerals */
if (!PyList_Check(opt)) { if (!PyList_Check(opt)) {
PyErr_SetString(PyExc_TypeError, "'minerals' must be a list"); PyErr_SetString(PyExc_TypeError, "'minerals' must be a list");
return 1; return 1;
} }
minerals_size = PyList_GET_SIZE(opt); minerals_size = PyList_GET_SIZE(opt);
minerals = self->minerals = calloc(minerals_size + 1, sizeof(struct MineralColor)); minerals = self->minerals = calloc(minerals_size + 1, sizeof(struct MineralColor));
if (minerals == NULL) { if (minerals == NULL) {
return 1; return 1;
} }
for (i = 0; i < minerals_size; i++) { for (i = 0; i < minerals_size; i++) {
PyObject *mineral = PyList_GET_ITEM(opt, i); PyObject* mineral = PyList_GET_ITEM(opt, i);
if (!PyArg_ParseTuple(mineral, "b(bbb)", &(minerals[i].blockid), &(minerals[i].r), &(minerals[i].g), &(minerals[i].b))) { if (!PyArg_ParseTuple(mineral, "b(bbb)", &(minerals[i].blockid), &(minerals[i].r), &(minerals[i].g), &(minerals[i].b))) {
free(minerals); free(minerals);
self->minerals = NULL; self->minerals = NULL;
@ -121,22 +120,22 @@ overlay_mineral_start(void *data, RenderState *state, PyObject *support) {
} else { } else {
self->minerals = default_minerals; self->minerals = default_minerals;
} }
/* setup custom color */ /* setup custom color */
self->parent.get_color = get_color; self->parent.get_color = get_color;
return 0; return 0;
} }
static void static void
overlay_mineral_finish(void *data, RenderState *state) { overlay_mineral_finish(void* data, RenderState* state) {
/* first free all *our* stuff */ /* first free all *our* stuff */
RenderPrimitiveMineral* self = (RenderPrimitiveMineral *)data; RenderPrimitiveMineral* self = (RenderPrimitiveMineral*)data;
if (self->minerals && self->minerals != default_minerals) { if (self->minerals && self->minerals != default_minerals) {
free(self->minerals); free(self->minerals);
} }
/* now, chain up */ /* now, chain up */
primitive_overlay.finish(data, state); primitive_overlay.finish(data, state);
} }

View File

@ -15,8 +15,8 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "overlay.h"
#include <math.h> #include <math.h>
#include "overlay.h"
typedef struct { typedef struct {
/* inherits from overlay */ /* inherits from overlay */
@ -30,28 +30,28 @@ typedef struct {
* http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Random.html * http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Random.html
*/ */
static void random_set_seed(long long *seed, long long new_seed) { static void random_set_seed(long long* seed, long long new_seed) {
*seed = (new_seed ^ 0x5deece66dLL) & ((1LL << 48) - 1); *seed = (new_seed ^ 0x5deece66dLL) & ((1LL << 48) - 1);
} }
static int random_next(long long *seed, int bits) { static int random_next(long long* seed, int bits) {
*seed = (*seed * 0x5deece66dLL + 0xbL) & ((1LL << 48) - 1); *seed = (*seed * 0x5deece66dLL + 0xbL) & ((1LL << 48) - 1);
return (int)(*seed >> (48 - bits)); return (int)(*seed >> (48 - bits));
} }
static int random_next_int(long long *seed, int n) { static int random_next_int(long long* seed, int n) {
int bits, val; int bits, val;
if (n <= 0) { if (n <= 0) {
/* invalid */ /* invalid */
return 0; return 0;
} }
if ((n & -n) == n) { if ((n & -n) == n) {
/* n is a power of two */ /* n is a power of two */
return (int)((n * (long long)random_next(seed, 31)) >> 31); return (int)((n * (long long)random_next(seed, 31)) >> 31);
} }
do { do {
bits = random_next(seed, 31); bits = random_next(seed, 31);
val = bits % n; val = bits % n;
@ -66,14 +66,15 @@ static int is_slime(long long map_seed, int chunkx, int chunkz) {
(long long)(chunkx * chunkx * 0x4c1906) + (long long)(chunkx * chunkx * 0x4c1906) +
(long long)(chunkx * 0x5ac0db) + (long long)(chunkx * 0x5ac0db) +
(long long)(chunkz * chunkz * 0x4307a7LL) + (long long)(chunkz * chunkz * 0x4307a7LL) +
(long long)(chunkz * 0x5f24f)) ^ 0x3ad8025f); (long long)(chunkz * 0x5f24f)) ^
0x3ad8025f);
return (random_next_int(&seed, 10) == 0); return (random_next_int(&seed, 10) == 0);
} }
static void get_color(void *data, RenderState *state, static void get_color(void* data, RenderState* state,
unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) { unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a) {
RenderPrimitiveSlime *self = (RenderPrimitiveSlime *)data; RenderPrimitiveSlime* self = (RenderPrimitiveSlime*)data;
/* set a nice, pretty green color */ /* set a nice, pretty green color */
*r = self->parent.color->r; *r = self->parent.color->r;
*g = self->parent.color->g; *g = self->parent.color->g;
@ -81,7 +82,7 @@ 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;
if (is_slime(self->seed, state->chunkx, state->chunkz)) { if (is_slime(self->seed, state->chunkx, state->chunkz)) {
/* slimes can spawn! */ /* slimes can spawn! */
*a = self->parent.color->a; *a = self->parent.color->a;
@ -89,24 +90,24 @@ static void get_color(void *data, RenderState *state,
} }
static int static int
overlay_slime_start(void *data, RenderState *state, PyObject *support) { overlay_slime_start(void* data, RenderState* state, PyObject* support) {
RenderPrimitiveSlime *self; RenderPrimitiveSlime* self;
PyObject *pyseed; PyObject* pyseed;
/* first, chain up */ /* first, chain up */
int ret = primitive_overlay.start(data, state, support); int ret = primitive_overlay.start(data, state, support);
if (ret != 0) if (ret != 0)
return ret; return ret;
/* now do custom initializations */ /* now do custom initializations */
self = (RenderPrimitiveSlime *)data; self = (RenderPrimitiveSlime*)data;
self->parent.get_color = get_color; self->parent.get_color = get_color;
self->parent.default_color.r = 40; self->parent.default_color.r = 40;
self->parent.default_color.g = 230; self->parent.default_color.g = 230;
self->parent.default_color.b = 40; self->parent.default_color.b = 40;
self->parent.default_color.a = 240; self->parent.default_color.a = 240;
pyseed = PyObject_GetAttrString(state->world, "seed"); pyseed = PyObject_GetAttrString(state->world, "seed");
if (!pyseed) if (!pyseed)
return 1; return 1;
@ -114,12 +115,12 @@ overlay_slime_start(void *data, RenderState *state, PyObject *support) {
Py_DECREF(pyseed); Py_DECREF(pyseed);
if (PyErr_Occurred()) if (PyErr_Occurred())
return 1; return 1;
return 0; return 0;
} }
static void static void
overlay_slime_finish(void *data, RenderState *state) { overlay_slime_finish(void* data, RenderState* state) {
/* chain up */ /* chain up */
primitive_overlay.finish(data, state); primitive_overlay.finish(data, state);
} }

View File

@ -15,37 +15,37 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "overlay.h"
#include <math.h> #include <math.h>
#include "overlay.h"
typedef struct { typedef struct {
/* inherits from overlay */ /* inherits from overlay */
RenderPrimitiveOverlay parent; RenderPrimitiveOverlay parent;
} RenderPrimitiveSpawn; } RenderPrimitiveSpawn;
static void get_color(void *data, RenderState *state, static void get_color(void* data, RenderState* state,
unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) { unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a) {
RenderPrimitiveSpawn* self = (RenderPrimitiveSpawn *)data; RenderPrimitiveSpawn* self = (RenderPrimitiveSpawn*)data;
int x = state->x, y = state->y, z = state->z; int x = state->x, y = state->y, z = state->z;
int y_light = y + 1; int y_light = y + 1;
unsigned char blocklight, skylight; unsigned char blocklight, skylight;
/* set a nice, pretty red color */ /* set a nice, pretty red color */
*r = self->parent.color->r; *r = self->parent.color->r;
*g = self->parent.color->g; *g = self->parent.color->g;
*b = self->parent.color->b; *b = self->parent.color->b;
/* default to no overlay, until told otherwise */ /* default to no overlay, until told otherwise */
*a = 0; *a = 0;
if (block_has_property(state->block, NOSPAWN)) { if (block_has_property(state->block, NOSPAWN)) {
/* nothing can spawn on this */ /* nothing can spawn on this */
return; return;
} }
blocklight = get_data(state, BLOCKLIGHT, x, y_light, z); blocklight = get_data(state, BLOCKLIGHT, x, y_light, z);
skylight = get_data(state, SKYLIGHT, x, y_light, z); skylight = get_data(state, SKYLIGHT, x, y_light, z);
if (OV_MAX(blocklight, skylight) <= 7) { if (OV_MAX(blocklight, skylight) <= 7) {
/* hostile mobs spawn in daylight */ /* hostile mobs spawn in daylight */
*a = 240; *a = 240;
@ -56,28 +56,28 @@ static void get_color(void *data, RenderState *state,
} }
static int static int
overlay_spawn_start(void *data, RenderState *state, PyObject *support) { overlay_spawn_start(void* data, RenderState* state, PyObject* support) {
RenderPrimitiveSpawn* self; RenderPrimitiveSpawn* self;
/* first, chain up */ /* first, chain up */
int ret = primitive_overlay.start(data, state, support); int ret = primitive_overlay.start(data, state, support);
if (ret != 0) if (ret != 0)
return ret; return ret;
/* now do custom initializations */ /* now do custom initializations */
self = (RenderPrimitiveSpawn *)data; self = (RenderPrimitiveSpawn*)data;
self->parent.get_color = get_color; self->parent.get_color = get_color;
self->parent.default_color.r = 229; self->parent.default_color.r = 229;
self->parent.default_color.g = 36; self->parent.default_color.g = 36;
self->parent.default_color.b = 38; self->parent.default_color.b = 38;
self->parent.default_color.a = 0; self->parent.default_color.a = 0;
return 0; return 0;
} }
static void static void
overlay_spawn_finish(void *data, RenderState *state) { overlay_spawn_finish(void* data, RenderState* state) {
/* chain up */ /* chain up */
primitive_overlay.finish(data, state); primitive_overlay.finish(data, state);
} }

View File

@ -15,42 +15,43 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "overlay.h"
#include "../mc_id.h" #include "../mc_id.h"
#include "overlay.h"
typedef enum { false, true } bool; typedef enum { false,
true } bool;
typedef struct { typedef struct {
/* inherits from overlay */ /* inherits from overlay */
RenderPrimitiveOverlay parent; RenderPrimitiveOverlay parent;
void *structures; void* structures;
int numcolors; int numcolors;
} RenderPrimitiveStructure; } RenderPrimitiveStructure;
struct Condition{ struct Condition {
int relx, rely, relz; int relx, rely, relz;
unsigned short block; unsigned short block;
}; };
struct Color { struct Color {
int numconds; int numconds;
struct Condition *conditions; struct Condition* conditions;
unsigned char r, g, b, a; unsigned char r, g, b, a;
}; };
static void get_color(void *data, static void get_color(void* data,
RenderState *state, RenderState* state,
unsigned char *r, unsigned char* r,
unsigned char *g, unsigned char* g,
unsigned char *b, unsigned char* b,
unsigned char *a) { unsigned char* a) {
/** /**
* Calculate the color at the current position and store the values to r,g,b,a. * Calculate the color at the current position and store the values to r,g,b,a.
**/ **/
RenderPrimitiveStructure *self = (RenderPrimitiveStructure *)data; RenderPrimitiveStructure* self = (RenderPrimitiveStructure*)data;
int x = state->x, z = state->z, y_max, y, col, cond; int x = state->x, z = state->z, y_max, y, col, cond;
struct Color *structures = (struct Color *)(self->structures); struct Color* structures = (struct Color*)(self->structures);
struct Condition * c = NULL; struct Condition* c = NULL;
bool all = true; bool all = true;
y_max = state->y + 1; y_max = state->y + 1;
@ -59,20 +60,20 @@ static void get_color(void *data,
* If all conditions are met for one y level set r,b,g,a accordingly. * If all conditions are met for one y level set r,b,g,a accordingly.
**/ **/
// iterate over all the colors // iterate over all the colors
for ( col = 0; col < self->numcolors; col++) { for (col = 0; col < self->numcolors; col++) {
// iterate over all y levels // iterate over all y levels
for (y = state->chunky * -16; y <= y_max; y++) { for (y = state->chunky * -16; y <= y_max; y++) {
// iterate over all the conditions // iterate over all the conditions
for (cond = 0; cond < structures[col].numconds; cond++) { for (cond = 0; cond < structures[col].numconds; cond++) {
all = true; all = true;
c = (struct Condition *)&structures[col].conditions[cond]; c = (struct Condition*)&structures[col].conditions[cond];
// check if the condition does apply and break from the conditions loop if not. // check if the condition does apply and break from the conditions loop if not.
if(!(c->block == get_data(state, BLOCKS, x+c->relx, y+c->rely, z+c->relz))) { if (!(c->block == get_data(state, BLOCKS, x + c->relx, y + c->rely, z + c->relz))) {
all = false; all = false;
break; break;
} }
} }
if (all){ if (all) {
// set the color // set the color
*r = structures[col].r; *r = structures[col].r;
*g = structures[col].g; *g = structures[col].g;
@ -85,12 +86,12 @@ static void get_color(void *data,
return; return;
} }
static int overlay_structure_start(void *data, RenderState *state, PyObject *support) { static int overlay_structure_start(void* data, RenderState* state, PyObject* support) {
/** /**
* Initializing the search for structures by parsing the arguments and storing them into * Initializing the search for structures by parsing the arguments and storing them into
* appropriate structures. If no arguments are passed create and use default values. * appropriate structures. If no arguments are passed create and use default values.
**/ **/
PyObject *opt; PyObject* opt;
RenderPrimitiveStructure* self; RenderPrimitiveStructure* self;
/* first, chain up */ /* first, chain up */
@ -99,7 +100,7 @@ static int overlay_structure_start(void *data, RenderState *state, PyObject *sup
return ret; return ret;
/* now do custom initializations */ /* now do custom initializations */
self = (RenderPrimitiveStructure *)data; self = (RenderPrimitiveStructure*)data;
// opt is a borrowed reference. do not deref // opt is a borrowed reference. do not deref
// store the structures python object into opt. // store the structures python object into opt.
@ -110,8 +111,8 @@ static int overlay_structure_start(void *data, RenderState *state, PyObject *sup
* Check if a sane option was passed. * Check if a sane option was passed.
**/ **/
if (opt && opt != Py_None) { if (opt && opt != Py_None) {
struct Color *structures = NULL; struct Color* structures = NULL;
struct Condition *cond = NULL; struct Condition* cond = NULL;
Py_ssize_t structures_size = 0, i, cond_size = 0, n = 0; Py_ssize_t structures_size = 0, i, cond_size = 0, n = 0;
bool cont = true; bool cont = true;
@ -135,11 +136,11 @@ static int overlay_structure_start(void *data, RenderState *state, PyObject *sup
**/ **/
if (cont) { if (cont) {
for (i = 0; i < structures_size; i++) { for (i = 0; i < structures_size; i++) {
PyObject *structure = PyList_GET_ITEM(opt, i); PyObject* structure = PyList_GET_ITEM(opt, i);
// condspy holding the conditions tuple of variable length (python object) // condspy holding the conditions tuple of variable length (python object)
PyObject *condspy; PyObject* condspy;
// colorpy holding the 4 tuple with r g b a values of the color // colorpy holding the 4 tuple with r g b a values of the color
PyObject *colorpy; PyObject* colorpy;
// getting the condspy and colorpy out of the structures. // getting the condspy and colorpy out of the structures.
if (!PyArg_ParseTuple(structure, "OO", &condspy, &colorpy)) { if (!PyArg_ParseTuple(structure, "OO", &condspy, &colorpy)) {
@ -150,11 +151,11 @@ static int overlay_structure_start(void *data, RenderState *state, PyObject *sup
} }
// Parse colorpy into a c-struct. // Parse colorpy into a c-struct.
if (!PyArg_ParseTuple( colorpy, "bbbb", if (!PyArg_ParseTuple(colorpy, "bbbb",
&structures[i].r, &structures[i].r,
&structures[i].g, &structures[i].g,
&structures[i].b, &structures[i].b,
&structures[i].a)) { &structures[i].a)) {
free(structures); free(structures);
self->structures = NULL; self->structures = NULL;
return 1; return 1;
@ -162,7 +163,7 @@ static int overlay_structure_start(void *data, RenderState *state, PyObject *sup
// Convert condspy to a fast sequence // Convert condspy to a fast sequence
condspy = PySequence_Fast(condspy, "Failed to parse conditions"); condspy = PySequence_Fast(condspy, "Failed to parse conditions");
if(condspy == NULL) { if (condspy == NULL) {
free(structures); free(structures);
self->structures = NULL; self->structures = NULL;
return 1; return 1;
@ -183,14 +184,14 @@ static int overlay_structure_start(void *data, RenderState *state, PyObject *sup
// iterate over all the conditions and read them. // iterate over all the conditions and read them.
for (n = 0; n < structures[i].numconds; n++) { for (n = 0; n < structures[i].numconds; n++) {
PyObject *ccond = PySequence_Fast_GET_ITEM(condspy, n); PyObject* ccond = PySequence_Fast_GET_ITEM(condspy, n);
if(!PyArg_ParseTuple( ccond, "iiib", if (!PyArg_ParseTuple(ccond, "iiib",
&cond[n].relx, &cond[n].relx,
&cond[n].rely, &cond[n].rely,
&cond[n].relz, &cond[n].relz,
&cond[n].block)){ &cond[n].block)) {
int x = 0; int x = 0;
for(x = 0; x < structures_size; x++){ for (x = 0; x < structures_size; x++) {
free(structures[x].conditions); free(structures[x].conditions);
} }
free(structures); free(structures);
@ -208,16 +209,16 @@ static int overlay_structure_start(void *data, RenderState *state, PyObject *sup
return 0; return 0;
} }
static void overlay_structure_finish(void *data, RenderState *state) { static void overlay_structure_finish(void* data, RenderState* state) {
/* first free all *our* stuff */ /* first free all *our* stuff */
RenderPrimitiveStructure* self = (RenderPrimitiveStructure *)data; RenderPrimitiveStructure* self = (RenderPrimitiveStructure*)data;
int i = 0; int i = 0;
if(self->structures) { if (self->structures) {
// freeing the nested structure // freeing the nested structure
struct Color * m = self->structures; struct Color* m = self->structures;
for(i = 0; i < self->numcolors; i++){ for (i = 0; i < self->numcolors; i++) {
if(m[i].conditions) if (m[i].conditions)
free(m[i].conditions); free(m[i].conditions);
} }
} }
@ -240,4 +241,3 @@ RenderPrimitiveInterface primitive_overlay_structure = {
NULL, NULL,
overlay_draw, overlay_draw,
}; };

View File

@ -18,9 +18,9 @@
#include "overlay.h" #include "overlay.h"
#include "../mc_id.h" #include "../mc_id.h"
static void get_color(void *data, RenderState *state, static void get_color(void* data, RenderState* state,
unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) { unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a) {
RenderPrimitiveOverlay* self = (RenderPrimitiveOverlay *)data; RenderPrimitiveOverlay* self = (RenderPrimitiveOverlay*)data;
*r = self->color->r; *r = self->color->r;
*g = self->color->g; *g = self->color->g;
@ -29,35 +29,35 @@ static void get_color(void *data, RenderState *state,
} }
static int static int
overlay_start(void *data, RenderState *state, PyObject *support) { overlay_start(void* data, RenderState* state, PyObject* support) {
PyObject *opt = NULL; PyObject* opt = NULL;
OverlayColor *color = NULL; OverlayColor* color = NULL;
RenderPrimitiveOverlay *self = (RenderPrimitiveOverlay *)data; RenderPrimitiveOverlay* self = (RenderPrimitiveOverlay*)data;
self->facemask_top = PyObject_GetAttrString(support, "facemask_top"); self->facemask_top = PyObject_GetAttrString(support, "facemask_top");
self->white_color = PyObject_GetAttrString(support, "whitecolor"); self->white_color = PyObject_GetAttrString(support, "whitecolor");
self->get_color = get_color; self->get_color = get_color;
color = self->color = calloc(1, sizeof(OverlayColor)); color = self->color = calloc(1, sizeof(OverlayColor));
if (color == NULL) { if (color == NULL) {
return 1; return 1;
} }
self->default_color.r = 200; self->default_color.r = 200;
self->default_color.g = 200; self->default_color.g = 200;
self->default_color.b = 255; self->default_color.b = 255;
self->default_color.a = 155; self->default_color.a = 155;
if(!render_mode_parse_option(support, "overlay_color", "bbbb", &(color->r), &(color->g), &(color->b), &(color->a))) { if (!render_mode_parse_option(support, "overlay_color", "bbbb", &(color->r), &(color->g), &(color->b), &(color->a))) {
if(PyErr_Occurred()) if (PyErr_Occurred())
PyErr_Clear(); PyErr_Clear();
free(color); free(color);
self->color = &self->default_color; self->color = &self->default_color;
// Check if it is None, if it is, continue and use the default, if it isn't, return an error // Check if it is None, if it is, continue and use the default, if it isn't, return an error
if(render_mode_parse_option(support, "overlay_color", "O", &(opt))) { if (render_mode_parse_option(support, "overlay_color", "O", &(opt))) {
// If it is an object, check to see if it is None, if it is, use the default. // If it is an object, check to see if it is None, if it is, use the default.
if(opt && opt != Py_None) { if (opt && opt != Py_None) {
return 1; return 1;
} }
} }
@ -67,56 +67,55 @@ overlay_start(void *data, RenderState *state, PyObject *support) {
} }
static void static void
overlay_finish(void *data, RenderState *state) { overlay_finish(void* data, RenderState* state) {
RenderPrimitiveOverlay *self = (RenderPrimitiveOverlay *)data; RenderPrimitiveOverlay* self = (RenderPrimitiveOverlay*)data;
if (self->color && self->color != &self->default_color) { if (self->color && self->color != &self->default_color) {
free(self->color); free(self->color);
} }
Py_DECREF(self->facemask_top); Py_DECREF(self->facemask_top);
Py_DECREF(self->white_color); Py_DECREF(self->white_color);
} }
void void overlay_draw(void* data, RenderState* state, PyObject* src, PyObject* mask, PyObject* mask_light) {
overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { RenderPrimitiveOverlay* self = (RenderPrimitiveOverlay*)data;
RenderPrimitiveOverlay *self = (RenderPrimitiveOverlay *)data;
unsigned char r, g, b, a; unsigned char r, g, b, a;
unsigned short top_block; unsigned short top_block;
// 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;
if (state->block == block_stone_slab) // half-step if (state->block == block_stone_slab) // half-step
increment=6; increment = 6;
else if (state->block == block_snow_layer) // snow else if (state->block == block_snow_layer) // snow
increment=9; increment = 9;
/* skip rendering the overlay if we can't see it */ /* skip rendering the overlay if we can't see it */
top_block = get_data(state, BLOCKS, state->x, state->y+1, state->z); top_block = get_data(state, BLOCKS, state->x, state->y + 1, state->z);
if (!is_transparent(top_block)) { if (!is_transparent(top_block)) {
return; return;
} }
/* check to be sure this block is solid/fluid */ /* check to be sure this block is solid/fluid */
if (block_has_property(top_block, SOLID) || block_has_property(top_block, FLUID)) { if (block_has_property(top_block, SOLID) || block_has_property(top_block, FLUID)) {
/* top block is fluid or solid, skip drawing */ /* top block is fluid or solid, skip drawing */
return; return;
} }
/* check to be sure this block is solid/fluid */ /* check to be sure this block is solid/fluid */
if (!block_has_property(state->block, SOLID) && !block_has_property(state->block, FLUID)) { if (!block_has_property(state->block, SOLID) && !block_has_property(state->block, FLUID)) {
/* not fluid or solid, skip drawing the overlay */ /* not fluid or solid, skip drawing the overlay */
return; return;
} }
/* 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);
/* do the overlay */ /* do the overlay */
if (a > 0) { if (a > 0) {
alpha_over_full(state->img, self->white_color, self->facemask_top, a/255.f, state->imgx, state->imgy + increment, 0, 0); alpha_over_full(state->img, self->white_color, self->facemask_top, a / 255.f, state->imgx, state->imgy + increment, 0, 0);
tint_with_mask(state->img, r, g, b, 255, self->facemask_top, state->imgx, state->imgy + increment, 0, 0); tint_with_mask(state->img, r, g, b, 255, self->facemask_top, state->imgx, state->imgy + increment, 0, 0);
} }
} }

View File

@ -27,14 +27,14 @@ typedef struct {
/* color will be a pointer to either the default_color object below or /* color will be a pointer to either the default_color object below or
to a specially allocated color object that is instantiated from the to a specially allocated color object that is instantiated from the
settings file */ settings file */
OverlayColor *color; OverlayColor* color;
OverlayColor default_color; OverlayColor default_color;
/* 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 */
void (*get_color)(void *, RenderState *, void (*get_color)(void*, RenderState*,
unsigned char *, unsigned char *, unsigned char *, unsigned char *); unsigned char*, unsigned char*, unsigned char*, unsigned char*);
} RenderPrimitiveOverlay; } RenderPrimitiveOverlay;
extern RenderPrimitiveInterface primitive_overlay; extern RenderPrimitiveInterface primitive_overlay;
void overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light); void overlay_draw(void* data, RenderState* state, PyObject* src, PyObject* mask, PyObject* mask_light);

View File

@ -15,11 +15,11 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "../overviewer.h"
#include "../mc_id.h"
#include "../block_class.h"
#include "lighting.h"
#include <math.h> #include <math.h>
#include "../block_class.h"
#include "../mc_id.h"
#include "../overviewer.h"
#include "lighting.h"
typedef struct { typedef struct {
/* inherits from lighting */ /* inherits from lighting */
@ -30,7 +30,7 @@ typedef struct {
struct SmoothLightingCorner { struct SmoothLightingCorner {
/* where this corner shows up on each block texture */ /* where this corner shows up on each block texture */
int imgx, imgy; int imgx, imgy;
/* the two block offsets that (together) determine the 4 blocks to use */ /* the two block offsets that (together) determine the 4 blocks to use */
int dx1, dy1, dz1; int dx1, dy1, dz1;
int dx2, dy2, dz2; int dx2, dy2, dz2;
@ -41,12 +41,12 @@ struct SmoothLightingFace {
/* offset from current coordinate to the block this face points towards /* offset from current coordinate to the block this face points towards
used for occlusion calculations, and as a base for later */ used for occlusion calculations, and as a base for later */
int dx, dy, dz; int dx, dy, dz;
/* the points that form the corners of this face */ /* the points that form the corners of this face */
struct SmoothLightingCorner corners[4]; struct SmoothLightingCorner corners[4];
/* pairs of (x,y) in order, as touch-up points, or NULL for none */ /* pairs of (x,y) in order, as touch-up points, or NULL for none */
int *touch_up_points; int* touch_up_points;
unsigned int num_touch_up_points; unsigned int num_touch_up_points;
}; };
@ -69,73 +69,51 @@ static struct SmoothLightingFace lighting_rules[] = {
// ... // ...
*/ */
/* top */ /* top */
{0, 1, 0, { {0, 1, 0, {
{0, 6, {0, 6, -1, 0, 0, 0, 0, -1},
-1, 0, 0, {12, 0, 1, 0, 0, 0, 0, -1},
0, 0, -1}, {24, 6, 1, 0, 0, 0, 0, 1},
{12, 0, {12, 12, -1, 0, 0, 0, 0, 1},
1, 0, 0, },
0, 0, -1}, top_touchups,
{24, 6, 6},
1, 0, 0,
0, 0, 1},
{12, 12,
-1, 0, 0,
0, 0, 1},
},
top_touchups, 6},
/* left */ /* left */
{-1, 0, 0, { {-1, 0, 0, {
{0, 18, {0, 18, 0, 0, -1, 0, -1, 0},
0, 0, -1, {0, 6, 0, 0, -1, 0, 1, 0},
0, -1, 0}, {12, 12, 0, 0, 1, 0, 1, 0},
{0, 6, {12, 24, 0, 0, 1, 0, -1, 0},
0, 0, -1, },
0, 1, 0}, NULL,
{12, 12, 0},
0, 0, 1,
0, 1, 0},
{12, 24,
0, 0, 1,
0, -1, 0},
},
NULL, 0},
/* right */ /* right */
{0, 0, 1, { {0, 0, 1, {
{24, 6, {24, 6, 1, 0, 0, 0, 1, 0},
1, 0, 0, {12, 12, -1, 0, 0, 0, 1, 0},
0, 1, 0}, {12, 24, -1, 0, 0, 0, -1, 0},
{12, 12, {24, 18, 1, 0, 0, 0, -1, 0},
-1, 0, 0, },
0, 1, 0}, NULL,
{12, 24, 0},
-1, 0, 0,
0, -1, 0},
{24, 18,
1, 0, 0,
0, -1, 0},
},
NULL, 0},
}; };
/* helpers for indexing the rule list */ /* helpers for indexing the rule list */
enum enum {
{
FACE_TOP = 0, FACE_TOP = 0,
FACE_LEFT = 1, FACE_LEFT = 1,
FACE_RIGHT = 2, FACE_RIGHT = 2,
}; };
static void static void
do_shading_with_rule(RenderPrimitiveSmoothLighting *self, RenderState *state, struct SmoothLightingFace face) { do_shading_with_rule(RenderPrimitiveSmoothLighting* self, RenderState* state, struct SmoothLightingFace face) {
int i; int i;
RenderPrimitiveLighting *lighting = (RenderPrimitiveLighting *)self; RenderPrimitiveLighting* lighting = (RenderPrimitiveLighting*)self;
int x = state->imgx, y = state->imgy; int x = state->imgx, y = state->imgy;
struct SmoothLightingCorner *pts = face.corners; struct SmoothLightingCorner* pts = face.corners;
float comp_shade_strength = 1.0 - lighting->strength; float comp_shade_strength = 1.0 - lighting->strength;
unsigned char pts_r[4] = {0, 0, 0, 0}; unsigned char pts_r[4] = {0, 0, 0, 0};
unsigned char pts_g[4] = {0, 0, 0, 0}; unsigned char pts_g[4] = {0, 0, 0, 0};
@ -143,97 +121,100 @@ do_shading_with_rule(RenderPrimitiveSmoothLighting *self, RenderState *state, st
int cx = state->x + face.dx; int cx = state->x + face.dx;
int cy = state->y + face.dy; int cy = state->y + face.dy;
int cz = state->z + face.dz; int cz = state->z + face.dz;
/* first, check for occlusion if the block is in the local chunk */ /* first, check for occlusion if the block is in the local chunk */
if (lighting_is_face_occluded(state, 0, cx, cy, cz)) if (lighting_is_face_occluded(state, 0, cx, cy, cz))
return; return;
/* calculate the lighting colors for each point */ /* calculate the lighting colors for each point */
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++) {
{
unsigned char r, g, b; unsigned char r, g, b;
unsigned int rgather = 0, ggather = 0, bgather = 0; unsigned int rgather = 0, ggather = 0, bgather = 0;
get_lighting_color(lighting, state, cx, cy, cz, get_lighting_color(lighting, state, cx, cy, cz,
&r, &g, &b); &r, &g, &b);
rgather += r; ggather += g; bgather += b; rgather += r;
ggather += g;
bgather += b;
get_lighting_color(lighting, state, get_lighting_color(lighting, state,
cx+pts[i].dx1, cy+pts[i].dy1, cz+pts[i].dz1, cx + pts[i].dx1, cy + pts[i].dy1, cz + pts[i].dz1,
&r, &g, &b); &r, &g, &b);
rgather += r; ggather += g; bgather += b; rgather += r;
ggather += g;
bgather += b;
get_lighting_color(lighting, state, get_lighting_color(lighting, state,
cx+pts[i].dx2, cy+pts[i].dy2, cz+pts[i].dz2, cx + pts[i].dx2, cy + pts[i].dy2, cz + pts[i].dz2,
&r, &g, &b); &r, &g, &b);
rgather += r; ggather += g; bgather += b; rgather += r;
ggather += g;
bgather += b;
/* FIXME special far corner handling */ /* FIXME special far corner handling */
get_lighting_color(lighting, state, get_lighting_color(lighting, state,
cx+pts[i].dx1+pts[i].dx2, cy+pts[i].dy1+pts[i].dy2, cz+pts[i].dz1+pts[i].dz2, cx + pts[i].dx1 + pts[i].dx2, cy + pts[i].dy1 + pts[i].dy2, cz + pts[i].dz1 + pts[i].dz2,
&r, &g, &b); &r, &g, &b);
rgather += r; ggather += g; bgather += b; rgather += r;
ggather += g;
rgather += (255*4 - rgather) * comp_shade_strength; bgather += b;
ggather += (255*4 - ggather) * comp_shade_strength;
bgather += (255*4 - bgather) * comp_shade_strength; rgather += (255 * 4 - rgather) * comp_shade_strength;
ggather += (255 * 4 - ggather) * comp_shade_strength;
bgather += (255 * 4 - bgather) * comp_shade_strength;
pts_r[i] = rgather / 4; pts_r[i] = rgather / 4;
pts_g[i] = ggather / 4; pts_g[i] = ggather / 4;
pts_b[i] = bgather / 4; pts_b[i] = bgather / 4;
} }
/* draw the face */ /* draw the face */
draw_triangle(state->img, 1, draw_triangle(state->img, 1,
x+pts[0].imgx, y+pts[0].imgy, pts_r[0], pts_g[0], pts_b[0], x + pts[0].imgx, y + pts[0].imgy, pts_r[0], pts_g[0], pts_b[0],
x+pts[1].imgx, y+pts[1].imgy, pts_r[1], pts_g[1], pts_b[1], x + pts[1].imgx, y + pts[1].imgy, pts_r[1], pts_g[1], pts_b[1],
x+pts[2].imgx, y+pts[2].imgy, pts_r[2], pts_g[2], pts_b[2], x + pts[2].imgx, y + pts[2].imgy, pts_r[2], pts_g[2], pts_b[2],
x, y, face.touch_up_points, face.num_touch_up_points); x, y, face.touch_up_points, face.num_touch_up_points);
draw_triangle(state->img, 0, draw_triangle(state->img, 0,
x+pts[0].imgx, y+pts[0].imgy, pts_r[0], pts_g[0], pts_b[0], x + pts[0].imgx, y + pts[0].imgy, pts_r[0], pts_g[0], pts_b[0],
x+pts[2].imgx, y+pts[2].imgy, pts_r[2], pts_g[2], pts_b[2], x + pts[2].imgx, y + pts[2].imgy, pts_r[2], pts_g[2], pts_b[2],
x+pts[3].imgx, y+pts[3].imgy, pts_r[3], pts_g[3], pts_b[3], x + pts[3].imgx, y + pts[3].imgy, pts_r[3], pts_g[3], pts_b[3],
x, y, NULL, 0); x, y, NULL, 0);
} }
static int static int
smooth_lighting_start(void *data, RenderState *state, PyObject *support) { smooth_lighting_start(void* data, RenderState* state, PyObject* support) {
/* first, chain up */ /* first, chain up */
int ret = primitive_lighting.start(data, state, support); int ret = primitive_lighting.start(data, state, support);
if (ret != 0) if (ret != 0)
return ret; return ret;
return 0; return 0;
} }
static void static void
smooth_lighting_finish(void *data, RenderState *state) { smooth_lighting_finish(void* data, RenderState* state) {
/* nothing special to do */ /* nothing special to do */
primitive_lighting.finish(data, state); primitive_lighting.finish(data, state);
} }
static void static void
smooth_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { smooth_lighting_draw(void* data, RenderState* state, PyObject* src, PyObject* mask, PyObject* mask_light) {
int light_top = 1; int light_top = 1;
int light_left = 1; int light_left = 1;
int light_right = 1; int light_right = 1;
RenderPrimitiveSmoothLighting *self = (RenderPrimitiveSmoothLighting *)data; RenderPrimitiveSmoothLighting* self = (RenderPrimitiveSmoothLighting*)data;
/* special case for leaves, water 8, water 9, ice 79 /* special case for leaves, water 8, water 9, ice 79
-- these are also smooth-lit! */ -- these are also smooth-lit! */
if (!block_class_is_subset(state->block, (mc_block_t[]){ if (!block_class_is_subset(state->block, (mc_block_t[]){block_leaves, block_flowing_water, block_water, block_ice}, 4) && is_transparent(state->block)) {
block_leaves,block_flowing_water,block_water,block_ice
}, 4) && is_transparent(state->block))
{
/* transparent blocks are rendered as usual, with flat lighting */ /* transparent blocks are rendered as usual, with flat lighting */
primitive_lighting.draw(data, state, src, mask, mask_light); primitive_lighting.draw(data, state, src, mask, mask_light);
return; return;
} }
/* non-transparent blocks get the special smooth treatment */ /* non-transparent blocks get the special smooth treatment */
/* special code for water */ /* special code for water */
if (state->block == block_water) if (state->block == block_water) {
{
if (!(state->block_pdata & (1 << 4))) if (!(state->block_pdata & (1 << 4)))
light_top = 0; light_top = 0;
if (!(state->block_pdata & (1 << 1))) if (!(state->block_pdata & (1 << 1)))
@ -241,7 +222,7 @@ smooth_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *ma
if (!(state->block_pdata & (1 << 2))) if (!(state->block_pdata & (1 << 2)))
light_right = 0; light_right = 0;
} }
if (light_top) if (light_top)
do_shading_with_rule(self, state, lighting_rules[FACE_TOP]); do_shading_with_rule(self, state, lighting_rules[FACE_TOP]);
if (light_left) if (light_left)
@ -251,7 +232,8 @@ smooth_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *ma
} }
RenderPrimitiveInterface primitive_smooth_lighting = { RenderPrimitiveInterface primitive_smooth_lighting = {
"smooth-lighting", sizeof(RenderPrimitiveSmoothLighting), "smooth-lighting",
sizeof(RenderPrimitiveSmoothLighting),
smooth_lighting_start, smooth_lighting_start,
smooth_lighting_finish, smooth_lighting_finish,
NULL, NULL,

View File

@ -15,9 +15,9 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "overviewer.h"
#include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h>
#include "overviewer.h"
/* this file defines render_primitives, /* this file defines render_primitives,
a list of all render primitives, ending in NULL a list of all render primitives, ending in NULL
@ -30,18 +30,18 @@
/* rendermode encapsulation */ /* rendermode encapsulation */
/* helper to create a single primitive */ /* helper to create a single primitive */
RenderPrimitive *render_primitive_create(PyObject *prim, RenderState *state) { RenderPrimitive* render_primitive_create(PyObject* prim, RenderState* state) {
RenderPrimitive *ret = NULL; RenderPrimitive* ret = NULL;
RenderPrimitiveInterface *iface = NULL; RenderPrimitiveInterface* iface = NULL;
unsigned int i; unsigned int i;
PyObject *pyname; PyObject* pyname;
const char* name; const char* name;
pyname = PyObject_GetAttrString(prim, "name"); pyname = PyObject_GetAttrString(prim, "name");
if (!pyname) if (!pyname)
return NULL; return NULL;
name = PyUnicode_AsUTF8(pyname); name = PyUnicode_AsUTF8(pyname);
for (i = 0; render_primitives[i] != NULL; i++) { for (i = 0; render_primitives[i] != NULL; i++) {
if (strcmp(render_primitives[i]->name, name) == 0) { if (strcmp(render_primitives[i]->name, name) == 0) {
iface = render_primitives[i]; iface = render_primitives[i];
@ -51,23 +51,23 @@ RenderPrimitive *render_primitive_create(PyObject *prim, RenderState *state) {
Py_DECREF(pyname); Py_DECREF(pyname);
if (iface == NULL) if (iface == NULL)
return (RenderPrimitive *)PyErr_Format(PyExc_RuntimeError, "invalid primitive name: %s", name); return (RenderPrimitive*)PyErr_Format(PyExc_RuntimeError, "invalid primitive name: %s", name);
ret = calloc(1, sizeof(RenderPrimitive)); ret = calloc(1, sizeof(RenderPrimitive));
if (ret == NULL) { if (ret == NULL) {
return (RenderPrimitive *)PyErr_Format(PyExc_RuntimeError, "Failed to alloc a render primitive"); return (RenderPrimitive*)PyErr_Format(PyExc_RuntimeError, "Failed to alloc a render primitive");
} }
if (iface->data_size > 0) { if (iface->data_size > 0) {
ret->primitive = calloc(1, iface->data_size); ret->primitive = calloc(1, iface->data_size);
if (ret->primitive == NULL) { if (ret->primitive == NULL) {
free(ret); free(ret);
return (RenderPrimitive *)PyErr_Format(PyExc_RuntimeError, "Failed to alloc render primitive data"); return (RenderPrimitive*)PyErr_Format(PyExc_RuntimeError, "Failed to alloc render primitive data");
} }
} }
ret->iface = iface; ret->iface = iface;
if (iface->start) { if (iface->start) {
if (iface->start(ret->primitive, state, prim)) { if (iface->start(ret->primitive, state, prim)) {
free(ret->primitive); free(ret->primitive);
@ -75,15 +75,15 @@ RenderPrimitive *render_primitive_create(PyObject *prim, RenderState *state) {
return NULL; return NULL;
} }
} }
return ret; return ret;
} }
RenderMode *render_mode_create(PyObject *mode, RenderState *state) { RenderMode* render_mode_create(PyObject* mode, RenderState* state) {
RenderMode *ret = NULL; RenderMode* ret = NULL;
PyObject *mode_fast = NULL; PyObject* mode_fast = NULL;
unsigned int i; unsigned int i;
mode_fast = PySequence_Fast(mode, "Mode is not a sequence type"); mode_fast = PySequence_Fast(mode, "Mode is not a sequence type");
if (!mode_fast) if (!mode_fast)
return NULL; return NULL;
@ -93,26 +93,26 @@ RenderMode *render_mode_create(PyObject *mode, RenderState *state) {
ret->num_primitives = PySequence_Length(mode); ret->num_primitives = PySequence_Length(mode);
ret->primitives = calloc(ret->num_primitives, sizeof(RenderPrimitive*)); ret->primitives = calloc(ret->num_primitives, sizeof(RenderPrimitive*));
for (i = 0; i < ret->num_primitives; i++) { for (i = 0; i < ret->num_primitives; i++) {
PyObject *pyprim = PySequence_Fast_GET_ITEM(mode_fast, i); PyObject* pyprim = PySequence_Fast_GET_ITEM(mode_fast, i);
RenderPrimitive *prim = render_primitive_create(pyprim, state); RenderPrimitive* prim = render_primitive_create(pyprim, state);
if (!prim) { if (!prim) {
render_mode_destroy(ret); render_mode_destroy(ret);
Py_DECREF(mode_fast); Py_DECREF(mode_fast);
return NULL; return NULL;
} }
ret->primitives[i] = prim; ret->primitives[i] = prim;
} }
return ret; return ret;
} }
void render_mode_destroy(RenderMode *self) { void render_mode_destroy(RenderMode* self) {
unsigned int i; unsigned int i;
for (i = 0; i < self->num_primitives; i++) { for (i = 0; i < self->num_primitives; i++) {
RenderPrimitive *prim = self->primitives[i]; RenderPrimitive* prim = self->primitives[i];
/* we may be destroying a half-constructed mode, so we need this /* we may be destroying a half-constructed mode, so we need this
check */ check */
if (prim) { if (prim) {
@ -129,40 +129,40 @@ void render_mode_destroy(RenderMode *self) {
free(self); free(self);
} }
int render_mode_occluded(RenderMode *self, int x, int y, int z) { int render_mode_occluded(RenderMode* self, int x, int y, int z) {
unsigned int i; unsigned int i;
int occluded = 0; int occluded = 0;
for (i = 0; i < self->num_primitives; i++) { for (i = 0; i < self->num_primitives; i++) {
RenderPrimitive *prim = self->primitives[i]; RenderPrimitive* prim = self->primitives[i];
if (prim->iface->occluded) { if (prim->iface->occluded) {
occluded |= prim->iface->occluded(prim->primitive, self->state, x, y, z); occluded |= prim->iface->occluded(prim->primitive, self->state, x, y, z);
} }
if (occluded) if (occluded)
return occluded; return occluded;
} }
return occluded; return occluded;
} }
int render_mode_hidden(RenderMode *self, int x, int y, int z) { int render_mode_hidden(RenderMode* self, int x, int y, int z) {
unsigned int i; unsigned int i;
int hidden = 0; int hidden = 0;
for (i = 0; i < self->num_primitives; i++) { for (i = 0; i < self->num_primitives; i++) {
RenderPrimitive *prim = self->primitives[i]; RenderPrimitive* prim = self->primitives[i];
if (prim->iface->hidden) { if (prim->iface->hidden) {
hidden |= prim->iface->hidden(prim->primitive, self->state, x, y, z); hidden |= prim->iface->hidden(prim->primitive, self->state, x, y, z);
} }
if (hidden) if (hidden)
return hidden; return hidden;
} }
return hidden; return hidden;
} }
void render_mode_draw(RenderMode *self, PyObject *img, PyObject *mask, PyObject *mask_light) { void render_mode_draw(RenderMode* self, PyObject* img, PyObject* mask, PyObject* mask_light) {
unsigned int i; unsigned int i;
for (i = 0; i < self->num_primitives; i++) { for (i = 0; i < self->num_primitives; i++) {
RenderPrimitive *prim = self->primitives[i]; RenderPrimitive* prim = self->primitives[i];
if (prim->iface->draw) { if (prim->iface->draw) {
prim->iface->draw(prim->primitive, self->state, img, mask, mask_light); prim->iface->draw(prim->primitive, self->state, img, mask, mask_light);
} }
@ -170,24 +170,24 @@ void render_mode_draw(RenderMode *self, PyObject *img, PyObject *mask, PyObject
} }
/* options parse helper */ /* options parse helper */
int render_mode_parse_option(PyObject *support, const char *name, const char *format, ...) { int render_mode_parse_option(PyObject* support, const char* name, const char* format, ...) {
va_list ap; va_list ap;
PyObject *item, *dict; PyObject *item, *dict;
int ret; int ret;
if (support == NULL || name == NULL) if (support == NULL || name == NULL)
return 0; return 0;
dict = PyObject_GetAttrString(support, "option_values"); dict = PyObject_GetAttrString(support, "option_values");
if (!dict) if (!dict)
return 0; return 0;
item = PyDict_GetItemString(dict, name); item = PyDict_GetItemString(dict, name);
if (item == NULL) { if (item == NULL) {
Py_DECREF(dict); Py_DECREF(dict);
return 0; return 0;
}; };
/* make sure the item we're parsing is a tuple /* make sure the item we're parsing is a tuple
for VaParse to work correctly */ for VaParse to work correctly */
if (!PyTuple_Check(item)) { if (!PyTuple_Check(item)) {
@ -195,26 +195,26 @@ int render_mode_parse_option(PyObject *support, const char *name, const char *fo
} else { } else {
Py_INCREF(item); Py_INCREF(item);
} }
va_start(ap, format); va_start(ap, format);
ret = PyArg_VaParse(item, format, ap); ret = PyArg_VaParse(item, format, ap);
va_end(ap); va_end(ap);
Py_DECREF(item); Py_DECREF(item);
Py_DECREF(dict); Py_DECREF(dict);
if (!ret) { if (!ret) {
PyObject *errtype, *errvalue, *errtraceback, *errstring; PyObject *errtype, *errvalue, *errtraceback, *errstring;
PyErr_Fetch(&errtype, &errvalue, &errtraceback); PyErr_Fetch(&errtype, &errvalue, &errtraceback);
errstring = PyUnicode_AsUTF8String(errvalue); errstring = PyUnicode_AsUTF8String(errvalue);
PyErr_Format(PyExc_TypeError, "rendermode option \"%s\" has incorrect type (%s)", name, errstring); PyErr_Format(PyExc_TypeError, "rendermode option \"%s\" has incorrect type (%s)", name, errstring);
Py_DECREF(errtype); Py_DECREF(errtype);
Py_DECREF(errvalue); Py_DECREF(errvalue);
Py_XDECREF(errtraceback); Py_XDECREF(errtraceback);
} }
return ret; return ret;
} }

View File

@ -47,20 +47,20 @@
/* render primitive interface */ /* render primitive interface */
typedef struct { typedef struct {
/* the name of this mode */ /* the name of this mode */
const char *name; const char* name;
/* the size of the local storage for this rendermode */ /* the size of the local storage for this rendermode */
unsigned int data_size; unsigned int data_size;
/* may return non-zero on error, last arg is the python support object */ /* may return non-zero on error, last arg is the python support object */
int (*start)(void *, RenderState *, PyObject *); int (*start)(void*, RenderState*, PyObject*);
void (*finish)(void *, RenderState *); void (*finish)(void*, RenderState*);
/* returns non-zero to skip rendering this block because it's not visible */ /* returns non-zero to skip rendering this block because it's not visible */
int (*occluded)(void *, RenderState *, int, int, int); int (*occluded)(void*, RenderState*, int, int, int);
/* returns non-zero to skip rendering this block because the user doesn't /* returns non-zero to skip rendering this block because the user doesn't
* want it visible */ * want it visible */
int (*hidden)(void *, RenderState *, int, int, int); int (*hidden)(void*, RenderState*, int, int, int);
/* last two arguments are img and mask, from texture lookup */ /* last two arguments are img and mask, from texture lookup */
void (*draw)(void *, RenderState *, PyObject *, PyObject *, PyObject *); void (*draw)(void*, RenderState*, PyObject*, PyObject*, PyObject*);
} RenderPrimitiveInterface; } RenderPrimitiveInterface;
/* A quick note about the difference between occluded and hidden: /* A quick note about the difference between occluded and hidden:
@ -80,26 +80,26 @@ typedef struct {
/* convenience wrapper for a single primitive + interface */ /* convenience wrapper for a single primitive + interface */
typedef struct { typedef struct {
void *primitive; void* primitive;
RenderPrimitiveInterface *iface; RenderPrimitiveInterface* iface;
} RenderPrimitive; } RenderPrimitive;
/* wrapper for passing around rendermodes */ /* wrapper for passing around rendermodes */
struct _RenderMode { struct _RenderMode {
unsigned int num_primitives; unsigned int num_primitives;
RenderPrimitive **primitives; RenderPrimitive** primitives;
RenderState *state; RenderState* state;
}; };
/* functions for creating / using rendermodes */ /* functions for creating / using rendermodes */
RenderMode *render_mode_create(PyObject *mode, RenderState *state); RenderMode* render_mode_create(PyObject* mode, RenderState* state);
void render_mode_destroy(RenderMode *self); void render_mode_destroy(RenderMode* self);
int render_mode_occluded(RenderMode *self, int x, int y, int z); int render_mode_occluded(RenderMode* self, int x, int y, int z);
int render_mode_hidden(RenderMode *self, int x, int y, int z); int render_mode_hidden(RenderMode* self, int x, int y, int z);
void render_mode_draw(RenderMode *self, PyObject *img, PyObject *mask, PyObject *mask_light); void render_mode_draw(RenderMode* self, PyObject* img, PyObject* mask, PyObject* mask_light);
/* helper function for reading in rendermode options /* helper function for reading in rendermode options
works like PyArg_ParseTuple on a support object */ works like PyArg_ParseTuple on a support object */
int render_mode_parse_option(PyObject *support, const char *name, const char *format, ...); int render_mode_parse_option(PyObject* support, const char* name, const char* format, ...);
#endif /* __RENDERMODES_H_INCLUDED__ */ #endif /* __RENDERMODES_H_INCLUDED__ */

View File

@ -8,11 +8,11 @@
/* like (a * b + 127) / 255), but much faster on most platforms /* like (a * b + 127) / 255), but much faster on most platforms
from PIL's _imaging.c */ from PIL's _imaging.c */
#define OV_MULDIV255(a, b, tmp)\ #define OV_MULDIV255(a, b, tmp) \
(tmp = (a) * (b) + 128, ((((tmp) >> 8) + (tmp)) >> 8)) (tmp = (a) * (b) + 128, ((((tmp) >> 8) + (tmp)) >> 8))
#define OV_BLEND(mask, in1, in2, tmp1, tmp2)\ #define OV_BLEND(mask, in1, in2, tmp1, tmp2) \
(OV_MULDIV255(in1, 255 - mask, tmp1) + OV_MULDIV255(in2, mask, tmp2)) (OV_MULDIV255(in1, 255 - mask, tmp1) + OV_MULDIV255(in2, mask, tmp2))
#define COUNT_OF(array) \ #define COUNT_OF(array) \
(sizeof(array) / sizeof(array[0])) (sizeof(array) / sizeof(array[0]))