Skip to content

Commit

Permalink
new blocks up to Minecraft 1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
equalpants committed Dec 29, 2011
1 parent 9b009ec commit 9ff181f
Show file tree
Hide file tree
Showing 11 changed files with 873 additions and 208 deletions.
11 changes: 11 additions & 0 deletions README
Expand Up @@ -36,6 +36,13 @@ Use supplied makefile to build with g++.

Change log (important stuff only):

1.0
-NOTE: users of jcornwellshiel's fork will need to regenerate their blocks-B.png
-new blocks all the way up through Minecraft 1.0
-endportal.png added; must be placed in images directory alongside terrain.png
-fixed some ugliness in the rendering of cross-shaped item blocks (saplings, etc.)
-improved rendering of large block sizes (B > 8)

0.7.4
-new blocks for Minecraft Beta 1.6: tall grass, ferns, dead shrubs, trapdoors

Expand Down Expand Up @@ -238,6 +245,10 @@ blocks-B.png, but they must be copied to the new locations.

Complete list of block image moves:

--- pigmap 1.0 ---
beds: 232->281, 233->282, 234->283, 235->284, 236->285, 237->286, 238->287, 239->288
cake: 228->289

--- pigmap 0.6 ---
furnaces: 68->183, 69->186, 149->184, 150->185, 151->187, 152->188
fire: 48->189
Expand Down
710 changes: 611 additions & 99 deletions blockimages.cpp

Large diffs are not rendered by default.

230 changes: 138 additions & 92 deletions blockimages.h

Large diffs are not rendered by default.

Binary file added endportal.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions map.h
Expand Up @@ -22,6 +22,14 @@
#include <string>
#include <vector>

// IMPORTANT NOTE:
// This program was written before the location of the sun moved in Minecraft Beta 1.9 or so,
// therefore all of the N/S/E/W directions here are now wrong--rotated 90 degrees from what they
// should be. For example, the positive X direction used to be South, and is called South here,
// but is now East in the game (as of Minecraft 1.0, anyway).
// I decided to leave the old direction names here, because it would be pretty easy to mess
// something up trying to go through and change everything. Apologies for the confusion!

// Minecraft coord system:
//
// +x = S +z = W +y = U
Expand Down
18 changes: 18 additions & 0 deletions pigmap.cpp
Expand Up @@ -22,6 +22,8 @@
// -have signs actually face correct directions
// -edge shadows on vertical edges, too?
// -proper redstone wire directions
// -better dragon egg
// -extended pistons
// -premultiply block image alphas?
// -dump list of corrupted chunks at end, so they can be retried later
// -keep some space around for PNG row pointers instead of allocating every time
Expand Down Expand Up @@ -759,6 +761,21 @@ void testReqTileCount(const string& inputpath)
}
}

void testResize()
{
int sourceSize = 16;
for (int B = 2; B <= 16; B++)
{
int destSize = 2*B;
cout << "====== B: " << B << " destSize: " << destSize << " sourceSize: " << sourceSize << " ======" << endl;
for (int i = 0; i < destSize; i++)
{
int j = interpolate(i, destSize, sourceSize);
cout << i << " --> " << j << endl;
}
}
}

//-------------------------------------------------------------------------------------------------------------------

bool validateParamsFull(const string& inputpath, const string& outputpath, const string& imgpath, const MapParams& mp, int threads, const string& chunklist, const string& regionlist, bool expand, const string& htmlpath)
Expand Down Expand Up @@ -935,6 +952,7 @@ int main(int argc, char **argv)
//testZOrder();
//testTileIdxs();
//testReqTileCount(inputpath);
//testResize();

