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:
parent
676bf32af9
commit
8162f3f877
|
@ -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
|
||||
...
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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]))
|
||||
|
|
Loading…
Reference in New Issue