forked from equalpants/pigmap
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathblockimages.h
132 lines (114 loc) · 6.69 KB
/
blockimages.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright 2010-2012 Michael J. Nelson
//
// This file is part of pigmap.
//
// pigmap is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// pigmap is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with pigmap. If not, see <http://www.gnu.org/licenses/>.
#ifndef BLOCKIMAGES_H
#define BLOCKIMAGES_H
#include <stdint.h>
#include "rgba.h"
// 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!
// EDIT: (Akudeu Kie)
// Since in 1.5 terrain.png will be deprecated and new texture format will be introduced,
// programm requires some rewriting anyway, so orientation is changed accordingly (N -> W, W -> S, S -> E, E -> N)
// this structure holds the block images used to build the map; each block image is a hexagonal shape within
// a 4Bx4B rectangle, with the unused area around it set to fully transparent
//
// example of hexagon shape for B = 3, where U represents pixels belonging to the U-facing side of the block, etc.:
//
// UU
// UUUUUU
// UUUUUUUUUU
// WUUUUUUUUUUS
// WWWUUUUUUSSS
// WWWWWUUSSSSS
// WWWWWWSSSSSS
// WWWWWWSSSSSS
// WWWWWWSSSSSS
// WWWWWSSSSS
// WWWSSS
// WS
//
// when supplying your own block images, there's nothing to stop you from going "out of bounds" and having
// non-transparent pixels outside the hexagon, but you'll just get a messed-up image, since the renderer
// uses only the hexagon to determine visibility, etc.
//
// note that translucent blocks require the most work to render, simply because you can see what's behind them;
// if every block in the world was translucent, for example, then every block would be considered visible
// ...so if you're editing the block images for special purposes like X-ray vision, the fastest results are
// obtained by making unwanted blocks fully transparent, not just translucent
// ...also, any pixels in the block images with alphas < 10 will have their alphas set to 0, and similarly
// any alphas > 245 will be set to 255; this is to prevent massive slowdown from accidental image-editing
// cock-ups, like somehow setting the transparency of the whole image to 99% instead of 100%, etc.
//
// most block images are created by resizing the relevant terrain.png images from 16x16 to 2Bx2B, then painting
// their columns onto the faces of the block image thusly (example is for B = 3 again):
//
// a f
// abcdef ab abc def
// abcdef aabbcd abcde bcdef
// abcdef ---> aabbccddef or abcdef or abcdef
// abcdef abccddeeff abcdef abcdef
// abcdef cdeeff abcdef abcdef
// abcdef ef bcdef abcde
// def abc
// f a
struct BlockImages
{
// this image holds all the block images, in rows of 16 (so its width is 4B*16; height depends on number of rows)
// ...the very first block image is a dummy one, fully transparent, for use with unrecognized blocks
RGBAImage img;
int rectsize; // size of block image bounding boxes
int blockversion; // version of the blocks-B.png
std::vector< std::vector< std::string > > blockDescriptors; // vector holding block type and block texture descriptions
// for every possible 12-bit block id/4-bit block data combination, this holds the offset into the image
// (unrecognized id/data values are pointed at the dummy block image)
// this doesn't handle some things like fences and double chests where the rendering doesn't depend solely
// on the blockID/blockData; for those, the renderer just has to know the proper offsets on its own
int blockOffsets[4096 * 16];
int getOffset(uint16_t blockID, uint8_t blockData) const {return blockOffsets[blockID * 16 + blockData];}
// check whether a block image is opaque (this is a function of the block images computed from the terrain,
// not of the actual block data; if a block image has 100% alpha everywhere, it's considered opaque)
std::vector<bool> opacity; // size is blockversion; indexed by offset
bool isOpaque(int offset) const {return opacity[offset];}
bool isOpaque(uint16_t blockID, uint8_t blockData) const {return opacity[getOffset(blockID, blockData)];}
// ...and the same thing for complete transparency (0% alpha everywhere)
std::vector<bool> transparency; // size is blockversion; indexed by offset
bool isTransparent(int offset) const {return transparency[offset];}
bool isTransparent(uint16_t blockID, uint8_t blockData) const {return transparency[getOffset(blockID, blockData)];}
// get the rectangle in img corresponding to an offset
ImageRect getRect(int offset) const {return ImageRect((offset%16)*rectsize, (offset/16)*rectsize, rectsize, rectsize);}
ImageRect getRect(uint16_t blockID, uint8_t blockData) const {return getRect(getOffset(blockID, blockData));}
// attempt to create a BlockImages structure: look for blocks-B.png in the imgpath, where B is the block size
// parameter; failing that, look for terrain.png and construct a new blocks-B.png from it; failing that, uh, fail
bool create(int B, const std::string& imgpath);
// create vector with block descriptors, used for offset assignment and block images construction
void setBlockDescriptors(std::ifstream& descriptorlist);
// set the offsets
int setOffsets();
// fill in the opacity and transparency members
void checkOpacityAndTransparency(int B);
// scan the block images looking for not-quite-transparent or not-quite-opaque pixels; if they're close enough,
// push them all the way
void retouchAlphas(int B);
// build block images from terrain.png, etc.
bool construct(int B, std::ifstream& texturelist, std::ifstream& descriptorlist, const std::string& imgpath);
};
#endif // BLOCKIMAGES_H