string inputpath, outputpath, imgpath = ".", chunklist, regionlist, htmlpath = ".";
MapParams mp(-1,-1,-1);
Expand Down
76 changes: 63 additions & 13 deletions render.cpp
Expand Up @@ -242,10 +242,27 @@ void checkSpecial(SceneGraphNode& node, uint8_t blockID, uint8_t blockData, cons
GETNEIGHBOR(blockIDS, blockDataS, BlockIdx(1,0,0))
GETNEIGHBOR(blockIDE, blockDataE, BlockIdx(0,-1,0))
GETNEIGHBOR(blockIDW, blockDataW, BlockIdx(0,1,0))
int bits = (blockIDN == 85 ? 0x1 : 0) | (blockIDS == 85 ? 0x2 : 0) | (blockIDE == 85 ? 0x4 : 0) | (blockIDW == 85 ? 0x8 : 0);
int bits = ((blockIDN == 85 || blockIDN == 107) ? 0x1 : 0) |
((blockIDS == 85 || blockIDS == 107) ? 0x2 : 0) |
((blockIDE == 85 || blockIDE == 107) ? 0x4 : 0) |
((blockIDW == 85 || blockIDW == 107) ? 0x8 : 0);
if (bits != 0)
node.bimgoffset = 157 + bits;
}
else if (blockID == 113) // nether fence
{
uint8_t blockIDN, blockDataN, blockIDE, blockDataE, blockIDS, blockDataS, blockIDW, blockDataW;
GETNEIGHBOR(blockIDN, blockDataN, BlockIdx(-1,0,0))
GETNEIGHBOR(blockIDS, blockDataS, BlockIdx(1,0,0))
GETNEIGHBOR(blockIDE, blockDataE, BlockIdx(0,-1,0))
GETNEIGHBOR(blockIDW, blockDataW, BlockIdx(0,1,0))
int bits = ((blockIDN == 113 || blockIDN == 107) ? 0x1 : 0) |
((blockIDS == 113 || blockIDS == 107) ? 0x2 : 0) |
((blockIDE == 113 || blockIDE == 107) ? 0x4 : 0) |
((blockIDW == 113 || blockIDW == 107) ? 0x8 : 0);
if (bits != 0)
node.bimgoffset = 316 + bits;
}
else if (blockID == 54) // chest
{
uint8_t blockIDN, blockDataN, blockIDE, blockDataE, blockIDS, blockDataS, blockIDW, blockDataW;
Expand All @@ -255,32 +272,65 @@ void checkSpecial(SceneGraphNode& node, uint8_t blockID, uint8_t blockData, cons
GETNEIGHBOR(blockIDW, blockDataW, BlockIdx(0,1,0))
// if there's another chest to the N, make this a southern half
if (blockIDN == 54)
node.bimgoffset = 174;
node.bimgoffset = (blockDataN == 3) ? 174 : 299;
// ...or if there's one to the S, make this a northern half
else if (blockIDS == 54)
node.bimgoffset = 173;
node.bimgoffset = (blockDataS == 3) ? 173 : 298;
// ...same deal with E/W
else if (blockIDW == 54)
node.bimgoffset = 175;
node.bimgoffset = (blockDataW == 4) ? 175 : 300;
else if (blockIDE == 54)
node.bimgoffset = 176;
// if this is a single chest, but there's an opaque block to the W, we should face N instead
// (note: technically just checking the blockID/blockData isn't correct, since the neighbor might
// itself require special processing, and might end up using a different block image, which might
// no longer be opaque--but nothing does that currently, and that would be one strange kind of block
// anyway, so the hell with it)
else if (rj.blockimages.isOpaque(blockIDW, blockDataW))
node.bimgoffset = 177;
node.bimgoffset = (blockDataE == 4) ? 176 : 301;
}
else if (blockID == 95) // locked chest
{
uint8_t blockIDW, blockDataW;
GETNEIGHBOR(blockIDW, blockDataW, BlockIdx(0,1,0))
// if there's an opaque block to the W, we should face N instead
// (also: see note above for regular chests)
if (rj.blockimages.isOpaque(blockIDW, blockDataW))
node.bimgoffset = 271;
}
else if (blockID == 101) // iron bars
{
uint8_t blockIDN, blockDataN, blockIDE, blockDataE, blockIDS, blockDataS, blockIDW, blockDataW;
GETNEIGHBOR(blockIDN, blockDataN, BlockIdx(-1,0,0))
GETNEIGHBOR(blockIDS, blockDataS, BlockIdx(1,0,0))
GETNEIGHBOR(blockIDE, blockDataE, BlockIdx(0,-1,0))
GETNEIGHBOR(blockIDW, blockDataW, BlockIdx(0,1,0))
// decide which edges to draw based on which neighbors are not air (zero neighbors gets the full cross)
int bits = (blockIDN != 0 ? 0x1 : 0) | (blockIDS != 0 ? 0x2 : 0) | (blockIDE != 0 ? 0x4 : 0) | (blockIDW != 0 ? 0x8 : 0);
static const int ironBarOffsets[16] = {355, 419, 420, 356, 421, 357, 359, 365, 422, 358, 360, 364, 361, 363, 362, 355};
node.bimgoffset = ironBarOffsets[bits];
}
else if (blockID == 102) // glass pane
{
uint8_t blockIDN, blockDataN, blockIDE, blockDataE, blockIDS, blockDataS, blockIDW, blockDataW;
GETNEIGHBOR(blockIDN, blockDataN, BlockIdx(-1,0,0))
GETNEIGHBOR(blockIDS, blockDataS, BlockIdx(1,0,0))
GETNEIGHBOR(blockIDE, blockDataE, BlockIdx(0,-1,0))
GETNEIGHBOR(blockIDW, blockDataW, BlockIdx(0,1,0))
// decide which edges to draw based on which neighbors are not air (zero neighbors gets the full cross)
int bits = (blockIDN != 0 ? 0x1 : 0) | (blockIDS != 0 ? 0x2 : 0) | (blockIDE != 0 ? 0x4 : 0) | (blockIDW != 0 ? 0x8 : 0);
static const int glassPaneOffsets[16] = {366, 423, 424, 367, 425, 368, 370, 376, 426, 369, 371, 375, 372, 374, 373, 366};
node.bimgoffset = glassPaneOffsets[bits];
}
else if ((blockID == 104 || blockID == 105) && blockData == 7) // full stem
{
uint8_t blockIDN, blockDataN, blockIDE, blockDataE, blockIDS, blockDataS, blockIDW, blockDataW;
GETNEIGHBOR(blockIDN, blockDataN, BlockIdx(-1,0,0))
GETNEIGHBOR(blockIDS, blockDataS, BlockIdx(1,0,0))
GETNEIGHBOR(blockIDE, blockDataE, BlockIdx(0,-1,0))
GETNEIGHBOR(blockIDW, blockDataW, BlockIdx(0,1,0))
int target = (blockID == 104) ? 86 : 103;
if (blockIDN == target)
node.bimgoffset = 403;
else if (blockIDS == target)
node.bimgoffset = 404;
else if (blockIDE == target)
node.bimgoffset = 405;
else if (blockIDW == target)
node.bimgoffset = 406;
}

//!!!!!!!! for now, only fully opaque blocks can have drop-off shadows, but some others like snow could
// probably use them, too
Expand Down
14 changes: 10 additions & 4 deletions rgba.cpp
Expand Up @@ -292,17 +292,16 @@ void reduceHalf(RGBAImage& dest, const ImageRect& drect, const RGBAImage& source




//!!!!!!!!! replace this with something non-idiotic? (it does surprisingly well, though!)
void resize(const RGBAImage& source, const ImageRect& srect, RGBAImage& dest, const ImageRect& drect)
{
for (int y = drect.y; y < drect.y + drect.h; y++)
{
float ypct = (float)(y - drect.y) / (float)(drect.h - 1);
int yoff = (int)(ypct * (float)(srect.h - 1));
int yoff = interpolate(y - drect.y, drect.h, srect.h);
for (int x = drect.x; x < drect.x + drect.w; x++)
{
float xpct = (float)(x - drect.x) / (float)(drect.w - 1);
int xoff = (int)(xpct * (float)(srect.w - 1));
int xoff = interpolate(x - drect.x, drect.w, srect.w);
dest(x, y) = source(srect.x + xoff, srect.y + yoff);
}
}
Expand Down Expand Up @@ -333,3 +332,10 @@ void blit(const RGBAImage& source, const ImageRect& srect, RGBAImage& dest, int3
for (int32_t xoff = xbegin, sx = srect.x + xbegin, dx = dxstart + xbegin; xoff < xend; xoff++, sx++, dx++)
dest(dx,dy) = source(sx,sy);
}

void flipX(RGBAImage& img, const ImageRect& rect)
{
for (int y = rect.y; y < rect.y + rect.h; y++)
for (int x1 = rect.x, x2 = rect.x + rect.w - 1; x1 < rect.x + rect.w/2; x1++, x2--)
swap(img(x1, y), img(x2, y));
}
3 changes: 3 additions & 0 deletions rgba.h
Expand Up @@ -88,4 +88,7 @@ void darken(RGBAImage& img, const ImageRect& rect, double r, double g, double b)
// copy source rect into destination rect of same size
void blit(const RGBAImage& source, const ImageRect& srect, RGBAImage& dest, int32_t dxstart, int32_t dystart);

// flip the target rect in the X direction
void flipX(RGBAImage& img, const ImageRect& rect);

#endif // RGBA_H
8 changes: 8 additions & 0 deletions utils.cpp
Expand Up @@ -240,6 +240,14 @@ int64_t mod64pos(int64_t a)
return (m == 0) ? 0 : (64 + m);
}

int64_t interpolate(int64_t i, int64_t destrange, int64_t srcrange)
{
double f = (double)i / (double)(destrange - 1);
f = f * (double)(srcrange - 1);
int64_t j = (int64_t)f;
return (f - (double)j >= 0.5) ? j+1 : j;
}



// technically, these use "upside-down-N-order", not Z-order--that is, the Y-coord is incremented
Expand Down
3 changes: 3 additions & 0 deletions utils.h
Expand Up @@ -63,6 +63,9 @@ int64_t ceildiv(int64_t a, int64_t b);
// positive remainder mod 64, for chunk subdirectories
int64_t mod64pos(int64_t a);

// given i in [0,destrange), find j in [0,srcrange)
int64_t interpolate(int64_t i, int64_t destrange, int64_t srcrange);


// take a row-major index into a SIZExSIZE array and convert it to Z-order
uint32_t toZOrder(uint32_t i, const uint32_t SIZE);
Expand Down

0 comments on commit 9ff181f

Please sign in to comment.