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

View File

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

View File

@ -24,28 +24,26 @@
#include "mc_id.h"
bool block_class_is_subset(
mc_block_t block,
const mc_block_t block_class[],
size_t block_class_len
);
mc_block_t block,
const mc_block_t block_class[],
size_t block_class_len);
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 size_t block_class_door_len;
extern const size_t block_class_door_len;
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 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 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 size_t block_class_alt_height_len;
extern const size_t block_class_alt_height_len;
#endif

View File

@ -26,13 +26,12 @@
typedef struct {
PyObject_HEAD
Imaging image;
Imaging image;
} ImagingObject;
inline Imaging
imaging_python_to_c(PyObject *obj)
{
PyObject *im;
imaging_python_to_c(PyObject* obj) {
PyObject* im;
Imaging image;
/* first, get the 'im' attribute */
@ -48,7 +47,7 @@ imaging_python_to_c(PyObject *obj)
return NULL;
}
image = ((ImagingObject *)im)->image;
image = ((ImagingObject*)im)->image;
Py_DECREF(im);
return image;
}
@ -57,14 +56,13 @@ imaging_python_to_c(PyObject *obj)
in these composite functions -- even handles auto-sizing to src! */
static inline void
setup_source_destination(Imaging src, Imaging dest,
int *sx, int *sy, int *dx, int *dy, int *xsize, int *ysize)
{
/* handle negative/zero sizes appropriately */
int* sx, int* sy, int* dx, int* dy, int* xsize, int* ysize) {
/* handle negative/zero sizes appropriately */
if (*xsize <= 0 || *ysize <= 0) {
*xsize = src->xsize;
*ysize = src->ysize;
}
/* set up the source position, size and destination position */
/* handle negative dest pos */
if (*dx < 0) {
@ -93,7 +91,7 @@ setup_source_destination(Imaging src, Imaging dest,
}
/* 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) {
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
* returns NULL on error, dest on success. You do NOT need to decref the return!
*/
inline PyObject *
alpha_over_full(PyObject *dest, PyObject *src, PyObject *mask, float overall_alpha,
inline PyObject*
alpha_over_full(PyObject* dest, PyObject* src, PyObject* mask, float overall_alpha,
int dx, int dy, int xsize, int ysize) {
/* libImaging handles */
Imaging imDest, imSrc, imMask;
@ -118,7 +116,7 @@ alpha_over_full(PyObject *dest, PyObject *src, PyObject *mask, float overall_alp
int tmp1, tmp2, tmp3;
/* integer [0, 255] version of overall_alpha */
UINT8 overall_alpha_int = 255 * overall_alpha;
/* short-circuit this whole thing if overall_alpha is zero */
if (overall_alpha_int == 0)
return dest;
@ -173,21 +171,21 @@ alpha_over_full(PyObject *dest, PyObject *src, PyObject *mask, float overall_alp
}
for (y = 0; y < ysize; y++) {
UINT8 *out = (UINT8 *)imDest->image[dy + y] + dx * 4;
UINT8 *outmask = (UINT8 *)imDest->image[dy + y] + dx * 4 + 3;
UINT8 *in = (UINT8 *)imSrc->image[sy + y] + sx * (imSrc->pixelsize);
UINT8 *inmask = (UINT8 *)imMask->image[sy + y] + sx * mask_stride + mask_offset;
UINT8* out = (UINT8*)imDest->image[dy + y] + dx * 4;
UINT8* outmask = (UINT8*)imDest->image[dy + y] + dx * 4 + 3;
UINT8* in = (UINT8*)imSrc->image[sy + y] + sx * (imSrc->pixelsize);
UINT8* inmask = (UINT8*)imMask->image[sy + y] + sx * mask_stride + mask_offset;
for (x = 0; x < xsize; x++) {
UINT8 in_alpha;
/* apply overall_alpha */
if (overall_alpha_int != 255 && *inmask != 0) {
in_alpha = OV_MULDIV255(*inmask, overall_alpha_int, tmp1);
} else {
in_alpha = *inmask;
}
/* special cases */
if (in_alpha == 255 || (*outmask == 0 && in_alpha > 0)) {
*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++) {
/* general case */
*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++, 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 */
/* properly refs the return value when needed: you DO need to decref the return */
PyObject *
alpha_over_wrap(PyObject *self, PyObject *args)
{
PyObject*
alpha_over_wrap(PyObject* self, PyObject* args) {
/* raw input python variables */
PyObject *dest, *src, *pos = NULL, *mask = NULL;
/* destination position and size */
int dx, dy, xsize, ysize;
/* return value: dest image on success */
PyObject *ret;
PyObject* ret;
if (!PyArg_ParseTuple(args, "OO|OO", &dest, &src, &pos, &mask))
return NULL;
if (mask == NULL)
mask = src;
/* destination position read */
if (pos == NULL) {
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
* also, it multiplies instead of doing an over operation
*/
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,
PyObject *mask, int dx, int dy, int xsize, int ysize) {
PyObject* mask, int dx, int dy, int xsize, int ysize) {
/* libImaging handles */
Imaging imDest, imMask;
/* cached blend properties */
@ -326,8 +323,8 @@ tint_with_mask(PyObject *dest, unsigned char sr, unsigned char sg,
}
for (y = 0; y < ysize; y++) {
UINT8 *out = (UINT8 *)imDest->image[dy + y] + dx * 4;
UINT8 *inmask = (UINT8 *)imMask->image[sy + y] + sx * mask_stride + mask_offset;
UINT8* out = (UINT8*)imDest->image[dy + y] + dx * 4;
UINT8* inmask = (UINT8*)imMask->image[sy + y] + sx * mask_stride + mask_offset;
for (x = 0; x < xsize; x++) {
/* special cases */
@ -345,7 +342,7 @@ tint_with_mask(PyObject *dest, unsigned char sr, unsigned char sg,
out += 4;
} else {
/* general case */
/* TODO work out general case */
*out = OV_MULDIV255(*out, (255 - *inmask) + OV_MULDIV255(sr, *inmask, tmp1), tmp2);
out++;
@ -373,16 +370,16 @@ tint_with_mask(PyObject *dest, unsigned char sr, unsigned char sg,
* (or at least, the version poorly reproduced here:
* http://www.gidforums.com/t-20838.html )
*/
PyObject *
draw_triangle(PyObject *dest, int inclusive,
PyObject*
draw_triangle(PyObject* dest, int inclusive,
int x0, int y0,
unsigned char r0, unsigned char g0, unsigned char b0,
int x1, int y1,
unsigned char r1, unsigned char g1, unsigned char b1,
int x2, int y2,
unsigned char r2, unsigned char g2, unsigned char b2,
int tux, int tuy, int *touchups, unsigned int num_touchups) {
int tux, int tuy, int* touchups, unsigned int num_touchups) {
/* destination image */
Imaging imDest;
/* ranges of pixels that are affected */
@ -397,7 +394,7 @@ draw_triangle(PyObject *dest, int inclusive,
int tmp;
/* iteration variables */
int x, y;
imDest = imaging_python_to_c(dest);
if (!imDest)
return NULL;
@ -408,48 +405,57 @@ draw_triangle(PyObject *dest, int inclusive,
"given destination image does not have mode \"RGBA\"");
return NULL;
}
/* set up draw ranges */
xmin = OV_MIN(x0, OV_MIN(x1, x2));
ymin = OV_MIN(y0, OV_MIN(y1, y2));
xmax = OV_MAX(x0, OV_MAX(x1, x2)) + 1;
ymax = OV_MAX(y0, OV_MAX(y1, y2)) + 1;
xmin = OV_MAX(xmin, 0);
ymin = OV_MAX(ymin, 0);
xmax = OV_MIN(xmax, imDest->xsize);
ymax = OV_MIN(ymax, imDest->ysize);
/* setup coefficients */
a12 = y1 - y2; b12 = x2 - x1; 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);
a12 = y1 - y2;
b12 = x2 - x1;
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 */
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);
/* iterate over the destination rect */
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++) {
float alpha, beta, gamma;
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);
if (alpha >= 0 && beta >= 0 && gamma >= 0 &&
(inclusive || (alpha * beta * gamma > 0))) {
unsigned int r = alpha * r0 + beta * r1 + gamma * r2;
unsigned int g = alpha * g0 + beta * g1 + gamma * g2;
unsigned int b = alpha * b0 + beta * b1 + gamma * b2;
*out = OV_MULDIV255(*out, r, tmp); out++;
*out = OV_MULDIV255(*out, g, tmp); out++;
*out = OV_MULDIV255(*out, b, tmp); out++;
*out = OV_MULDIV255(*out, r, tmp);
out++;
*out = OV_MULDIV255(*out, g, tmp);
out++;
*out = OV_MULDIV255(*out, b, tmp);
out++;
/* keep alpha the same */
out++;
} else {
@ -458,42 +464,45 @@ draw_triangle(PyObject *dest, int inclusive,
}
}
}
while (num_touchups > 0) {
float alpha, beta, gamma;
unsigned int r, g, b;
UINT8 *out;
UINT8* out;
x = touchups[0] + tux;
y = touchups[1] + tuy;
touchups += 2;
num_touchups--;
if (x < 0 || x >= imDest->xsize || y < 0 || y >= imDest->ysize)
continue;
out = (UINT8 *)imDest->image[y] + x * 4;
out = (UINT8*)imDest->image[y] + x * 4;
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);
r = alpha * r0 + beta * r1 + gamma * r2;
g = alpha * g0 + beta * g1 + gamma * g2;
b = alpha * b0 + beta * b1 + gamma * b2;
*out = OV_MULDIV255(*out, r, tmp); out++;
*out = OV_MULDIV255(*out, g, tmp); out++;
*out = OV_MULDIV255(*out, b, tmp); out++;
*out = OV_MULDIV255(*out, r, tmp);
out++;
*out = OV_MULDIV255(*out, g, tmp);
out++;
*out = OV_MULDIV255(*out, b, tmp);
out++;
}
return dest;
}
/* scales the image to half size
*/
inline PyObject *
resize_half(PyObject *dest, PyObject *src) {
inline PyObject*
resize_half(PyObject* dest, PyObject* src) {
/* libImaging handles */
Imaging imDest, imSrc;
/* alpha properties */
@ -501,138 +510,134 @@ resize_half(PyObject *dest, PyObject *src) {
/* iteration variables */
unsigned int x, y;
/* temp color variables */
unsigned int r, g, b, a;
unsigned int r, g, b, a;
/* size values for source and destination */
int src_width, src_height, dest_width, dest_height;
imDest = imaging_python_to_c(dest);
imSrc = imaging_python_to_c(src);
if (!imDest || !imSrc)
return NULL;
/* check the various image modes, make sure they make sense */
if (strcmp(imDest->mode, "RGBA") != 0) {
PyErr_SetString(PyExc_ValueError,
"given destination image does not have mode \"RGBA\"");
return NULL;
}
if (strcmp(imSrc->mode, "RGBA") != 0 && strcmp(imSrc->mode, "RGB") != 0) {
PyErr_SetString(PyExc_ValueError,
"given source image does not have mode \"RGBA\" or \"RGB\"");
return NULL;
}
src_width = imSrc->xsize;
src_height = imSrc->ysize;
dest_width = imDest->xsize;
dest_height = imDest->ysize;
/* make sure destination size is 1/2 src size */
if (src_width / 2 != dest_width || src_height / 2 != dest_height) {
PyErr_SetString(PyExc_ValueError,
"destination image size is not one-half source image size");
return NULL;
}
/* set up flags for the src/mask type */
src_has_alpha = (imSrc->pixelsize == 4 ? 1 : 0);
dest_has_alpha = (imDest->pixelsize == 4 ? 1 : 0);
/* check that there remains anything to resize */
if (dest_width <= 0 || dest_height <= 0) {
/* nothing to do, return */
return dest;
}
/* set to fully opaque if source has no alpha channel */
if(!src_has_alpha)
if (!src_has_alpha)
a = 0xFF << 2;
for (y = 0; y < dest_height; y++) {
UINT8 *out = (UINT8 *)imDest->image[y];
UINT8 *in_row1 = (UINT8 *)imSrc->image[y * 2];
UINT8 *in_row2 = (UINT8 *)imSrc->image[y * 2 + 1];
UINT8* out = (UINT8*)imDest->image[y];
UINT8* in_row1 = (UINT8*)imSrc->image[y * 2];
UINT8* in_row2 = (UINT8*)imSrc->image[y * 2 + 1];
for (x = 0; x < dest_width; x++) {
// read first column
r = *in_row1;
r = *in_row1;
r += *in_row2;
in_row1++;
in_row2++;
g = *in_row1;
g = *in_row1;
g += *in_row2;
in_row1++;
in_row2++;
b = *in_row1;
b = *in_row1;
b += *in_row2;
in_row1++;
in_row2++;
if (src_has_alpha)
{
a = *in_row1;
in_row2++;
if (src_has_alpha) {
a = *in_row1;
a += *in_row2;
in_row1++;
in_row2++;
}
// read second column
r += *in_row1;
// read second column
r += *in_row1;
r += *in_row2;
in_row1++;
in_row2++;
g += *in_row1;
g += *in_row1;
g += *in_row2;
in_row1++;
in_row2++;
b += *in_row1;
b += *in_row1;
b += *in_row2;
in_row1++;
in_row2++;
if (src_has_alpha)
{
a += *in_row1;
if (src_has_alpha) {
a += *in_row1;
a += *in_row2;
in_row1++;
in_row2++;
}
// write blended color
// write blended color
*out = (UINT8)(r >> 2);
out++;
*out = (UINT8)(g >> 2);
out++;
*out = (UINT8)(b >> 2);
out++;
if (dest_has_alpha)
{
if (dest_has_alpha) {
*out = (UINT8)(a >> 2);
out++;
}
}
}
return dest;
}
/* wraps resize_half so it can be called directly from python */
PyObject *
resize_half_wrap(PyObject *self, PyObject *args)
{
PyObject*
resize_half_wrap(PyObject* self, PyObject* args) {
/* raw input python variables */
PyObject *dest, *src;
/* return value: dest image on success */
PyObject *ret;
PyObject* ret;
if (!PyArg_ParseTuple(args, "OO", &dest, &src))
return NULL;
ret = resize_half(dest, src);
if (ret == dest) {
/* 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/>.
*/
#include "overviewer.h"
#include "mc_id.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_data = 0;
unsigned char *block_properties = NULL;
unsigned char* block_properties = NULL;
static PyObject *known_blocks = NULL;
static PyObject *transparent_blocks = NULL;
static PyObject *solid_blocks = NULL;
static PyObject *fluid_blocks = NULL;
static PyObject *nospawn_blocks = NULL;
static PyObject *nodata_blocks = NULL;
static PyObject* known_blocks = NULL;
static PyObject* transparent_blocks = NULL;
static PyObject* solid_blocks = NULL;
static PyObject* fluid_blocks = NULL;
static PyObject* nospawn_blocks = NULL;
static PyObject* nodata_blocks = NULL;
PyObject *init_chunk_render(void) {
PyObject *tmp = NULL;
PyObject* init_chunk_render(void) {
PyObject* tmp = NULL;
unsigned int i;
/* this function only needs to be called once, anything more should be
* ignored */
if (textures) {
Py_RETURN_NONE;
}
textures = PyImport_ImportModule("overviewer_core.textures");
/* ensure none of these pointers are NULL */
/* ensure none of these pointers are NULL */
if ((!textures)) {
return NULL;
}
tmp = PyObject_GetAttrString(textures, "max_blockid");
if (!tmp)
return NULL;
@ -79,11 +79,11 @@ PyObject *init_chunk_render(void) {
nodata_blocks = PyObject_GetAttrString(textures, "nodata_blocks");
if (!nodata_blocks)
return NULL;
block_properties = calloc(max_blockid, sizeof(unsigned char));
for (i = 0; i < max_blockid; i++) {
PyObject *block = PyLong_FromLong(i);
PyObject* block = PyLong_FromLong(i);
if (PySequence_Contains(known_blocks, block))
block_properties[i] |= 1 << KNOWN;
if (PySequence_Contains(transparent_blocks, block))
@ -96,19 +96,19 @@ PyObject *init_chunk_render(void) {
block_properties[i] |= 1 << NOSPAWN;
if (PySequence_Contains(nodata_blocks, block))
block_properties[i] |= 1 << NODATA;
Py_DECREF(block);
}
Py_RETURN_NONE;
}
/* helper for load_chunk, loads a section into a chunk */
static inline void load_chunk_section(ChunkData *dest, int i, PyObject *section) {
dest->sections[i].blocks = (PyArrayObject*) PyDict_GetItemString(section, "Blocks");
dest->sections[i].data = (PyArrayObject*) PyDict_GetItemString(section, "Data");
dest->sections[i].skylight = (PyArrayObject*) PyDict_GetItemString(section, "SkyLight");
dest->sections[i].blocklight = (PyArrayObject*) PyDict_GetItemString(section, "BlockLight");
static inline void load_chunk_section(ChunkData* dest, int i, PyObject* section) {
dest->sections[i].blocks = (PyArrayObject*)PyDict_GetItemString(section, "Blocks");
dest->sections[i].data = (PyArrayObject*)PyDict_GetItemString(section, "Data");
dest->sections[i].skylight = (PyArrayObject*)PyDict_GetItemString(section, "SkyLight");
dest->sections[i].blocklight = (PyArrayObject*)PyDict_GetItemString(section, "BlockLight");
Py_INCREF(dest->sections[i].blocks);
Py_INCREF(dest->sections[i].data);
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.
*/
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;
PyObject *chunk = NULL;
PyObject *sections = NULL;
PyObject* chunk = NULL;
PyObject* sections = NULL;
if (dest->loaded)
return 0;
/* set up reasonable defaults */
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].data = NULL;
dest->sections[i].skylight = NULL;
dest->sections[i].blocklight = NULL;
}
dest->loaded = 1;
x += state->chunkx;
z += state->chunkz;
@ -166,31 +165,31 @@ int load_chunk(RenderState* state, int x, int z, unsigned char required) {
}
return 1;
}
dest->biomes = (PyArrayObject*) PyDict_GetItemString(chunk, "Biomes");
dest->biomes = (PyArrayObject*)PyDict_GetItemString(chunk, "Biomes");
Py_INCREF(dest->biomes);
for (i = 0; i < PySequence_Fast_GET_SIZE(sections); i++) {
PyObject *ycoord = NULL;
PyObject* ycoord = NULL;
int sectiony = 0;
PyObject *section = PySequence_Fast_GET_ITEM(sections, i);
PyObject* section = PySequence_Fast_GET_ITEM(sections, i);
ycoord = PyDict_GetItemString(section, "Y");
if (!ycoord)
continue;
sectiony = PyLong_AsLong(ycoord);
if (sectiony >= 0 && sectiony < SECTIONS_PER_CHUNK)
load_chunk_section(dest, sectiony, section);
}
Py_DECREF(sections);
Py_DECREF(chunk);
return 0;
}
/* helper to unload all loaded chunks */
static void
unload_all_chunks(RenderState *state) {
unload_all_chunks(RenderState* state) {
unsigned int i, j, k;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
@ -209,7 +208,7 @@ unload_all_chunks(RenderState *state) {
}
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
* 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
* 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) {
pdata = pdata|(1 << 3);
}
pdata = pdata | (1 << 3);
}
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) {
pdata = pdata|(1 << 1);
pdata = pdata | (1 << 1);
}
if (get_data(state, BLOCKS, x, y, z - 1) == blockid) {
pdata = pdata|(1 << 0);
pdata = pdata | (1 << 0);
}
return pdata;
}
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
* depending on what are surrounded.
@ -255,23 +254,23 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
if (state->block == block_grass) { /* grass */
/* 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 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;
/* 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;
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
* 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
* */
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;
} else {
} else {
data = 16;
}
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 */
/* 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) |
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_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);
} else if (state->block == block_redstone_wire) { /* redstone */
/* 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) */
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 */
if (get_data(state, BLOCKS, x, y+1, z) == 0) {
above_level_data = check_adjacent_blocks(state, x, y+1, z, state->block);
} /* else above_level_data = 0 */
/* check for air in y+1, no air = no connection with upper level */
if (get_data(state, BLOCKS, x, y + 1, z) == 0) {
above_level_data = check_adjacent_blocks(state, x, y + 1, z, state->block);
} /* else above_level_data = 0 */
/* 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);
/* check the posibility of connection with y-1 level, check for air */
possibly_connected = check_adjacent_blocks(state, x, y, z, 0);
/* 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);
/* add the three bits */
if (ancilData > 0) { /* powered redstone wire */
final_data = final_data | 0x40;
@ -316,12 +315,12 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
}
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
* choose from single or double chest and the correct half of
* 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
* bit 0x8 = first half */
@ -353,7 +352,7 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
}
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:
* they seem to stick to almost everything but air,
* 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);
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 */
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;
if ((ancilData & 0x8) == 0x8) {
/* 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) {
/* hinge on the left */
data = b_data | 0x8 | 0x10;
@ -382,14 +381,13 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
}
} else {
/* 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) {
/* hinge on the left */
data = ancilData | 0x10;
} else {
data = ancilData;
}
}
return data;
} 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);
}
} else if (state->block == block_waterlily) {
int wx,wz,wy,rotation;
int wx, wz, wy, rotation;
long pr;
/* calculate the global block coordinates of this position */
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 */
unsigned char stairs_base[8];
unsigned char neigh_base[8];
unsigned char *stairs = stairs_base;
unsigned char *neigh = neigh_base;
unsigned char* stairs = stairs_base;
unsigned char* neigh = neigh_base;
/* 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: */
/* Example: the ridge for an east-ascending stair are the two east quarters */
/* 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: */
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 */
/* masks for port and starboard, i.e. left and right sides while ascending: */
unsigned char port_mask[] = { 0x18, 0x60, 0x30, 0x48 };
unsigned char starboard_mask[] = { 0x60, 0x18, 0x48, 0x30 };
unsigned char port_mask[] = {0x18, 0x60, 0x30, 0x48};
unsigned char starboard_mask[] = {0x60, 0x18, 0x48, 0x30};
/* we may need to lock some quarters into place depending on neighbors */
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 */
/* TODO: get this just once? store in state? */
PyObject *texrot;
PyObject* texrot;
int northdir;
texrot = PyObject_GetAttrString(state->textures, "rotation");
northdir = PyLong_AsLong(texrot);
/* fix the rotation value for different northdirections */
#define FIX_ROT(x) (((x) & ~0x3) | repair_rot[((x) & 0x3) | (northdir << 2)])
/* fix the rotation value for different northdirections */
#define FIX_ROT(x) (((x) & ~0x3) | repair_rot[((x)&0x3) | (northdir << 2)])
ancilData = FIX_ROT(ancilData);
/* 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 */
/* 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[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[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[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[3] = neigh[7] = FIX_ROT(get_data(state, DATA, x, y, z+1));
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[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);
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[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));
#undef FIX_ROT
#undef FIX_ROT
/* 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:
@ -523,8 +521,8 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
/* use bottom block data format plus one bit for top
* block (0x8)
*/
if( get_data(state, BLOCKS, x, y-1, z) == block_double_plant ) {
data = get_data(state, DATA, x, y-1, z) | 0x8;
if (get_data(state, BLOCKS, x, y - 1, z) == block_double_plant) {
data = get_data(state, DATA, x, y - 1, z) | 0x8;
} else {
data = ancilData;
}
@ -535,34 +533,33 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
return 0;
}
/* TODO triple check this to make sure reference counting is correct */
PyObject*
chunk_render(PyObject *self, PyObject *args) {
chunk_render(PyObject* self, PyObject* args) {
RenderState state;
PyObject *modeobj;
PyObject *blockmap;
PyObject* modeobj;
PyObject* blockmap;
int xoff, yoff;
PyObject *imgsize, *imgsize0_py, *imgsize1_py;
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;
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))
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))
return NULL;
/* set up the render mode */
state.rendermode = rendermode = render_mode_create(modeobj, &state);
if (rendermode == NULL) {
@ -581,7 +578,7 @@ chunk_render(PyObject *self, PyObject *args) {
PyErr_SetString(PyExc_RuntimeError, "you must call Textures.generate()");
return NULL;
}
/* get the image size */
imgsize = PyObject_GetAttrString(state.img, "size");
@ -593,14 +590,14 @@ chunk_render(PyObject *self, PyObject *args) {
imgsize1 = PyLong_AsLong(imgsize1_py);
Py_DECREF(imgsize0_py);
Py_DECREF(imgsize1_py);
/* set all block data to unloaded */
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
state.chunks[i][j].loaded = 0;
}
}
/* get the block data for the center column, erroring out if needed */
if (load_chunk(&state, 0, 0, 1)) {
render_mode_destroy(rendermode);
@ -614,7 +611,7 @@ chunk_render(PyObject *self, PyObject *args) {
unload_all_chunks(&state);
Py_RETURN_NONE;
}
/* set blocks_py, state.blocks, and state.blockdatas as convenience */
blocks_py = state.blocks = state.chunks[1][1].sections[state.chunky].blocks;
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
so tallgrass is in the same place, no matter what mode is used */
srand(1);
for (state.x = 15; state.x > -1; state.x--) {
for (state.z = 0; state.z < 16; state.z++) {
/* 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 */
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++) {
unsigned short ancilData;
state.imgy -= 12;
/* get blockid */
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)) {
continue;
}
/* make sure we're rendering inside the image boundaries */
if ((state.imgx >= imgsize0 + 24) || (state.imgx <= -24)) {
continue;
@ -648,14 +645,14 @@ chunk_render(PyObject *self, PyObject *args) {
if ((state.imgy >= imgsize1 + 24) || (state.imgy <= -24)) {
continue;
}
/* check for occlusion */
if (render_mode_occluded(rendermode, state.x, state.y, state.z)) {
continue;
}
/* everything stored here will be a borrowed ref */
if (block_has_property(state.block, NODATA)) {
/* block shouldn't have data associated with it, set it to 0 */
ancilData = 0;
@ -676,20 +673,19 @@ chunk_render(PyObject *self, PyObject *args) {
state.block_pdata = 0;
}
}
/* make sure our block info is in-bounds */
if (state.block >= max_blockid || ancilData >= max_data)
continue;
/* get the texture */
t = PyList_GET_ITEM(blockmap, max_data * state.block + ancilData);
/* if we don't get a texture, try it again with 0 data */
if ((t == NULL || t == Py_None) && ancilData != 0)
t = PyList_GET_ITEM(blockmap, max_data * state.block);
/* 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;
int do_rand = (state.block == block_tallgrass /*|| state.block == block_red_flower || state.block == block_double_plant*/);
int randx = 0, randy = 0;
@ -707,9 +703,9 @@ chunk_render(PyObject *self, PyObject *args) {
state.imgx += randx;
state.imgy += randy;
}
render_mode_draw(rendermode, src, mask, mask_light);
if (do_rand) {
/* undo the random offsets */
state.imgx -= randx;
@ -722,7 +718,7 @@ chunk_render(PyObject *self, PyObject *args) {
/* free up the rendermode info */
render_mode_destroy(rendermode);
Py_DECREF(blockmap);
unload_all_chunks(&state);

View File

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

View File

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

View File

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

View File

@ -15,9 +15,9 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../overviewer.h"
#include "../mc_id.h"
#include "../block_class.h"
#include "../mc_id.h"
#include "../overviewer.h"
#include "biomes.h"
typedef struct {
@ -25,32 +25,31 @@ typedef struct {
/* grasscolor and foliagecolor lookup tables */
PyObject *grasscolor, *foliagecolor, *watercolor;
/* biome-compatible grass/leaf textures */
PyObject *grass_texture;
PyObject* grass_texture;
} PrimitiveBase;
static int
base_start(void *data, RenderState *state, PyObject *support) {
PrimitiveBase *self = (PrimitiveBase *)data;
base_start(void* data, RenderState* state, PyObject* support) {
PrimitiveBase* self = (PrimitiveBase*)data;
if (!render_mode_parse_option(support, "biomes", "i", &(self->use_biomes)))
return 1;
/* biome-compliant grass mask (includes sides!) */
self->grass_texture = PyObject_GetAttrString(state->textures, "biome_grass_texture");
/* color lookup tables */
self->foliagecolor = PyObject_CallMethod(state->textures, "load_foliage_color", "");
self->grasscolor = PyObject_CallMethod(state->textures, "load_grass_color", "");
self->watercolor = PyObject_CallMethod(state->textures, "load_water_color", "");
return 0;
}
static void
base_finish(void *data, RenderState *state) {
PrimitiveBase *self = (PrimitiveBase *)data;
base_finish(void* data, RenderState* state) {
PrimitiveBase* self = (PrimitiveBase*)data;
Py_DECREF(self->foliagecolor);
Py_DECREF(self->grasscolor);
Py_DECREF(self->watercolor);
@ -58,14 +57,14 @@ base_finish(void *data, RenderState *state) {
}
static int
base_occluded(void *data, RenderState *state, int x, int y, int z) {
if ( (x != 0) && (y != 15) && (z != 15) &&
!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+1, 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+1, z))) {
base_occluded(void* data, RenderState* state, int x, int y, int z) {
if ((x != 0) && (y != 15) && (z != 15) &&
!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 + 1, 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 + 1, z))) {
return 1;
}
@ -73,16 +72,16 @@ base_occluded(void *data, RenderState *state, int x, int y, int z) {
}
static void
base_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
PrimitiveBase *self = (PrimitiveBase *)data;
base_draw(void* data, RenderState* state, PyObject* src, PyObject* mask, PyObject* mask_light) {
PrimitiveBase* self = (PrimitiveBase*)data;
/* 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 char below_data = get_data(state, DATA, 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);
/* draw the block! */
alpha_over(state->img, src, mask, state->imgx, state->imgy, 0, 0);
/* check for biome-compatible blocks
*
* 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.
*/
if (/* grass, but not snowgrass */
(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_vine,
block_waterlily,
block_flowing_water,
block_water,
block_leaves,
block_leaves2
},
6) ||
(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_vine, block_waterlily, block_flowing_water, block_water, block_leaves, block_leaves2},
6) ||
/* tallgrass, but not dead shrubs */
(state->block == block_tallgrass && state->block_data != 0) ||
/* 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 */
(state->block == block_double_plant && (state->block_data == 2 || state->block_data == 3)) ||
/* 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! */
PyObject *facemask = mask;
PyObject* facemask = mask;
unsigned char r = 255, g = 255, b = 255;
PyObject *color_table = NULL;
PyObject* color_table = NULL;
unsigned char flip_xy = 0;
if (state->block == block_grass) {
/* grass needs a special facemask */
facemask = self->grass_texture;
}
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)) {
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)) {
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;
}
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;
if (state->block_data == 2)
{
if (state->block_data == 2) {
/* birch!
birch foliage color is flipped XY-ways */
flip_xy = 1;
}
}
if (color_table) {
unsigned char biome;
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;
unsigned int multr = 0, multg = 0, multb = 0;
int tmp;
PyObject *color = NULL;
PyObject* color = NULL;
if (self->use_biomes) {
/* average over all neighbors */
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 */
}
temp += biome_table[biome].temperature;
rain += biome_table[biome].rainfall;
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;
}
}
temp /= 9.0;
rain /= 9.0;
multr /= 9;
@ -195,15 +171,15 @@ base_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObjec
multg = biome_table[DEFAULT_BIOME].g;
multb = biome_table[DEFAULT_BIOME].b;
}
/* second coordinate is actually scaled to fit inside the triangle
so store it in rain */
rain *= temp;
/* make sure they're sane */
temp = OV_CLAMP(temp, 0.0, 1.0);
rain = OV_CLAMP(rain, 0.0, 1.0);
/* convert to x/y coordinates in color table */
tablex = 255 - (255 * temp);
tabley = 255 - (255 * rain);
@ -212,27 +188,28 @@ base_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObjec
tablex = 255 - tabley;
tabley = tmp;
}
/* look up color! */
color = PySequence_GetItem(color_table, tabley * 256 + tablex);
r = PyLong_AsLong(PyTuple_GET_ITEM(color, 0));
g = PyLong_AsLong(PyTuple_GET_ITEM(color, 1));
b = PyLong_AsLong(PyTuple_GET_ITEM(color, 2));
Py_DECREF(color);
/* do the after-coloration */
r = OV_MULDIV255(r, multr, tmp);
g = OV_MULDIV255(g, multg, tmp);
b = OV_MULDIV255(b, multb, tmp);
}
/* final coloration */
tint_with_mask(state->img, r, g, b, 255, facemask, state->imgx, state->imgy, 0, 0);
}
}
RenderPrimitiveInterface primitive_base = {
"base", sizeof(PrimitiveBase),
"base",
sizeof(PrimitiveBase),
base_start,
base_finish,
base_occluded,

View File

@ -15,7 +15,6 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/
#define DEFAULT_BIOME 4 /* forest, nice and green */
typedef struct {
@ -65,7 +64,7 @@ static Biome biome_table[] = {
{"TaigaHills", 0.05, 0.8, 255, 255, 255},
/* 20 */
{"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},
{"JungleHills", 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))

View File

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

View File

@ -18,22 +18,22 @@
#include "../overviewer.h"
static int
clear_base_occluded(void *data, RenderState *state, int x, int y, int z) {
if ( (x != 0) && (y != 15) && (z != 127) &&
!render_mode_hidden(state->rendermode, x-1, y, z) &&
!render_mode_hidden(state->rendermode, x, y, z+1) &&
!render_mode_hidden(state->rendermode, x, y+1, 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+1, z))) {
clear_base_occluded(void* data, RenderState* state, int x, int y, int z) {
if ((x != 0) && (y != 15) && (z != 127) &&
!render_mode_hidden(state->rendermode, x - 1, y, z) &&
!render_mode_hidden(state->rendermode, x, y, z + 1) &&
!render_mode_hidden(state->rendermode, x, y + 1, 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 + 1, z))) {
return 1;
}
return 0;
}
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 */
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/>.
*/
#include "../overviewer.h"
#include <math.h>
#include "../overviewer.h"
typedef struct {
/* list of colors used for tinting */
PyObject *depth_colors;
PyObject* depth_colors;
} RenderPrimitiveDepthTinting;
static int
depth_tinting_start(void *data, RenderState *state, PyObject *support) {
depth_tinting_start(void* data, RenderState* state, PyObject* support) {
RenderPrimitiveDepthTinting* self;
self = (RenderPrimitiveDepthTinting *)data;
self = (RenderPrimitiveDepthTinting*)data;
self->depth_colors = PyObject_GetAttrString(support, "depth_colors");
if (self->depth_colors == NULL)
@ -36,35 +36,36 @@ depth_tinting_start(void *data, RenderState *state, PyObject *support) {
}
static void
depth_tinting_finish(void *data, RenderState *state) {
depth_tinting_finish(void* data, RenderState* state) {
RenderPrimitiveDepthTinting* self;
self = (RenderPrimitiveDepthTinting *)data;
self = (RenderPrimitiveDepthTinting*)data;
Py_DECREF(self->depth_colors);
}
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;
int y, r, g, b;
self = (RenderPrimitiveDepthTinting *)data;
self = (RenderPrimitiveDepthTinting*)data;
y = state->chunky * 16 + state->y;
r = 0, g = 0, b = 0;
/* the colors array assumes y is between 0 and 127, so we scale it */
y = (y * 128) / (16 * SECTIONS_PER_CHUNK);
/* get the colors and tint and tint */
r = PyLong_AsLong(PyList_GetItem(self->depth_colors, 0 + y*3));
g = PyLong_AsLong(PyList_GetItem(self->depth_colors, 1 + y*3));
b = PyLong_AsLong(PyList_GetItem(self->depth_colors, 2 + y*3));
r = PyLong_AsLong(PyList_GetItem(self->depth_colors, 0 + y * 3));
g = PyLong_AsLong(PyList_GetItem(self->depth_colors, 1 + 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);
}
RenderPrimitiveInterface primitive_depth_tinting = {
"depth-tinting", sizeof(RenderPrimitiveDepthTinting),
"depth-tinting",
sizeof(RenderPrimitiveDepthTinting),
depth_tinting_start,
depth_tinting_finish,
NULL,

View File

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

View File

@ -15,69 +15,65 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../overviewer.h"
#include "../mc_id.h"
#include "../block_class.h"
#include "../mc_id.h"
#include "../overviewer.h"
typedef struct {
float opacity;
} PrimitiveEdgeLines;
static int
edge_lines_start(void *data, RenderState *state, PyObject *support) {
PrimitiveEdgeLines *self = (PrimitiveEdgeLines *)data;
edge_lines_start(void* data, RenderState* state, PyObject* support) {
PrimitiveEdgeLines* self = (PrimitiveEdgeLines*)data;
if (!render_mode_parse_option(support, "opacity", "f", &(self->opacity)))
return 1;
return 0;
}
static void
edge_lines_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
PrimitiveEdgeLines *self = (PrimitiveEdgeLines *)data;
edge_lines_draw(void* data, RenderState* state, PyObject* src, PyObject* mask, PyObject* mask_light) {
PrimitiveEdgeLines* self = (PrimitiveEdgeLines*)data;
/* Draw some edge lines! */
if (block_class_is_subset(state->block, (mc_block_t[]){block_stone_slab,block_snow_layer}, 2)
|| !is_transparent(state->block)) {
if (block_class_is_subset(state->block, (mc_block_t[]){block_stone_slab, block_snow_layer}, 2) || !is_transparent(state->block)) {
Imaging img_i = imaging_python_to_c(state->img);
unsigned char ink[] = {0, 0, 0, 255 * self->opacity};
unsigned short side_block;
int x = state->x, y = state->y, z = state->z;
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
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)
increment=9;
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
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)
increment = 9;
/* +X side */
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)) &&
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)) &&
/* 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 */
!(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))
)) {
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);
!(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)))) {
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 */
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)) &&
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)) &&
/* 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 */
!(
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))
)) {
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);
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)))) {
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 = {
"edge-lines", sizeof(PrimitiveEdgeLines),
"edge-lines",
sizeof(PrimitiveEdgeLines),
edge_lines_start,
NULL,
NULL,

View File

@ -22,19 +22,19 @@ typedef struct {
} PrimitiveExposed;
static int
exposed_start(void *data, RenderState *state, PyObject *support) {
PrimitiveExposed *self = (PrimitiveExposed *)data;
exposed_start(void* data, RenderState* state, PyObject* support) {
PrimitiveExposed* self = (PrimitiveExposed*)data;
if (!render_mode_parse_option(support, "mode", "I", &(self->mode)))
return 1;
return 0;
}
static int
exposed_hidden(void *data, RenderState *state, int x, int y, int z) {
PrimitiveExposed *self = (PrimitiveExposed *)data;
exposed_hidden(void* data, RenderState* state, int x, int y, int z) {
PrimitiveExposed* self = (PrimitiveExposed*)data;
/* Unset these flags if seeming exposure from any of these directions would
* 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 */
validMinusX = 0;
}
if (x == 15 && (!(state->chunks[2][1].loaded) || state->chunks[2][1].sections[state->chunky].blocks == NULL)) {
/* No data in +x direction */
validPlusX = 0;
}
if (y == 0 && (state->chunky - 1 < 0 || state->chunks[1][1].sections[state->chunky - 1].blocks == NULL)) {
/* No data in -y direction */
validMinusY = 0;
}
if (y == 15 && (state->chunky + 1 >= SECTIONS_PER_CHUNK || state->chunks[1][1].sections[state->chunky + 1].blocks == NULL)) {
/* No data in +y direction */
validPlusY = 0;
}
if (z == 0 && (!(state->chunks[1][0].loaded) || state->chunks[1][0].sections[state->chunky].blocks == NULL)) {
/* No data in -z direction */
validMinusZ = 0;
}
if (z == 15 && (!(state->chunks[1][2].loaded) || state->chunks[1][2].sections[state->chunky].blocks == NULL)) {
/* No data in +z direction */
validPlusZ = 0;
}
/* 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))) ||
(validPlusX && is_transparent(get_data(state, BLOCKS, x+1, y, z))) ||
(validMinusY && 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))) ||
(validPlusZ && is_transparent(get_data(state, BLOCKS, x, y, z+1 ))) ) {
if ((validMinusX && 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))) ||
(validPlusY && is_transparent(get_data(state, BLOCKS, x, y + 1, z))) ||
(validMinusZ && is_transparent(get_data(state, BLOCKS, x, y, z - 1))) ||
(validPlusZ && is_transparent(get_data(state, BLOCKS, x, y, z + 1)))) {
/* Block is exposed */
/* Returns 1 and hides us if we're rendering unexposed blocks, 0 and
* 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 */
}
RenderPrimitiveInterface primitive_exposed = {
"exposed", sizeof(PrimitiveExposed),
"exposed",
sizeof(PrimitiveExposed),
exposed_start,
NULL,
NULL,

View File

@ -18,57 +18,58 @@
#include "../overviewer.h"
typedef struct {
PyObject *black_color;
PyObject *white_color;
PyObject* black_color;
PyObject* white_color;
unsigned int sealevel;
} PrimitiveHeightFading;
static int
height_fading_start(void *data, RenderState *state, PyObject *support) {
PrimitiveHeightFading *self = (PrimitiveHeightFading *)data;
height_fading_start(void* data, RenderState* state, PyObject* support) {
PrimitiveHeightFading* self = (PrimitiveHeightFading*)data;
if (!render_mode_parse_option(support, "sealevel", "I", &(self->sealevel)))
return 1;
self->black_color = PyObject_GetAttrString(support, "black_color");
self->white_color = PyObject_GetAttrString(support, "white_color");
return 0;
}
static void
height_fading_finish(void *data, RenderState *state) {
PrimitiveHeightFading *self = (PrimitiveHeightFading *)data;
height_fading_finish(void* data, RenderState* state) {
PrimitiveHeightFading* self = (PrimitiveHeightFading*)data;
Py_DECREF(self->black_color);
Py_DECREF(self->white_color);
}
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;
PrimitiveHeightFading *self = (PrimitiveHeightFading *)data;
PrimitiveHeightFading* self = (PrimitiveHeightFading*)data;
int y = 16 * state->chunky + state->y;
/* 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 */
y = (y * 128) / (2 * self->sealevel);
/* negative alpha => darkness, positive => light */
alpha = (1.0 / (1 + expf((70 - y) / 11.0))) * 0.6 - 0.55;
if (alpha < 0.0) {
alpha *= -1;
height_color = self->black_color;
}
alpha_over_full(state->img, height_color, mask_light, alpha, state->imgx, state->imgy, 0, 0);
}
RenderPrimitiveInterface primitive_height_fading = {
"height-fading", sizeof(PrimitiveHeightFading),
"height-fading",
sizeof(PrimitiveHeightFading),
height_fading_start,
height_fading_finish,
NULL,

View File

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

View File

@ -15,18 +15,18 @@
* 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 "lighting.h"
#include "../block_class.h"
#include "../mc_id.h"
#include "../overviewer.h"
/* figures out the color from a given skylight and blocklight,
used in lighting calculations */
static void
calculate_light_color(void *data,
calculate_light_color(void* data,
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));
*r = v;
*g = v;
@ -35,22 +35,22 @@ calculate_light_color(void *data,
/* fancy version that uses the colored light texture */
static void
calculate_light_color_fancy(void *data,
calculate_light_color_fancy(void* data,
unsigned char skylight, unsigned char blocklight,
unsigned char *r, unsigned char *g, unsigned char *b) {
RenderPrimitiveLighting *mode = (RenderPrimitiveLighting *)(data);
unsigned char* r, unsigned char* g, unsigned char* b) {
RenderPrimitiveLighting* mode = (RenderPrimitiveLighting*)(data);
unsigned int index;
PyObject *color;
PyObject* color;
blocklight = OV_MAX(blocklight, skylight);
index = skylight + blocklight * 16;
color = PySequence_GetItem(mode->lightcolor, index);
*r = PyLong_AsLong(PyTuple_GET_ITEM(color, 0));
*g = PyLong_AsLong(PyTuple_GET_ITEM(color, 1));
*b = PyLong_AsLong(PyTuple_GET_ITEM(color, 2));
Py_DECREF(color);
}
@ -59,9 +59,9 @@ calculate_light_color_fancy(void *data,
(the "skylight - 11" part)
*/
static void
calculate_light_color_night(void *data,
calculate_light_color_night(void* data,
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));
*r = v;
*g = v;
@ -70,20 +70,20 @@ calculate_light_color_night(void *data,
/* fancy night version that uses the colored light texture */
static void
calculate_light_color_fancy_night(void *data,
calculate_light_color_fancy_night(void* data,
unsigned char skylight, unsigned char blocklight,
unsigned char *r, unsigned char *g, unsigned char *b) {
RenderPrimitiveLighting *mode = (RenderPrimitiveLighting *)(data);
unsigned char* r, unsigned char* g, unsigned char* b) {
RenderPrimitiveLighting* mode = (RenderPrimitiveLighting*)(data);
unsigned int index;
PyObject *color;
PyObject* color;
index = skylight + blocklight * 16;
color = PySequence_GetItem(mode->lightcolor, index);
*r = PyLong_AsLong(PyTuple_GET_ITEM(color, 0));
*g = PyLong_AsLong(PyTuple_GET_ITEM(color, 1));
*b = PyLong_AsLong(PyTuple_GET_ITEM(color, 2));
Py_DECREF(color);
}
@ -98,8 +98,8 @@ calculate_light_color_fancy_night(void *data,
*/
unsigned char
estimate_blocklevel(RenderPrimitiveLighting *self, RenderState *state,
int x, int y, int z, int *authoratative) {
estimate_blocklevel(RenderPrimitiveLighting* self, RenderState* state,
int x, int y, int z, int* authoratative) {
/* placeholders for later data arrays, coordinates */
unsigned short block;
@ -109,19 +109,19 @@ estimate_blocklevel(RenderPrimitiveLighting *self, RenderState *state,
/* defaults to "guess" until told otherwise */
if (authoratative)
*authoratative = 0;
block = get_data(state, BLOCKS, x, y, z);
if (authoratative == NULL) {
int auth;
/* iterate through all surrounding blocks to take an average */
int dx, dy, dz, local_block;
for (dx = -1; dx <= 1; dx += 2) {
for (dy = -1; dy <= 1; dy += 2) {
for (dz = -1; dz <= 1; dz += 2) {
coeff = estimate_blocklevel(self, state, x+dx, y+dy, z+dz, &auth);
local_block = get_data(state, BLOCKS, x+dx, y+dy, z+dz);
coeff = estimate_blocklevel(self, state, x + dx, y + dy, z + dz, &auth);
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
using every 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 */
if (average_count > 0) {
return average_gather / average_count;
}
blocklevel = get_data(state, BLOCKLIGHT, x, y, z);
/* no longer a guess */
if (!block_class_is_subset(block, block_class_alt_height, block_class_alt_height_len) && authoratative) {
*authoratative = 1;
}
return blocklevel;
}
inline void
get_lighting_color(RenderPrimitiveLighting *self, RenderState *state,
get_lighting_color(RenderPrimitiveLighting* self, RenderState* state,
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 */
unsigned short block;
unsigned char skylevel, blocklevel;
block = get_data(state, BLOCKS, x, y, z);
skylevel = get_data(state, SKYLIGHT, x, y, z);
blocklevel = get_data(state, BLOCKLIGHT, x, y, z);
/* special half-step handling, stairs handling */
/* 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;
/* stairs and half-blocks take the skylevel from the upper block if it's transparent */
int upper_counter = 0;
/* but if the upper_block is one of these special half-steps, we need to look at *its* upper_block */
do {
upper_counter++;
upper_counter++;
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));
if (is_transparent(upper_block)) {
@ -178,31 +178,30 @@ get_lighting_color(RenderPrimitiveLighting *self, RenderState *state,
} else {
skylevel = 15;
}
/* the block has a bad blocklevel, estimate it from neigborhood
* use given coordinates, no local ones! */
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! */
*r = 255;
*g = 255;
*b = 255;
return;
}
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 */
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 */
if (x >= 0 && x < 16 && y >= 0 && y < 16 && z >= 0 && z < 16) {
unsigned short block = getArrayShort3D(state->blocks, 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 */
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.
This wouldn't be necessary if the textures were truly
tessellate-able */
return 1;
return 1;
}
}
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
lighting results from (x, y, z) */
static inline void
do_shading_with_mask(RenderPrimitiveLighting *self, RenderState *state,
int x, int y, int z, PyObject *mask) {
do_shading_with_mask(RenderPrimitiveLighting* self, RenderState* state,
int x, int y, int z, PyObject* mask) {
unsigned char r, g, b;
float comp_strength;
/* check occlusion */
if (lighting_is_face_occluded(state, self->skip_sides, x, y, z))
return;
get_lighting_color(self, state, x, y, z, &r, &g, &b);
comp_strength = 1.0 - self->strength;
r += (255 - r) * comp_strength;
g += (255 - g) * comp_strength;
b += (255 - b) * comp_strength;
tint_with_mask(state->img, r, g, b, 255, mask, state->imgx, state->imgy, 0, 0);
}
static int
lighting_start(void *data, RenderState *state, PyObject *support) {
lighting_start(void* data, RenderState* state, PyObject* support) {
RenderPrimitiveLighting* self;
self = (RenderPrimitiveLighting *)data;
self = (RenderPrimitiveLighting*)data;
/* don't skip sides by default */
self->skip_sides = 0;
@ -256,19 +255,19 @@ lighting_start(void *data, RenderState *state, PyObject *support) {
return 1;
if (!render_mode_parse_option(support, "color", "i", &(self->color)))
return 1;
self->facemasks_py = PyObject_GetAttrString(support, "facemasks");
// borrowed references, don't need to be decref'd
self->facemasks[0] = PyTuple_GetItem(self->facemasks_py, 0);
self->facemasks[1] = PyTuple_GetItem(self->facemasks_py, 1);
self->facemasks[2] = PyTuple_GetItem(self->facemasks_py, 2);
if (self->night) {
self->calculate_light_color = calculate_light_color_night;
} else {
self->calculate_light_color = calculate_light_color;
}
if (self->color) {
self->lightcolor = PyObject_CallMethod(state->textures, "load_light_color", "");
if (self->lightcolor == Py_None) {
@ -285,37 +284,37 @@ lighting_start(void *data, RenderState *state, PyObject *support) {
} else {
self->lightcolor = NULL;
}
return 0;
}
static void
lighting_finish(void *data, RenderState *state) {
RenderPrimitiveLighting *self = (RenderPrimitiveLighting *)data;
lighting_finish(void* data, RenderState* state) {
RenderPrimitiveLighting* self = (RenderPrimitiveLighting*)data;
Py_DECREF(self->facemasks_py);
}
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;
int x, y, z;
self = (RenderPrimitiveLighting *)data;
self = (RenderPrimitiveLighting*)data;
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
* blocks that are transparent for occlusion calculations and
* need per-face shading if the face is drawn. */
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 */
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 */
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
* 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);
} else {
/* 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-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 + 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, y, z + 1, self->facemasks[2]);
}
}
RenderPrimitiveInterface primitive_lighting = {
"lighting", sizeof(RenderPrimitiveLighting),
"lighting",
sizeof(RenderPrimitiveLighting),
lighting_start,
lighting_finish,
NULL,

View File

@ -18,21 +18,21 @@
#include "../overviewer.h"
typedef struct {
PyObject *facemasks_py;
PyObject *facemasks[3];
PyObject* facemasks_py;
PyObject* facemasks[3];
/* light color image, loaded if color_light is True */
PyObject *lightcolor;
PyObject* lightcolor;
/* can be overridden in derived rendermodes to control lighting
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
* sides is actually important. Right now, this is used in cave mode
*/
int skip_sides;
float strength;
int color;
int night;
@ -40,7 +40,7 @@ typedef struct {
/* exposed so that smooth-lighting can use them */
extern RenderPrimitiveInterface primitive_lighting;
int lighting_is_face_occluded(RenderState *state, int skip_sides, int x, int y, int z);
void get_lighting_color(RenderPrimitiveLighting *self, RenderState *state,
int lighting_is_face_occluded(RenderState* state, int skip_sides, int x, int y, int z);
void get_lighting_color(RenderPrimitiveLighting* self, RenderState* state,
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/>.
*/
#include "../overviewer.h"
#include "../mc_id.h"
#include "../block_class.h"
#include "nether.h"
#include "../block_class.h"
#include "../mc_id.h"
#include "../overviewer.h"
static void
walk_chunk(RenderState *state, RenderPrimitiveNether *data) {
walk_chunk(RenderState* state, RenderPrimitiveNether* data) {
int x, y, z;
int id;
@ -29,16 +29,16 @@ walk_chunk(RenderState *state, RenderPrimitiveNether *data) {
for (z = -1; z < DEPTH + 1; z++) {
id = get_data(state, BLOCKS, x, NETHER_ROOF - (state->chunky * 16), z);
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);
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);
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;
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;
else
break;
}
@ -48,21 +48,22 @@ walk_chunk(RenderState *state, RenderPrimitiveNether *data) {
}
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;
int real_y;
self = (RenderPrimitiveNether *)data;
self = (RenderPrimitiveNether*)data;
if (!(self->walked_chunk))
walk_chunk(state, self);
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 = {
"nether", sizeof(RenderPrimitiveNether),
"nether",
sizeof(RenderPrimitiveNether),
NULL,
NULL,
NULL,

View File

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

View File

@ -18,15 +18,14 @@
#include "../overviewer.h"
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
due to how the nether is currently generated, this will also count
empty sections as 'solid'
*/
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) {
missing_section = 1;
y += 16;
@ -38,18 +37,18 @@ netherold_hidden(void *data, RenderState *state, int x, int y, int z) {
return 0;
missing_section = 0;
}
if (!missing_section && get_data(state, BLOCKS, x, y, z) == 0)
{
return 0;
}
if (!missing_section && get_data(state, BLOCKS, x, y, z) == 0) {
return 0;
}
y++;
}
return 1;
}
RenderPrimitiveInterface primitive_nether_old = {
"netherold", 0,
"netherold",
0,
NULL,
NULL,
NULL,

View File

@ -18,17 +18,18 @@
#include "../overviewer.h"
static int
no_fluids_start(void *data, RenderState *state, PyObject *support) {
no_fluids_start(void* data, RenderState* state, PyObject* support) {
return 0;
}
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);
}
RenderPrimitiveInterface primitive_no_fluids = {
"no-fluids", 0,
"no-fluids",
0,
no_fluids_start,
NULL,
NULL,

View File

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

View File

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

View File

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

View File

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

View File

@ -15,42 +15,43 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "overlay.h"
#include "../mc_id.h"
#include "overlay.h"
typedef enum { false, true } bool;
typedef enum { false,
true } bool;
typedef struct {
/* inherits from overlay */
RenderPrimitiveOverlay parent;
void *structures;
void* structures;
int numcolors;
} RenderPrimitiveStructure;
struct Condition{
struct Condition {
int relx, rely, relz;
unsigned short block;
};
struct Color {
int numconds;
struct Condition *conditions;
struct Condition* conditions;
unsigned char r, g, b, a;
};
static void get_color(void *data,
RenderState *state,
unsigned char *r,
unsigned char *g,
unsigned char *b,
unsigned char *a) {
static void get_color(void* data,
RenderState* state,
unsigned char* r,
unsigned char* g,
unsigned char* b,
unsigned char* 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;
struct Color *structures = (struct Color *)(self->structures);
struct Condition * c = NULL;
struct Color* structures = (struct Color*)(self->structures);
struct Condition* c = NULL;
bool all = true;
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.
**/
// iterate over all the colors
for ( col = 0; col < self->numcolors; col++) {
for (col = 0; col < self->numcolors; col++) {
// iterate over all y levels
for (y = state->chunky * -16; y <= y_max; y++) {
// iterate over all the conditions
for (cond = 0; cond < structures[col].numconds; cond++) {
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.
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;
break;
}
}
if (all){
if (all) {
// set the color
*r = structures[col].r;
*g = structures[col].g;
@ -85,12 +86,12 @@ static void get_color(void *data,
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
* appropriate structures. If no arguments are passed create and use default values.
**/
PyObject *opt;
PyObject* opt;
RenderPrimitiveStructure* self;
/* first, chain up */
@ -99,7 +100,7 @@ static int overlay_structure_start(void *data, RenderState *state, PyObject *sup
return ret;
/* now do custom initializations */
self = (RenderPrimitiveStructure *)data;
self = (RenderPrimitiveStructure*)data;
// opt is a borrowed reference. do not deref
// 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.
**/
if (opt && opt != Py_None) {
struct Color *structures = NULL;
struct Condition *cond = NULL;
struct Color* structures = NULL;
struct Condition* cond = NULL;
Py_ssize_t structures_size = 0, i, cond_size = 0, n = 0;
bool cont = true;
@ -135,11 +136,11 @@ static int overlay_structure_start(void *data, RenderState *state, PyObject *sup
**/
if (cont) {
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)
PyObject *condspy;
PyObject* condspy;
// 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.
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.
if (!PyArg_ParseTuple( colorpy, "bbbb",
&structures[i].r,
&structures[i].g,
&structures[i].b,
&structures[i].a)) {
if (!PyArg_ParseTuple(colorpy, "bbbb",
&structures[i].r,
&structures[i].g,
&structures[i].b,
&structures[i].a)) {
free(structures);
self->structures = NULL;
return 1;
@ -162,7 +163,7 @@ static int overlay_structure_start(void *data, RenderState *state, PyObject *sup
// Convert condspy to a fast sequence
condspy = PySequence_Fast(condspy, "Failed to parse conditions");
if(condspy == NULL) {
if (condspy == NULL) {
free(structures);
self->structures = NULL;
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.
for (n = 0; n < structures[i].numconds; n++) {
PyObject *ccond = PySequence_Fast_GET_ITEM(condspy, n);
if(!PyArg_ParseTuple( ccond, "iiib",
PyObject* ccond = PySequence_Fast_GET_ITEM(condspy, n);
if (!PyArg_ParseTuple(ccond, "iiib",
&cond[n].relx,
&cond[n].rely,
&cond[n].relz,
&cond[n].block)){
&cond[n].block)) {
int x = 0;
for(x = 0; x < structures_size; x++){
for (x = 0; x < structures_size; x++) {
free(structures[x].conditions);
}
free(structures);
@ -208,16 +209,16 @@ static int overlay_structure_start(void *data, RenderState *state, PyObject *sup
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 */
RenderPrimitiveStructure* self = (RenderPrimitiveStructure *)data;
RenderPrimitiveStructure* self = (RenderPrimitiveStructure*)data;
int i = 0;
if(self->structures) {
if (self->structures) {
// freeing the nested structure
struct Color * m = self->structures;
for(i = 0; i < self->numcolors; i++){
if(m[i].conditions)
struct Color* m = self->structures;
for (i = 0; i < self->numcolors; i++) {
if (m[i].conditions)
free(m[i].conditions);
}
}
@ -240,4 +241,3 @@ RenderPrimitiveInterface primitive_overlay_structure = {
NULL,
overlay_draw,
};

View File

@ -18,9 +18,9 @@
#include "overlay.h"
#include "../mc_id.h"
static void get_color(void *data, RenderState *state,
unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) {
RenderPrimitiveOverlay* self = (RenderPrimitiveOverlay *)data;
static void get_color(void* data, RenderState* state,
unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a) {
RenderPrimitiveOverlay* self = (RenderPrimitiveOverlay*)data;
*r = self->color->r;
*g = self->color->g;
@ -29,35 +29,35 @@ static void get_color(void *data, RenderState *state,
}
static int
overlay_start(void *data, RenderState *state, PyObject *support) {
PyObject *opt = NULL;
OverlayColor *color = NULL;
RenderPrimitiveOverlay *self = (RenderPrimitiveOverlay *)data;
overlay_start(void* data, RenderState* state, PyObject* support) {
PyObject* opt = NULL;
OverlayColor* color = NULL;
RenderPrimitiveOverlay* self = (RenderPrimitiveOverlay*)data;
self->facemask_top = PyObject_GetAttrString(support, "facemask_top");
self->white_color = PyObject_GetAttrString(support, "whitecolor");
self->get_color = get_color;
color = self->color = calloc(1, sizeof(OverlayColor));
if (color == NULL) {
return 1;
}
self->default_color.r = 200;
self->default_color.g = 200;
self->default_color.b = 255;
self->default_color.a = 155;
if(!render_mode_parse_option(support, "overlay_color", "bbbb", &(color->r), &(color->g), &(color->b), &(color->a))) {
if(PyErr_Occurred())
if (!render_mode_parse_option(support, "overlay_color", "bbbb", &(color->r), &(color->g), &(color->b), &(color->a))) {
if (PyErr_Occurred())
PyErr_Clear();
free(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
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(opt && opt != Py_None) {
if (opt && opt != Py_None) {
return 1;
}
}
@ -67,56 +67,55 @@ overlay_start(void *data, RenderState *state, PyObject *support) {
}
static void
overlay_finish(void *data, RenderState *state) {
RenderPrimitiveOverlay *self = (RenderPrimitiveOverlay *)data;
overlay_finish(void* data, RenderState* state) {
RenderPrimitiveOverlay* self = (RenderPrimitiveOverlay*)data;
if (self->color && self->color != &self->default_color) {
free(self->color);
}
Py_DECREF(self->facemask_top);
Py_DECREF(self->white_color);
}
void
overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
RenderPrimitiveOverlay *self = (RenderPrimitiveOverlay *)data;
void overlay_draw(void* data, RenderState* state, PyObject* src, PyObject* mask, PyObject* mask_light) {
RenderPrimitiveOverlay* self = (RenderPrimitiveOverlay*)data;
unsigned char r, g, b, a;
unsigned short top_block;
// exactly analogous to edge-line code for these special blocks
int increment=0;
if (state->block == block_stone_slab) // half-step
increment=6;
int increment = 0;
if (state->block == block_stone_slab) // half-step
increment = 6;
else if (state->block == block_snow_layer) // snow
increment=9;
increment = 9;
/* 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)) {
return;
}
/* check to be sure this block is solid/fluid */
if (block_has_property(top_block, SOLID) || block_has_property(top_block, FLUID)) {
/* top block is fluid or solid, skip drawing */
return;
}
/* check to be sure this block is solid/fluid */
if (!block_has_property(state->block, SOLID) && !block_has_property(state->block, FLUID)) {
/* not fluid or solid, skip drawing the overlay */
return;
}
/* get our color info */
self->get_color(data, state, &r, &g, &b, &a);
/* do the overlay */
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);
}
}

View File

@ -27,14 +27,14 @@ typedef struct {
/* color will be a pointer to either the default_color object below or
to a specially allocated color object that is instantiated from the
settings file */
OverlayColor *color;
OverlayColor* color;
OverlayColor default_color;
/* can be overridden in derived classes to control
overlay alpha and color
last four vars are r, g, b, a out */
void (*get_color)(void *, RenderState *,
unsigned char *, unsigned char *, unsigned char *, unsigned char *);
void (*get_color)(void*, RenderState*,
unsigned char*, unsigned char*, unsigned char*, unsigned char*);
} RenderPrimitiveOverlay;
extern RenderPrimitiveInterface primitive_overlay;
void overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light);
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/>.
*/
#include "../overviewer.h"
#include "../mc_id.h"
#include "../block_class.h"
#include "lighting.h"
#include <math.h>
#include "../block_class.h"
#include "../mc_id.h"
#include "../overviewer.h"
#include "lighting.h"
typedef struct {
/* inherits from lighting */
@ -30,7 +30,7 @@ typedef struct {
struct SmoothLightingCorner {
/* where this corner shows up on each block texture */
int imgx, imgy;
/* the two block offsets that (together) determine the 4 blocks to use */
int dx1, dy1, dz1;
int dx2, dy2, dz2;
@ -41,12 +41,12 @@ struct SmoothLightingFace {
/* offset from current coordinate to the block this face points towards
used for occlusion calculations, and as a base for later */
int dx, dy, dz;
/* the points that form the corners of this face */
struct SmoothLightingCorner corners[4];
/* 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;
};
@ -69,73 +69,51 @@ static struct SmoothLightingFace lighting_rules[] = {
// ...
*/
/* top */
{0, 1, 0, {
{0, 6,
-1, 0, 0,
0, 0, -1},
{12, 0,
1, 0, 0,
0, 0, -1},
{24, 6,
1, 0, 0,
0, 0, 1},
{12, 12,
-1, 0, 0,
0, 0, 1},
},
top_touchups, 6},
{0, 6, -1, 0, 0, 0, 0, -1},
{12, 0, 1, 0, 0, 0, 0, -1},
{24, 6, 1, 0, 0, 0, 0, 1},
{12, 12, -1, 0, 0, 0, 0, 1},
},
top_touchups,
6},
/* left */
{-1, 0, 0, {
{0, 18,
0, 0, -1,
0, -1, 0},
{0, 6,
0, 0, -1,
0, 1, 0},
{12, 12,
0, 0, 1,
0, 1, 0},
{12, 24,
0, 0, 1,
0, -1, 0},
},
NULL, 0},
{0, 18, 0, 0, -1, 0, -1, 0},
{0, 6, 0, 0, -1, 0, 1, 0},
{12, 12, 0, 0, 1, 0, 1, 0},
{12, 24, 0, 0, 1, 0, -1, 0},
},
NULL,
0},
/* right */
{0, 0, 1, {
{24, 6,
1, 0, 0,
0, 1, 0},
{12, 12,
-1, 0, 0,
0, 1, 0},
{12, 24,
-1, 0, 0,
0, -1, 0},
{24, 18,
1, 0, 0,
0, -1, 0},
},
NULL, 0},
{24, 6, 1, 0, 0, 0, 1, 0},
{12, 12, -1, 0, 0, 0, 1, 0},
{12, 24, -1, 0, 0, 0, -1, 0},
{24, 18, 1, 0, 0, 0, -1, 0},
},
NULL,
0},
};
/* helpers for indexing the rule list */
enum
{
enum {
FACE_TOP = 0,
FACE_LEFT = 1,
FACE_RIGHT = 2,
};
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;
RenderPrimitiveLighting *lighting = (RenderPrimitiveLighting *)self;
RenderPrimitiveLighting* lighting = (RenderPrimitiveLighting*)self;
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;
unsigned char pts_r[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 cy = state->y + face.dy;
int cz = state->z + face.dz;
/* first, check for occlusion if the block is in the local chunk */
if (lighting_is_face_occluded(state, 0, cx, cy, cz))
return;
/* 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 int rgather = 0, ggather = 0, bgather = 0;
get_lighting_color(lighting, state, cx, cy, cz,
&r, &g, &b);
rgather += r; ggather += g; bgather += b;
rgather += r;
ggather += g;
bgather += b;
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);
rgather += r; ggather += g; bgather += b;
rgather += r;
ggather += g;
bgather += b;
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);
rgather += r; ggather += g; bgather += b;
rgather += r;
ggather += g;
bgather += b;
/* FIXME special far corner handling */
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);
rgather += r; ggather += g; bgather += b;
rgather += (255*4 - rgather) * comp_shade_strength;
ggather += (255*4 - ggather) * comp_shade_strength;
bgather += (255*4 - bgather) * comp_shade_strength;
rgather += r;
ggather += g;
bgather += b;
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_g[i] = ggather / 4;
pts_b[i] = bgather / 4;
}
/* draw the face */
draw_triangle(state->img, 1,
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[2].imgx, y+pts[2].imgy, pts_r[2], pts_g[2], pts_b[2],
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[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);
draw_triangle(state->img, 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[3].imgx, y+pts[3].imgy, pts_r[3], pts_g[3], pts_b[3],
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[3].imgx, y + pts[3].imgy, pts_r[3], pts_g[3], pts_b[3],
x, y, NULL, 0);
}
static int
smooth_lighting_start(void *data, RenderState *state, PyObject *support) {
smooth_lighting_start(void* data, RenderState* state, PyObject* support) {
/* first, chain up */
int ret = primitive_lighting.start(data, state, support);
if (ret != 0)
return ret;
return ret;
return 0;
}
static void
smooth_lighting_finish(void *data, RenderState *state) {
smooth_lighting_finish(void* data, RenderState* state) {
/* nothing special to do */
primitive_lighting.finish(data, state);
}
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_left = 1;
int light_right = 1;
RenderPrimitiveSmoothLighting *self = (RenderPrimitiveSmoothLighting *)data;
RenderPrimitiveSmoothLighting* self = (RenderPrimitiveSmoothLighting*)data;
/* special case for leaves, water 8, water 9, ice 79
-- these are also smooth-lit! */
if (!block_class_is_subset(state->block, (mc_block_t[]){
block_leaves,block_flowing_water,block_water,block_ice
}, 4) && is_transparent(state->block))
{
if (!block_class_is_subset(state->block, (mc_block_t[]){block_leaves, block_flowing_water, block_water, block_ice}, 4) && is_transparent(state->block)) {
/* transparent blocks are rendered as usual, with flat lighting */
primitive_lighting.draw(data, state, src, mask, mask_light);
return;
}
/* non-transparent blocks get the special smooth treatment */
/* special code for water */
if (state->block == block_water)
{
if (state->block == block_water) {
if (!(state->block_pdata & (1 << 4)))
light_top = 0;
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)))
light_right = 0;
}
if (light_top)
do_shading_with_rule(self, state, lighting_rules[FACE_TOP]);
if (light_left)
@ -251,7 +232,8 @@ smooth_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *ma
}
RenderPrimitiveInterface primitive_smooth_lighting = {
"smooth-lighting", sizeof(RenderPrimitiveSmoothLighting),
"smooth-lighting",
sizeof(RenderPrimitiveSmoothLighting),
smooth_lighting_start,
smooth_lighting_finish,
NULL,

View File

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

View File

@ -47,20 +47,20 @@
/* render primitive interface */
typedef struct {
/* the name of this mode */
const char *name;
const char* name;
/* the size of the local storage for this rendermode */
unsigned int data_size;
/* may return non-zero on error, last arg is the python support object */
int (*start)(void *, RenderState *, PyObject *);
void (*finish)(void *, RenderState *);
int (*start)(void*, RenderState*, PyObject*);
void (*finish)(void*, RenderState*);
/* 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
* 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 */
void (*draw)(void *, RenderState *, PyObject *, PyObject *, PyObject *);
void (*draw)(void*, RenderState*, PyObject*, PyObject*, PyObject*);
} RenderPrimitiveInterface;
/* A quick note about the difference between occluded and hidden:
@ -80,26 +80,26 @@ typedef struct {
/* convenience wrapper for a single primitive + interface */
typedef struct {
void *primitive;
RenderPrimitiveInterface *iface;
void* primitive;
RenderPrimitiveInterface* iface;
} RenderPrimitive;
/* wrapper for passing around rendermodes */
struct _RenderMode {
unsigned int num_primitives;
RenderPrimitive **primitives;
RenderState *state;
RenderPrimitive** primitives;
RenderState* state;
};
/* functions for creating / using rendermodes */
RenderMode *render_mode_create(PyObject *mode, RenderState *state);
void render_mode_destroy(RenderMode *self);
int render_mode_occluded(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);
RenderMode* render_mode_create(PyObject* mode, RenderState* state);
void render_mode_destroy(RenderMode* self);
int render_mode_occluded(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);
/* helper function for reading in rendermode options
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__ */

View File

@ -8,11 +8,11 @@
/* like (a * b + 127) / 255), but much faster on most platforms
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))
#define OV_BLEND(mask, in1, in2, tmp1, tmp2)\
(OV_MULDIV255(in1, 255 - mask, tmp1) + OV_MULDIV255(in2, mask, tmp2))
#define OV_BLEND(mask, in1, in2, tmp1, tmp2) \
(OV_MULDIV255(in1, 255 - mask, tmp1) + OV_MULDIV255(in2, mask, tmp2))
#define COUNT_OF(array) \
(sizeof(array) / sizeof(array[0]))