From d26fe3d9f8c3b298f628aa3f08edbd3656febb08 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 1 Feb 2015 11:58:50 +0100 Subject: Write PNG files No biome colors or light levels yet... --- CMakeLists.txt | 1 + src/CMakeLists.txt | 11 +-- src/MinedMap.cpp | 78 ++++++++++++++++-- src/World/BlockType.cpp | 208 ++++++++++++++++++++++++++++++++++++++++++++++++ src/World/BlockType.hpp | 42 ++++++++++ src/World/Chunk.cpp | 5 +- 6 files changed, 330 insertions(+), 15 deletions(-) create mode 100644 src/World/BlockType.cpp create mode 100644 src/World/BlockType.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f476f23..a96a79b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,7 @@ project(MINEDMAP CXX) find_package(PkgConfig REQUIRED) +pkg_check_modules(LIBPNG REQUIRED libpng>=1.2) pkg_check_modules(ZLIB REQUIRED zlib) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index df50419..dd10223 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,12 +1,13 @@ -include_directories(${ZLIB_INCLUDE_DIRS}) -link_directories(${ZLIB_LIBRARY_DIRS}) +include_directories(${ZLIB_INCLUDE_DIRS} ${LIBPNG_INCLUDE_DIRS}) +link_directories(${ZLIB_LIBRARY_DIRS} ${LIBPNG_LIBRARY_DIRS}) add_executable(MinedMap MinedMap.cpp NBT/Tag.cpp + World/BlockType.cpp World/Chunk.cpp World/Region.cpp ) -set_target_properties(MinedMap PROPERTIES COMPILE_FLAGS "-std=c++11 -Wall ${ZLIB_CFLAGS_OTHER}") -set_target_properties(MinedMap PROPERTIES LINK_FLAGS "${ZLIB_LDFLAGS_OTHER}") -target_link_libraries(MinedMap ${ZLIB_LIBRARIES}) +set_target_properties(MinedMap PROPERTIES COMPILE_FLAGS "-std=c++11 -Wall ${ZLIB_CFLAGS_OTHER} ${LIBPNG_CFLAGS_OTHER}") +set_target_properties(MinedMap PROPERTIES LINK_FLAGS "${ZLIB_LDFLAGS_OTHER} ${LIBPNG_LDFLAGS_OTHER}") +target_link_libraries(MinedMap ${ZLIB_LIBRARIES} ${LIBPNG_LIBRARIES}) diff --git a/src/MinedMap.cpp b/src/MinedMap.cpp index fea62ce..a95b6d6 100644 --- a/src/MinedMap.cpp +++ b/src/MinedMap.cpp @@ -24,25 +24,89 @@ */ +#include "World/BlockType.hpp" #include "World/Region.hpp" #include "NBT/ListTag.hpp" +#include +#include +#include #include -#include +#include +#include +#include -int main(int argc, char *argv[]) { - using namespace MinedMap; - if (argc < 2) { - std::cerr << "Usage: " << argv[0] << " region" << std::endl; +using namespace MinedMap; + + +static void writePNG(const char *filename, const uint32_t data[World::Region::SIZE*World::Chunk::SIZE][World::Region::SIZE*World::Chunk::SIZE]) { + std::FILE *f = std::fopen(filename, "wb"); + if (!f) + throw std::system_error(errno, std::generic_category(), "unable to open output file"); + + png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); + if (!png_ptr) + throw std::runtime_error("unable to create PNG write struct"); + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_write_struct(&png_ptr, nullptr); + throw std::runtime_error("unable to create PNG info struct"); + } + + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_write_struct(&png_ptr, &info_ptr); + fclose(f); + throw std::runtime_error("unable to write PNG file"); + } + + png_init_io(png_ptr, f); + + png_set_IHDR(png_ptr, info_ptr, World::Region::SIZE*World::Chunk::SIZE, World::Region::SIZE*World::Chunk::SIZE, + 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + uint8_t *row_pointers[World::Region::SIZE*World::Chunk::SIZE]; + for (size_t i = 0; i < World::Region::SIZE*World::Chunk::SIZE; i++) + row_pointers[i] = const_cast(reinterpret_cast(data[i])); + + png_set_rows(png_ptr, info_ptr, row_pointers); + png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); + + std::fclose(f); +} + +int main(int argc, char *argv[]) { + if (argc < 3) { + std::cerr << "Usage: " << argv[0] << " region output" << std::endl; return 1; } World::Region region(argv[1]); - const World::Chunk &chunk = *region(0, 0); - World::Chunk::Blocks layer = chunk.getTopLayer(); + uint32_t image[World::Region::SIZE*World::Chunk::SIZE][World::Region::SIZE*World::Chunk::SIZE] = {}; + + for (size_t X = 0; X < World::Region::SIZE; X++) { + for (size_t Z = 0; Z < World::Region::SIZE; Z++) { + const World::Chunk *chunk = region(X, Z); + if (!chunk) + continue; + + World::Chunk::Blocks layer = chunk->getTopLayer(); + + for (size_t x = 0; x < World::Chunk::SIZE; x++) { + for (size_t z = 0; z < World::Chunk::SIZE; z++) { + const World::BlockType &t = World::BLOCK_TYPES[layer.blocks[x][z].id]; + + if (t.opaque) + image[Z*World::Chunk::SIZE+z][X*World::Chunk::SIZE+x] = htonl((t.color << 8) | 0xff); + } + } + } + } + + writePNG(argv[2], image); return 0; } diff --git a/src/World/BlockType.cpp b/src/World/BlockType.cpp new file mode 100644 index 0000000..a65e3eb --- /dev/null +++ b/src/World/BlockType.cpp @@ -0,0 +1,208 @@ +/* + Copyright (c) 2015, Matthias Schiffer + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include "BlockType.hpp" + + +namespace MinedMap { +namespace World { + +const BlockType BLOCK_TYPES[256] = { + /* 0 */ {false, 0}, + /* 1 */ {true, 8224125}, + /* 2 */ {true, 9671571}, + /* 3 */ {true, 8806467}, + /* 4 */ {true, 8026746}, + /* 5 */ {true, 10256206}, + /* 6 */ {true, 4679205}, + /* 7 */ {true, 5460819}, + /* 8 */ {true, 3229684}, + /* 9 */ {true, 3032052}, + /* 10 */ {true, 13589267}, + /* 11 */ {true, 13916690}, + /* 12 */ {true, 14406560}, + /* 13 */ {true, 8289402}, + /* 14 */ {true, 9407356}, + /* 15 */ {true, 8880766}, + /* 16 */ {true, 7566195}, + /* 17 */ {true, 10124621}, + /* 18 */ {true, 8882055}, + /* 19 */ {true, 11974201}, + /* 20 */ {true, 14348532}, + /* 21 */ {true, 6713478}, + /* 22 */ {true, 2507657}, + /* 23 */ {true, 6316128}, + /* 24 */ {true, 14340766}, + /* 25 */ {true, 6570802}, + /* 26 */ {true, 9311766}, + /* 27 */ {true, 8678472}, + /* 28 */ {true, 7890265}, + /* 29 */ {true, 6316128}, + /* 30 */ {true, 14474460}, + /* 31 */ {false, 0}, + /* 32 */ {false, 0}, + /* 33 */ {true, 6316128}, + /* 34 */ {true, 10060121}, + /* 35 */ {true, 14540253}, + /* 36 */ {false, 0}, + /* 37 */ {false, 0}, + /* 38 */ {false, 0}, + /* 39 */ {false, 0}, + /* 40 */ {false, 0}, + /* 41 */ {true, 16378958}, + /* 42 */ {true, 14408667}, + /* 43 */ {true, 10461087}, + /* 44 */ {true, 10461087}, + /* 45 */ {true, 9593686}, + /* 46 */ {true, 8536367}, + /* 47 */ {true, 10256206}, + /* 48 */ {true, 6781287}, + /* 49 */ {true, 1315357}, + /* 50 */ {false, 0}, + /* 51 */ {true, 13863989}, + /* 52 */ {true, 1713969}, + /* 53 */ {true, 10256206}, + /* 54 */ {true, 10256206}, + /* 55 */ {true, 11213577}, + /* 56 */ {true, 8490127}, + /* 57 */ {true, 6413269}, + /* 58 */ {true, 7030570}, + /* 59 */ {true, 45842}, + /* 60 */ {true, 7555885}, + /* 61 */ {true, 6316128}, + /* 62 */ {true, 6316128}, + /* 63 */ {false, 0}, + /* 64 */ {true, 8807730}, + /* 65 */ {false, 0}, + /* 66 */ {true, 7957592}, + /* 67 */ {true, 8026746}, + /* 68 */ {false, 0}, + /* 69 */ {false, 0}, + /* 70 */ {true, 8224125}, + /* 71 */ {true, 10724259}, + /* 72 */ {true, 10256206}, + /* 73 */ {true, 8678251}, + /* 74 */ {true, 8678251}, + /* 75 */ {true, 11213577}, + /* 76 */ {true, 11213577}, + /* 77 */ {false, 0}, + /* 78 */ {true, 15727611}, + /* 79 */ {true, 8236543}, + /* 80 */ {true, 15727611}, + /* 81 */ {true, 877336}, + /* 82 */ {true, 10396848}, + /* 83 */ {true, 9748581}, + /* 84 */ {true, 7031095}, + /* 85 */ {true, 10256206}, + /* 86 */ {true, 12613141}, + /* 87 */ {true, 7288372}, + /* 88 */ {true, 5521459}, + /* 89 */ {true, 9401925}, + /* 90 */ {true, 5704383}, + /* 91 */ {true, 12613141}, + /* 92 */ {true, 14994894}, + /* 93 */ {true, 9933715}, + /* 94 */ {true, 10523539}, + /* 95 */ {true, 16777215}, + /* 96 */ {true, 8281389}, + /* 97 */ {true, 8224125}, + /* 98 */ {true, 8026746}, + /* 99 */ {true, 9267795}, + /* 100 */ {true, 11937060}, + /* 101 */ {true, 7171178}, + /* 102 */ {true, 14348532}, + /* 103 */ {true, 9935140}, + /* 104 */ {false, 0}, + /* 105 */ {false, 0}, + /* 106 */ {true, 7303023}, + /* 107 */ {true, 10256206}, + /* 108 */ {true, 9593686}, + /* 109 */ {true, 8026746}, + /* 110 */ {true, 7299945}, + /* 111 */ {true, 7763574}, + /* 112 */ {true, 2889242}, + /* 113 */ {true, 2889242}, + /* 114 */ {true, 2889242}, + /* 115 */ {true, 6950430}, + /* 116 */ {true, 6766651}, + /* 117 */ {true, 6974058}, + /* 118 */ {true, 3618615}, + /* 119 */ {true, 788751}, + /* 120 */ {true, 5862752}, + /* 121 */ {true, 14540709}, + /* 122 */ {true, 788751}, + /* 123 */ {true, 4598554}, + /* 124 */ {true, 7821623}, + /* 125 */ {true, 10256206}, + /* 126 */ {true, 10256206}, + /* 127 */ {true, 9079872}, + /* 128 */ {true, 14340766}, + /* 129 */ {true, 7176308}, + /* 130 */ {true, 788751}, + /* 131 */ {false, 0}, + /* 132 */ {false, 0}, + /* 133 */ {true, 5364085}, + /* 134 */ {true, 6769966}, + /* 135 */ {true, 12825467}, + /* 136 */ {true, 10120781}, + /* 137 */ {true, 11700591}, + /* 138 */ {true, 7658967}, + /* 139 */ {true, 8026746}, + /* 140 */ {true, 7749939}, + /* 141 */ {true, 109328}, + /* 142 */ {true, 109328}, + /* 143 */ {false, 0}, + /* 144 */ {false, 0}, + /* 145 */ {true, 4209724}, + /* 146 */ {true, 10256206}, + /* 147 */ {true, 16378958}, + /* 148 */ {true, 14408667}, + /* 149 */ {true, 10262165}, + /* 150 */ {true, 10851732}, + /* 151 */ {true, 8549470}, + /* 152 */ {true, 11213577}, + /* 153 */ {true, 8213583}, + /* 154 */ {true, 3618615}, + /* 155 */ {true, 15526370}, + /* 156 */ {true, 15526370}, + /* 157 */ {true, 6837063}, + /* 158 */ {true, 6316128}, + /* 159 */ {true, 13742753}, + /* 160 */ {true, 16777215}, + /* 161 */ {true, 8882055}, + /* 162 */ {true, 10115904}, + /* 163 */ {true, 11098931}, + /* 164 */ {true, 4007698}, + /* 170 */ {true, 11045648}, + /* 171 */ {true, 14540253}, + /* 172 */ {true, 9854018}, + /* 173 */ {true, 1184274}, + /* 174 */ {true, 10863349}, + /* 175 */ {false, 0}, +}; + +} +} diff --git a/src/World/BlockType.hpp b/src/World/BlockType.hpp new file mode 100644 index 0000000..d131487 --- /dev/null +++ b/src/World/BlockType.hpp @@ -0,0 +1,42 @@ +/* + Copyright (c) 2015, Matthias Schiffer + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#pragma once + +#include + +namespace MinedMap { +namespace World { + +struct BlockType { + bool opaque; + uint32_t color; +}; + +extern const BlockType BLOCK_TYPES[256]; + +} +} diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index 2dc9014..99d40a5 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -25,6 +25,7 @@ #include "Chunk.hpp" +#include "BlockType.hpp" #include "../Util.hpp" #include "../NBT/ByteTag.hpp" #include "../NBT/ByteArrayTag.hpp" @@ -143,7 +144,7 @@ Chunk::Blocks Chunk::getTopLayer() const { continue; uint8_t block = getBlockAt(*it, x, y, z); - if (block) { + if (BLOCK_TYPES[block].opaque) { blocks.blocks[x][z].id = block; blocks.blocks[x][z].data = getDataAt(*it, x, y, z); done++; @@ -153,8 +154,6 @@ Chunk::Blocks Chunk::getTopLayer() const { } } - std::cerr << "Done: " << done << std::endl; - return blocks; } -- cgit v1.2.3