Initial commit
commit
117a3cfe60
|
@ -0,0 +1,71 @@
|
|||
PROGNAME = mcconvert
|
||||
rm = /bin/rm -f
|
||||
CC = cc
|
||||
CXX = c++
|
||||
AS = as
|
||||
DEFS = -Wno-multichar
|
||||
INCLUDES = -I. -I/usr/local/include
|
||||
LIBS = -L/usr/local/lib -lz -lsqlite3
|
||||
DEFINES = $(INCLUDES) $(DEFS) -DSYS_UNIX=1
|
||||
|
||||
CFLAGS = -pipe -Wall -O3 $(DEFINES)
|
||||
CXXFLAGS = -pipe -Wall -O3 $(DEFINES)
|
||||
ASFLAGS =
|
||||
|
||||
SOURCES = db.c \
|
||||
mapcontent.c \
|
||||
mcconvert.c \
|
||||
vector.c
|
||||
|
||||
OBJECTS = ${SOURCES:.c=.o}
|
||||
SRCS = ${addprefix src/,$(SOURCES)}
|
||||
OBJS = ${addprefix obj/,$(OBJECTS)}
|
||||
|
||||
.SILENT:
|
||||
|
||||
obj/%.o: src/%.c
|
||||
mkdir -p $(@D);
|
||||
#$(rm) $@;
|
||||
if ${CC} ${CFLAGS} -c -o $@ $<; then \
|
||||
printf "\033[32mbuilt $@.\033[m\n"; \
|
||||
else \
|
||||
printf "\033[31mbuild of $@ failed!\033[m\n"; \
|
||||
false; \
|
||||
fi
|
||||
|
||||
obj/%.o: src/%.cpp
|
||||
mkdir -p $(@D);
|
||||
$(rm) $@;
|
||||
if ${CXX} ${CXXFLAGS} -c -o $@ $<; then \
|
||||
printf "\033[32mbuilt $@.\033[m\n"; \
|
||||
else \
|
||||
printf "\033[31mbuild of $@ failed!\033[m\n"; \
|
||||
false; \
|
||||
fi
|
||||
|
||||
obj/%.o: src/%.s
|
||||
mkdir -p $(@D);
|
||||
$(rm) $@;
|
||||
if ${AS} ${ASFLAGS} $< -o $@; then \
|
||||
printf "\033[32mbuilt $@.\033[m\n"; \
|
||||
else \
|
||||
printf "\033[31mbuild of $@ failed!\033[m\n"; \
|
||||
false; \
|
||||
fi
|
||||
|
||||
all: $(PROGNAME)
|
||||
|
||||
debug: CFLAGS = -pipe -Wall -g $(DEFINES)
|
||||
debug: $(PROGNAME)
|
||||
|
||||
$(PROGNAME) : $(OBJS)
|
||||
if $(CC) $(CFLAGS) -o $(PROGNAME) $(OBJS) $(LIBS); then \
|
||||
printf "\033[32mlinked $@.\033[m\n"; \
|
||||
else \
|
||||
printf "\033[31mlink of $@ failed!\033[m\n"; \
|
||||
false; \
|
||||
fi
|
||||
|
||||
clean:
|
||||
$(rm) $(PROGNAME) core *~
|
||||
$(rm) -rf obj/*
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<CodeBlocks_project_file>
|
||||
<FileVersion major="1" minor="6" />
|
||||
<Project>
|
||||
<Option title="mcconvert" />
|
||||
<Option pch_mode="2" />
|
||||
<Option compiler="gcc" />
|
||||
<Build>
|
||||
<Target title="Debug">
|
||||
<Option output="bin/Debug/mcconvert" prefix_auto="1" extension_auto="1" />
|
||||
<Option object_output="obj/Debug/" />
|
||||
<Option type="1" />
|
||||
<Option compiler="gcc" />
|
||||
<Option parameters="/usr/home/ryan/Desktop/asdf_uncompressed.mine" />
|
||||
<Compiler>
|
||||
<Add option="-g" />
|
||||
</Compiler>
|
||||
</Target>
|
||||
<Target title="Release">
|
||||
<Option output="bin/Release/mcconvert" prefix_auto="1" extension_auto="1" />
|
||||
<Option object_output="obj/Release/" />
|
||||
<Option type="1" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-O2" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
</Linker>
|
||||
</Target>
|
||||
</Build>
|
||||
<Compiler>
|
||||
<Add option="-Wall" />
|
||||
<Add directory="/usr/local/include" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add library="/usr/lib/libz.so" />
|
||||
<Add library="/usr/local/lib/libsqlite3.so" />
|
||||
</Linker>
|
||||
<Unit filename="src/db.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="src/db.h" />
|
||||
<Unit filename="src/mapcontent.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="src/mapcontent.h" />
|
||||
<Unit filename="src/mcconvert.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="src/mcconvert.h" />
|
||||
<Unit filename="src/vector.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="src/vector.h" />
|
||||
<Extensions>
|
||||
<envvars />
|
||||
<code_completion />
|
||||
<lib_finder disable_auto="1" />
|
||||
<debugger />
|
||||
</Extensions>
|
||||
</Project>
|
||||
</CodeBlocks_project_file>
|
|
@ -0,0 +1,132 @@
|
|||
/*-
|
||||
* Copyright (c) 2013 Ryan Kwolek <kwolekr@minetest.net>.
|
||||
* 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 AUTHOR 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* db.c -
|
||||
* Routines related to database manipulation
|
||||
*/
|
||||
|
||||
#include "mcconvert.h"
|
||||
#include "mapcontent.h"
|
||||
#include "db.h"
|
||||
|
||||
sqlite3 *m_database = NULL;
|
||||
sqlite3_stmt *m_database_read = NULL;
|
||||
sqlite3_stmt *m_database_write = NULL;
|
||||
sqlite3_stmt *m_database_list = NULL;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void DBCreate() {
|
||||
int e = sqlite3_exec(m_database,
|
||||
"CREATE TABLE IF NOT EXISTS `blocks` ("
|
||||
"`pos` INT NOT NULL PRIMARY KEY,"
|
||||
"`data` BLOB"
|
||||
");", NULL, NULL, NULL);
|
||||
if (e == SQLITE_ABORT)
|
||||
fprintf(stderr, "Could not create database structure\n");
|
||||
else
|
||||
printf("Database structure was created\n");
|
||||
}
|
||||
|
||||
|
||||
int DBVerify() {
|
||||
if (!m_database) {
|
||||
int needs_create;
|
||||
int d;
|
||||
|
||||
needs_create = 1; //!stat(OUTPUT_FILENAME, NULL);
|
||||
|
||||
d = sqlite3_open_v2(OUTPUT_FILENAME, &m_database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
|
||||
if (d != SQLITE_OK) {
|
||||
fprintf(stderr, "WARNING: Database failed to open: %s\n", sqlite3_errmsg(m_database));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (needs_create)
|
||||
DBCreate();
|
||||
|
||||
d = sqlite3_prepare(m_database, "SELECT `data` FROM `blocks` WHERE `pos`=? LIMIT 1", -1, &m_database_read, NULL);
|
||||
if (d != SQLITE_OK) {
|
||||
fprintf(stderr, "WARNING: Database read statment failed to prepare: %s\n", sqlite3_errmsg(m_database));
|
||||
return 0;
|
||||
}
|
||||
|
||||
d = sqlite3_prepare(m_database, "REPLACE INTO `blocks` VALUES(?, ?)", -1, &m_database_write, NULL);
|
||||
if (d != SQLITE_OK) {
|
||||
fprintf(stderr, "WARNING: Database write statment failed to prepare: %s\n", sqlite3_errmsg(m_database));
|
||||
return 0;
|
||||
}
|
||||
|
||||
d = sqlite3_prepare(m_database, "SELECT `pos` FROM `blocks`", -1, &m_database_list, NULL);
|
||||
if (d != SQLITE_OK) {
|
||||
fprintf(stderr, "WARNING: Database list statment failed to prepare: %s\n", sqlite3_errmsg(m_database));
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("Database opened\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int DBSaveMapBlock(MapBlock *block) {
|
||||
DBVerify();
|
||||
|
||||
// To make things easy, just guess the needed size of the buffer.
|
||||
// This seems like a generous enough amount.
|
||||
u8 *output = malloc(0x20000);
|
||||
size_t outlen = MapBlockSerialize(block, output);
|
||||
if (outlen > 0x20000) {
|
||||
fprintf(stderr, "UH OH, serialized output was too big\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int success = 0;
|
||||
if (sqlite3_exec(m_database, "BEGIN;", NULL, NULL, NULL) != SQLITE_OK)
|
||||
fprintf(stderr, "WARNING: begin save failed, saving might be slow.\n");
|
||||
|
||||
if (sqlite3_bind_int64(m_database_write, 1, MapBlockPosToInteger(block->pos)) != SQLITE_OK)
|
||||
fprintf(stderr, "WARNING: Block position failed to bind: %s\n", sqlite3_errmsg(m_database));
|
||||
|
||||
if (sqlite3_bind_blob(m_database_write, 2, output, outlen, NULL) != SQLITE_OK)
|
||||
fprintf(stderr, "WARNING: Block data failed to bind: %s\n", sqlite3_errmsg(m_database));
|
||||
|
||||
int written = sqlite3_step(m_database_write);
|
||||
if (written != SQLITE_DONE)
|
||||
fprintf(stderr, "ERROR: Block failed to save (%d, %d, %d) %s\n",
|
||||
block->pos.X, block->pos.Y, block->pos.Z, sqlite3_errmsg(m_database));
|
||||
|
||||
success = 1;
|
||||
|
||||
sqlite3_reset(m_database_write);
|
||||
if (sqlite3_exec(m_database, "COMMIT;", NULL, NULL, NULL) != SQLITE_OK)
|
||||
fprintf(stderr, "WARNING: end save failed, map might not have saved.\n");
|
||||
|
||||
free(output);
|
||||
|
||||
return success;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*-
|
||||
* Copyright (c) 2013 Ryan Kwolek <kwolekr@minetest.net>.
|
||||
* 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 AUTHOR 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#ifndef DB_HEADER
|
||||
#define DB_HEADER
|
||||
|
||||
extern sqlite3 *m_database;
|
||||
extern sqlite3_stmt *m_database_read;
|
||||
extern sqlite3_stmt *m_database_write;
|
||||
extern sqlite3_stmt *m_database_list;
|
||||
|
||||
void DBCreate();
|
||||
int DBVerify();
|
||||
int DBSaveMapBlock(MapBlock *block);
|
||||
|
||||
#endif // DB_HEADER
|
|
@ -0,0 +1,233 @@
|
|||
/*-
|
||||
* Copyright (c) 2013 Ryan Kwolek <kwolekr@minetest.net>.
|
||||
* 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 AUTHOR 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* mapcontent.c -
|
||||
* Routines pertaining to map node names, name-id mapping, and map block serialization
|
||||
*/
|
||||
|
||||
#include "mcconvert.h"
|
||||
#include "mapcontent.h"
|
||||
|
||||
const char *node_names[] = {
|
||||
"air",
|
||||
"default:stone",
|
||||
"default:dirt_with_grass",
|
||||
"default:dirt",
|
||||
"default:cobble",
|
||||
"default:wood",
|
||||
"default:sapling",
|
||||
"default:cloud", //actually bedrock, but this is indestructable as well
|
||||
"default:water_flowing",
|
||||
"default:water_source",
|
||||
|
||||
"default:lava_flowing",
|
||||
"default:lava_source",
|
||||
"default:sand",
|
||||
"default:gravel",
|
||||
"default:stone_with_mese",
|
||||
"default:stone_with_iron",
|
||||
"default:stone_with_coal",
|
||||
"default:tree",
|
||||
"default:leaves",
|
||||
"default:nyancat_rainbow", //sponge...
|
||||
|
||||
"default:glass",
|
||||
"wool:red", //red
|
||||
"wool:orange", //orange
|
||||
"wool:yellow", //yellow
|
||||
"wool:green", //lightgreen
|
||||
"wool:green", //green
|
||||
"wool:darkgreen", //aquagreen
|
||||
"wool:cyan", //cyan
|
||||
"wool:blue", //lightblue
|
||||
"wool:blue", //blue
|
||||
"wool:violet", //purple
|
||||
"wool:violet", //lightpurple
|
||||
"wool:pink", //pink
|
||||
"wool:magenta", //darkpink
|
||||
"wool:dark_grey", //darkgrey
|
||||
"wool:grey", //lightgrey
|
||||
"wool:white", //white
|
||||
"", //yellow flower
|
||||
"", //red flower
|
||||
"", //mushroom1
|
||||
|
||||
"", //mushroom2
|
||||
"default:mese",
|
||||
"default:steelblock",
|
||||
"default:cobble", //full step
|
||||
"stairs:slab_cobble", //half step
|
||||
"default:brick",
|
||||
"", //tnt
|
||||
"default:bookshelf",
|
||||
"default:mossycobble",
|
||||
"default:obsidian"
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
sqlite3_int64 MapBlockPosToInteger(const v3s16 pos) {
|
||||
return (sqlite3_int64)pos.Z * 16777216 +
|
||||
(sqlite3_int64)pos.Y * 4096 +
|
||||
(sqlite3_int64)pos.X;
|
||||
}
|
||||
|
||||
|
||||
LPVECTOR MapBlockCreateMappingTableAndFixNodes(MapNode *nodes, size_t nnodes) {
|
||||
u8 global_to_relative_id_map[ARRAYLEN(node_names)];
|
||||
LPVECTOR names_seen = NULL;
|
||||
int i;
|
||||
u8 id, global_id, relative_id, num_ids = 0;
|
||||
|
||||
memset(global_to_relative_id_map, 0xFF, sizeof(global_to_relative_id_map));
|
||||
|
||||
for (i = 0; i != nnodes; i++) {
|
||||
global_id = nodes[i].param0;
|
||||
if (global_id >= ARRAYLEN(node_names)) {
|
||||
fprintf(stderr, "ERROR: Invalid node ID 0x%04x\n", (u16)global_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
relative_id = global_to_relative_id_map[global_id];
|
||||
if (relative_id != 0xFF) {
|
||||
id = relative_id;
|
||||
} else {
|
||||
if (*node_names[global_id]) {
|
||||
id = num_ids;
|
||||
num_ids++;
|
||||
|
||||
global_to_relative_id_map[global_id] = id;
|
||||
VectorAdd(&names_seen, node_names[global_id]);
|
||||
} else {
|
||||
id = 0; //just make it anything, whatever the first node was
|
||||
}
|
||||
}
|
||||
nodes[i].param0 = id;
|
||||
}
|
||||
|
||||
return names_seen;
|
||||
}
|
||||
|
||||
|
||||
size_t MapBlockSerialize(MapBlock *block, u8 *outbuf) {
|
||||
u8 *os = outbuf;
|
||||
u8 *compressed_data;
|
||||
size_t compressed_len;
|
||||
LPVECTOR names_seen;
|
||||
|
||||
// MapBlock serialization version
|
||||
InsertU8(os, 25);
|
||||
|
||||
// Flag byte
|
||||
u8 flags = 0;
|
||||
InsertU8(os, flags);
|
||||
|
||||
// Bulk node data
|
||||
u32 nodecount = MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE;
|
||||
|
||||
u8 content_width = 2;
|
||||
u8 params_width = 2;
|
||||
InsertU8(os, content_width);
|
||||
InsertU8(os, params_width);
|
||||
|
||||
names_seen = MapBlockCreateMappingTableAndFixNodes(block->data, nodecount);
|
||||
if (!names_seen) {
|
||||
fprintf(stderr, "crap\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
MapNodeSerializeBulk(block->data, nodecount, &compressed_data, &compressed_len);
|
||||
memcpy(os, compressed_data, compressed_len);
|
||||
os += compressed_len;
|
||||
free(compressed_data);
|
||||
|
||||
// Node metadata
|
||||
u8 buf[4];
|
||||
WriteU8(buf, 0); //version 1 for real data, 0 for "go away"
|
||||
ZLibCompress(buf, 1, &compressed_data, &compressed_len);
|
||||
|
||||
memcpy(os, compressed_data, compressed_len);
|
||||
os += compressed_len;
|
||||
free(compressed_data);
|
||||
|
||||
// Static objects
|
||||
InsertU8(os, 0);
|
||||
InsertU16(os, 0);
|
||||
|
||||
// Timestamp
|
||||
InsertU32(os, 0xFFFFFFFF);
|
||||
|
||||
// Write block-specific node definition id mapping
|
||||
InsertU8(os, 0);
|
||||
InsertU16(os, names_seen->numelem); //num ids
|
||||
int i;
|
||||
for (i = 0; i != names_seen->numelem; i++) {
|
||||
size_t len;
|
||||
|
||||
InsertU16(os, i);
|
||||
len = strlen(names_seen->elem[i]);
|
||||
InsertU16(os, len);
|
||||
memcpy(os, names_seen->elem[i], len);
|
||||
os += len;
|
||||
}
|
||||
free(names_seen);
|
||||
|
||||
InsertU8(os, 2+4+4);
|
||||
InsertU16(os, 0); //number of timers, none
|
||||
|
||||
return os - outbuf;
|
||||
}
|
||||
|
||||
|
||||
void MapNodeSerializeBulk(const MapNode *nodes, u32 nodecount,
|
||||
u8 **outbuf, size_t *outlen) {
|
||||
unsigned int i;
|
||||
size_t datalen = nodecount * sizeof(MapNode);
|
||||
u8 *databuf = malloc(datalen);
|
||||
u8 *d = databuf;
|
||||
|
||||
// Serialize content
|
||||
for (i = 0; i != nodecount; i++) {
|
||||
WriteU16(d, nodes[i].param0);
|
||||
d += sizeof(nodes[i].param0);
|
||||
}
|
||||
|
||||
// Serialize param1
|
||||
for (i = 0; i != nodecount; i++) {
|
||||
WriteU8(d, nodes[i].param1);
|
||||
d += sizeof(nodes[i].param1);
|
||||
}
|
||||
|
||||
// Serialize param2
|
||||
for (i = 0; i != nodecount; i++) {
|
||||
WriteU8(d, nodes[i].param2);
|
||||
d += sizeof(nodes[i].param2);
|
||||
}
|
||||
|
||||
ZLibCompress(databuf, datalen, outbuf, outlen);
|
||||
|
||||
free(databuf);
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*-
|
||||
* Copyright (c) 2013 Ryan Kwolek <kwolekr@minetest.net>.
|
||||
* 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 AUTHOR 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Disk serialized MapBlock format:
|
||||
|
||||
(u8) version = 8
|
||||
|
||||
basic information
|
||||
(u8) flags = 0
|
||||
(u8) content width = 2
|
||||
(u8) params width = 2
|
||||
|
||||
node data
|
||||
ZLib deflate {
|
||||
for each node:
|
||||
(u16) param0
|
||||
for each node:
|
||||
(u8) param1
|
||||
for each node:
|
||||
(u8) param2
|
||||
}
|
||||
|
||||
ZLib deflate {
|
||||
node metadata list
|
||||
(u8) version = 1
|
||||
(s16) count
|
||||
for each nodemetadata:
|
||||
()
|
||||
}
|
||||
|
||||
static object list
|
||||
(u8) version = 0
|
||||
(u16) count
|
||||
for each stored object:
|
||||
()
|
||||
for each active object:
|
||||
()
|
||||
|
||||
name-id mapping
|
||||
(u8) version = 0
|
||||
(u16) count
|
||||
for each name-id mapping:
|
||||
(u16) id = ids are of what first occur in the block, start at 0
|
||||
(u16) name length
|
||||
(u8[]) name
|
||||
|
||||
node timer list
|
||||
(u8) version = 10
|
||||
(u16) count
|
||||
*/
|
||||
|
||||
/*
|
||||
Sample data:
|
||||
|
||||
19 ;mapblock version
|
||||
08 ;flags
|
||||
02 ;content width
|
||||
02 ;params width
|
||||
789CEDC13101000000C2A0F54F6D0C1FA000000000000000000000000000000080B70140000001789C63000000010001000000
|
||||
FFFFFFFF ;timestamp
|
||||
00 ;nameidmapping version
|
||||
0001 ;count
|
||||
0000 ;id
|
||||
0006 ;strlen("ignore")
|
||||
69 67 6E 6F 72 65 ;string "ignore"
|
||||
0A ;node timer version
|
||||
0000 ;node timer count
|
||||
*/
|
||||
|
||||
#ifndef MAPCONTENT_HEADER
|
||||
#define MAPCONTENT_HEADER
|
||||
|
||||
#include "vector.h"
|
||||
|
||||
LPVECTOR MapBlockCreateMappingTableAndFixNodes(MapNode *nodes, size_t nnodes);
|
||||
size_t MapBlockSerialize(MapBlock *block, u8 *outbuf);
|
||||
void MapNodeSerializeBulk(const MapNode *nodes, u32 nodecount,
|
||||
u8 **outbuf, size_t *outlen);
|
||||
sqlite3_int64 MapBlockPosToInteger(const v3s16 pos);
|
||||
|
||||
|
||||
#endif // MAPCONTENT_HEADER
|
|
@ -0,0 +1,378 @@
|
|||
/*-
|
||||
* Copyright (c) 2013 Ryan Kwolek <kwolekr@minetest.net>.
|
||||
* 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 AUTHOR 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* mcconvert.c -
|
||||
* A utility to convert an extracted Minecraft Classic map to
|
||||
* Minetest's 0.4.x SQLite3 format.
|
||||
*/
|
||||
|
||||
#include "mcconvert.h"
|
||||
#include "vector.h"
|
||||
#include "mapcontent.h"
|
||||
#include "db.h"
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char fn_output_buf[256];
|
||||
char *fn_input, *fn_output;
|
||||
FILE *fin;
|
||||
uint32_t magic;
|
||||
uint8_t version;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Insufficient number of arguments\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fn_input = argv[1];
|
||||
fn_output = fn_output_buf;
|
||||
strlcpy(fn_output_buf, fn_input, sizeof(fn_output_buf));
|
||||
|
||||
fin = fopen(fn_input, "rb");
|
||||
if (!fin) {
|
||||
perror("Could not open input file for read");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fread(&magic, 1, sizeof(magic), fin);
|
||||
magic = SWAP4(magic);
|
||||
if (magic != 0x271bb788) {
|
||||
fprintf(stderr, "Header mismatch, invalid Minecraft Classic map file\n");
|
||||
fclose(fin);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fread(&version, 1, sizeof(version), fin);
|
||||
if (version != 2) {
|
||||
fprintf(stderr, "Unhandled map file version\n");
|
||||
fclose(fin);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
fseek(fin, 6, SEEK_CUR); // ac ed 00 05 73 72
|
||||
for (i = 0; i != 3; i++) {
|
||||
char *str;
|
||||
uint16_t slen;
|
||||
|
||||
fread(&slen, 1, sizeof(slen), fin);
|
||||
slen = SWAP2(slen);
|
||||
str = malloc(slen + 1);
|
||||
|
||||
fread(str, slen, 1, fin);
|
||||
str[slen] = 0;
|
||||
|
||||
printf("str: %s\n", str);
|
||||
free(str);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
fseek(fin, MCC_MAPDATA_OFFSET, SEEK_SET);
|
||||
u8 *mcdata = malloc(MAP_NNODES);
|
||||
int nread = fread(mcdata, MAP_NNODES, 1, fin);
|
||||
if (nread != 1) {
|
||||
fprintf(stderr, "Failed to read node data\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ConvertMCToMT(mcdata);
|
||||
CreateWalls();
|
||||
//free(mcdata);
|
||||
|
||||
printf("done!\n");
|
||||
|
||||
if (m_database_read)
|
||||
sqlite3_finalize(m_database_read);
|
||||
if (m_database_write)
|
||||
sqlite3_finalize(m_database_write);
|
||||
if (m_database)
|
||||
sqlite3_close(m_database);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ConvertMCToMT(u8 *mcdata) {
|
||||
int bx, by, bz;
|
||||
MapBlock *block = malloc(sizeof(MapBlock));
|
||||
|
||||
for (by = 0; by != MAP_NBLOCKS_Y; by++) {
|
||||
for (bz = 0; bz != MAP_NBLOCKS_Z; bz++) {
|
||||
for (bx = 0; bx != MAP_NBLOCKS_X; bx++) {
|
||||
|
||||
CopyMapBlockFromMC(mcdata, bx, by, bz, block->data);
|
||||
block->pos.X = bx;
|
||||
block->pos.Y = by;
|
||||
block->pos.Z = bz;
|
||||
DBSaveMapBlock(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(block);
|
||||
}
|
||||
|
||||
|
||||
void CopyMapBlockFromMC(u8 *mcdata, s16 bx, s16 by, s16 bz, MapNode *blockdata) {
|
||||
int x, y, z;
|
||||
int i = 0;
|
||||
|
||||
bx *= MAP_BLOCKSIZE;
|
||||
by *= MAP_BLOCKSIZE;
|
||||
bz *= MAP_BLOCKSIZE;
|
||||
|
||||
bx = 255 - bx;
|
||||
|
||||
for (z = 0; z != MAP_BLOCKSIZE; z++) {
|
||||
for (y = 0; y != MAP_BLOCKSIZE; y++) {
|
||||
// X coordinate needs to be inverted for some reason
|
||||
for (x = 0; x != MAP_BLOCKSIZE; x++) {
|
||||
int index = MINDEX(bx - x, by + y, bz + z);
|
||||
blockdata[i].param0 = mcdata[index];
|
||||
blockdata[i].param1 = 0x0F; // full lighting in daytime for now
|
||||
blockdata[i].param2 = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CreateWalls() {
|
||||
int bx, by, bz;
|
||||
int x, y, z;
|
||||
int i;
|
||||
MapBlock *mblock = malloc(sizeof(MapBlock));
|
||||
MapBlock *block = malloc(sizeof(MapBlock));
|
||||
|
||||
////////////////-y
|
||||
i = 0;
|
||||
for (z = 0; z != MAP_BLOCKSIZE; z++) {
|
||||
for (y = 0; y != MAP_BLOCKSIZE; y++) {
|
||||
for (x = 0; x != MAP_BLOCKSIZE; x++) {
|
||||
mblock->data[i].param0 = (y == MAP_BLOCKSIZE - 1) ? 7 : 0;
|
||||
mblock->data[i].param1 = 0x0F;
|
||||
mblock->data[i].param2 = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (bz = 0; bz != MAP_NBLOCKS_Z; bz++) {
|
||||
for (bx = 0; bx != MAP_NBLOCKS_X; bx++) {
|
||||
block->pos.X = bx;
|
||||
block->pos.Y = -1;
|
||||
block->pos.Z = bz;
|
||||
|
||||
memcpy(block->data, mblock->data, sizeof(block->data));
|
||||
DBSaveMapBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////-x
|
||||
i = 0;
|
||||
for (z = 0; z != MAP_BLOCKSIZE; z++) {
|
||||
for (y = 0; y != MAP_BLOCKSIZE; y++) {
|
||||
for (x = 0; x != MAP_BLOCKSIZE; x++) {
|
||||
mblock->data[i].param0 = (x == MAP_BLOCKSIZE - 1) ? 7 : 0;
|
||||
mblock->data[i].param1 = 0x0F;
|
||||
mblock->data[i].param2 = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (bz = 0; bz != MAP_NBLOCKS_Z; bz++) {
|
||||
for (by = 0; by != MAP_NBLOCKS_Y / 2; by++) {
|
||||
block->pos.X = -1;
|
||||
block->pos.Y = by;
|
||||
block->pos.Z = bz;
|
||||
|
||||
memcpy(block->data, mblock->data, sizeof(block->data));
|
||||
DBSaveMapBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////+x
|
||||
i = 0;
|
||||
for (z = 0; z != MAP_BLOCKSIZE; z++) {
|
||||
for (y = 0; y != MAP_BLOCKSIZE; y++) {
|
||||
for (x = 0; x != MAP_BLOCKSIZE; x++) {
|
||||
mblock->data[i].param0 = (x == 0) ? 7 : 0;
|
||||
mblock->data[i].param1 = 0x0F;
|
||||
mblock->data[i].param2 = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (bz = 0; bz != MAP_NBLOCKS_Z; bz++) {
|
||||
for (by = 0; by != MAP_NBLOCKS_Y / 2; by++) {
|
||||
block->pos.X = MAP_NBLOCKS_X;
|
||||
block->pos.Y = by;
|
||||
block->pos.Z = bz;
|
||||
|
||||
memcpy(block->data, mblock->data, sizeof(block->data));
|
||||
DBSaveMapBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////-z
|
||||
i = 0;
|
||||
for (z = 0; z != MAP_BLOCKSIZE; z++) {
|
||||
for (y = 0; y != MAP_BLOCKSIZE; y++) {
|
||||
for (x = 0; x != MAP_BLOCKSIZE; x++) {
|
||||
mblock->data[i].param0 = (z == MAP_BLOCKSIZE - 1) ? 7 : 0;
|
||||
mblock->data[i].param1 = 0x0F;
|
||||
mblock->data[i].param2 = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (by = 0; by != MAP_NBLOCKS_Y / 2; by++) {
|
||||
for (bx = 0; bx != MAP_NBLOCKS_X; bx++) {
|
||||
block->pos.X = bx;
|
||||
block->pos.Y = by;
|
||||
block->pos.Z = -1;
|
||||
|
||||
memcpy(block->data, mblock->data, sizeof(block->data));
|
||||
DBSaveMapBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////+z
|
||||
i = 0;
|
||||
for (z = 0; z != MAP_BLOCKSIZE; z++) {
|
||||
for (y = 0; y != MAP_BLOCKSIZE; y++) {
|
||||
for (x = 0; x != MAP_BLOCKSIZE; x++) {
|
||||
mblock->data[i].param0 = (z == 0) ? 7 : 0;
|
||||
mblock->data[i].param1 = 0x0F;
|
||||
mblock->data[i].param2 = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (by = 0; by != MAP_NBLOCKS_Y / 2; by++) {
|
||||
for (bx = 0; bx != MAP_NBLOCKS_X; bx++) {
|
||||
block->pos.X = bx;
|
||||
block->pos.Y = by;
|
||||
block->pos.Z = MAP_NBLOCKS_Z;
|
||||
|
||||
memcpy(block->data, mblock->data, sizeof(block->data));
|
||||
DBSaveMapBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
free(block);
|
||||
free(mblock);
|
||||
}
|
||||
|
||||
|
||||
/////////////////// Zlib wrappers
|
||||
|
||||
|
||||
int ZLibCompress(u8 *data, size_t datalen, u8 **out, size_t *outlen) {
|
||||
z_stream z;
|
||||
int status = 0;
|
||||
int ret;
|
||||
unsigned char *outbuf;
|
||||
size_t outbuflen;
|
||||
|
||||
*out = NULL;
|
||||
*outlen = 0;
|
||||
|
||||
z.zalloc = Z_NULL;
|
||||
z.zfree = Z_NULL;
|
||||
z.opaque = Z_NULL;
|
||||
|
||||
ret = deflateInit(&z, -1);
|
||||
if (ret != Z_OK) {
|
||||
fprintf(stderr, "compressZlib: deflateInit failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
outbuflen = deflateBound(&z, datalen);
|
||||
outbuf = malloc(outbuflen);
|
||||
|
||||
z.next_in = (Bytef *)data;
|
||||
z.avail_in = datalen;
|
||||
z.next_out = outbuf;
|
||||
z.avail_out = outbuflen;
|
||||
status = deflate(&z, Z_FINISH);
|
||||
|
||||
deflateEnd(&z);
|
||||
|
||||
if (status != Z_STREAM_END) {
|
||||
fprintf(stderr, "compressZlib: deflate failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*outlen = outbuflen - z.avail_out;
|
||||
*out = outbuf;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int ZLibDecompress(u8 *data, size_t datalen, u8 **out, size_t *outlen) {
|
||||
z_stream z;
|
||||
int status = 0;
|
||||
int ret;
|
||||
unsigned char *outbuf;
|
||||
size_t outbuflen;
|
||||
|
||||
*out = NULL;
|
||||
*outlen = 0;
|
||||
|
||||
z.zalloc = Z_NULL;
|
||||
z.zfree = Z_NULL;
|
||||
z.opaque = Z_NULL;
|
||||
|
||||
ret = deflateInit(&z, -1);
|
||||
if (ret != Z_OK) {
|
||||
fprintf(stderr, "compressZlib: deflateInit failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
outbuflen = deflateBound(&z, datalen);
|
||||
outbuf = malloc(outbuflen);
|
||||
|
||||
z.next_in = (Bytef *)data;
|
||||
z.avail_in = datalen;
|
||||
z.next_out = outbuf;
|
||||
z.avail_out = outbuflen;
|
||||
status = deflate(&z, Z_FINISH);
|
||||
|
||||
deflateEnd(&z);
|
||||
|
||||
if (status != Z_STREAM_END) {
|
||||
fprintf(stderr, "compressZlib: deflate failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*outlen = outbuflen - z.avail_out;
|
||||
*out = outbuf;
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
/*-
|
||||
* Copyright (c) 2013 Ryan Kwolek <kwolekr@minetest.net>.
|
||||
* 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 AUTHOR 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#ifndef MCCONVERT_HEADER
|
||||
#define MCCONVERT_HEADER
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#define MAP_BLOCKSIZE 16
|
||||
#define MAP_BLOCKNUMNODES (MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE)
|
||||
|
||||
#define ARRAYLEN(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#define SWAP2(num) ((((num) >> 8) & 0x00FF) | \
|
||||
(((num) << 8) & 0xFF00))
|
||||
#define SWAP4(num) ((((num) >> 24) & 0x000000FF) | \
|
||||
(((num) >> 8) & 0x0000FF00) | \
|
||||
(((num) << 8) & 0x00FF0000) | \
|
||||
(((num) << 24) & 0xFF000000))
|
||||
|
||||
#define OUTPUT_FILENAME "tehmap.sqlite"
|
||||
|
||||
// These parameters need to be guessed
|
||||
#define MCC_MAP_CX 256
|
||||
#define MCC_MAP_CY 64
|
||||
#define MCC_MAP_CZ 256
|
||||
|
||||
#define MCC_MAPDATA_OFFSET 20630
|
||||
|
||||
#define MAP_NNODES (MCC_MAP_CX * MCC_MAP_CY * MCC_MAP_CZ)
|
||||
#define MAP_NBLOCKS_X (MCC_MAP_CX / MAP_BLOCKSIZE)
|
||||
#define MAP_NBLOCKS_Y (MCC_MAP_CY / MAP_BLOCKSIZE)
|
||||
#define MAP_NBLOCKS_Z (MCC_MAP_CZ / MAP_BLOCKSIZE)
|
||||
|
||||
#define MINDEX(x,y,z) ((x) + ((y) * MCC_MAP_CX * MCC_MAP_CZ) + ((z) * MCC_MAP_CX))
|
||||
|
||||
typedef int8_t s8;
|
||||
typedef int16_t s16;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t s64;
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef struct _v2s16 {
|
||||
s16 X;
|
||||
s16 Y;
|
||||
} v2s16;
|
||||
|
||||
typedef struct _v3s16 {
|
||||
s16 X;
|
||||
s16 Y;
|
||||
s16 Z;
|
||||
} v3s16;
|
||||
|
||||
typedef struct _MapNode {
|
||||
u16 param0;
|
||||
u8 param1;
|
||||
u8 param2;
|
||||
} MapNode;
|
||||
|
||||
typedef struct _MapBlock {
|
||||
v3s16 pos;
|
||||
MapNode data[MAP_BLOCKNUMNODES];
|
||||
} MapBlock;
|
||||
|
||||
|
||||
static inline void WriteU64(u8 *data, u64 i) {
|
||||
data[0] = ((i >> 56) & 0xff);
|
||||
data[1] = ((i >> 48) & 0xff);
|
||||
data[2] = ((i >> 40) & 0xff);
|
||||
data[3] = ((i >> 32) & 0xff);
|
||||
data[4] = ((i >> 24) & 0xff);
|
||||
data[5] = ((i >> 16) & 0xff);
|
||||
data[6] = ((i >> 8) & 0xff);
|
||||
data[7] = ((i >> 0) & 0xff);
|
||||
}
|
||||
|
||||
|
||||
static inline void WriteU32(u8 *data, u32 i) {
|
||||
data[0] = ((i >> 24) & 0xff);
|
||||
data[1] = ((i >> 16) & 0xff);
|
||||
data[2] = ((i >> 8) & 0xff);
|
||||
data[3] = ((i >> 0) & 0xff);
|
||||
}
|
||||
|
||||
|
||||
static inline void WriteU16(u8 *data, u16 i) {
|
||||
data[0] = ((i >> 8) & 0xff);
|
||||
data[1] = ((i >> 0) & 0xff);
|
||||
}
|
||||
|
||||
|
||||
static inline void WriteU8(u8 *data, u8 i) {
|
||||
data[0] = ((i >> 0) & 0xff);
|
||||
}
|
||||
|
||||
#define InsertU8(data, i) { \
|
||||
WriteU8(data, i); \
|
||||
data += sizeof(u8); \
|
||||
}
|
||||
|
||||
#define InsertU16(data, i) { \
|
||||
WriteU16(data, i); \
|
||||
data += sizeof(u16); \
|
||||
}
|
||||
|
||||
#define InsertU32(data, i) { \
|
||||
WriteU32(data, i); \
|
||||
data += sizeof(u32); \
|
||||
}
|
||||
|
||||
#define InsertU64(data, i) { \
|
||||
WriteU64(data, i); \
|
||||
data += sizeof(u64); \
|
||||
}
|
||||
|
||||
int ZLibCompress(u8 *data, size_t datalen, u8 **out, size_t *outlen);
|
||||
int ZLibDecompress(u8 *data, size_t datalen, u8 **out, size_t *outlen);
|
||||
void CopyMapBlockFromMC(u8 *mcdata, s16 bx, s16 by, s16 bz, MapNode *blockdata);
|
||||
void ConvertMCToMT(u8 *mcdata);
|
||||
void CreateWalls();
|
||||
|
||||
#endif //MCCONVERT_HEADER
|
|
@ -0,0 +1,116 @@
|
|||
/*-
|
||||
* Copyright (c) 2010 Ryan Kwolek <kwolekr@minetest.net>.
|
||||
* 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 AUTHOR 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* vector.c -
|
||||
* Routines to maintain a dynamic, auto-resizing array with built in counter.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "vector.h"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
LPVECTOR VectorInit(unsigned int size) {
|
||||
LPVECTOR vect;
|
||||
|
||||
vect = (LPVECTOR)malloc(sizeof(VECTOR) + size * sizeof(void *));
|
||||
vect->numelem = 0;
|
||||
vect->maxelem = size;
|
||||
return vect;
|
||||
}
|
||||
|
||||
|
||||
LPVECTOR VectorAdd(LPVECTOR *vector, void *item) {
|
||||
LPVECTOR v = *vector;
|
||||
|
||||
if (!v)
|
||||
v = VectorInit(VECTOR_DEFAULT_SIZE);
|
||||
|
||||
if (v->numelem == v->maxelem) {
|
||||
v->maxelem <<= 1;
|
||||
v = realloc(v, sizeof(VECTOR) + v->maxelem * sizeof(void *));
|
||||
}
|
||||
v->elem[v->numelem] = item;
|
||||
v->numelem++;
|
||||
|
||||
*vector = v;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
int VectorRemove(LPVECTOR vector, void *item) {
|
||||
int i, found = 0;
|
||||
|
||||
if (!vector)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i != vector->numelem; i++) {
|
||||
if (found)
|
||||
vector->elem[i - 1] = vector->elem[i];
|
||||
if (vector->elem[i] == item) {
|
||||
found = 1;
|
||||
vector->numelem--;
|
||||
}
|
||||
}
|
||||
#ifdef VECTOR_TRIM_ARRAYS
|
||||
if (vector->numelem < (vector->maxelem >> 2)) {
|
||||
vector->maxelem >>= 1;
|
||||
vector = realloc(vector, sizeof(VECTOR) + vector->maxelem * sizeof(void *));
|
||||
}
|
||||
#endif
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
void VectorRemoveItem(LPVECTOR vector, int index) {
|
||||
int i;
|
||||
|
||||
if (!vector || index >= vector->numelem)
|
||||
return;
|
||||
|
||||
for (i = index; i != vector->numelem; i++)
|
||||
vector->elem[i] = vector->elem[i + 1];
|
||||
|
||||
vector->numelem--;
|
||||
}
|
||||
|
||||
|
||||
void VectorClear(LPVECTOR vector) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i != vector->numelem; i++)
|
||||
free(vector->elem[i]);
|
||||
vector->numelem = 0;
|
||||
}
|
||||
|
||||
|
||||
void VectorDelete(LPVECTOR vector) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i != vector->numelem; i++)
|
||||
free(vector->elem[i]);
|
||||
free(vector);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*-
|
||||
* Copyright (c) 2013 Ryan Kwolek <kwolekr@minetest.net>.
|
||||
* 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 AUTHOR 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#ifndef VECTOR_HEADER
|
||||
#define VECTOR_HEADER
|
||||
|
||||
#define VECTOR_DEFAULT_SIZE 4
|
||||
//#define VECTOR_TRIM_ARRAYS
|
||||
|
||||
typedef struct _vector {
|
||||
int numelem;
|
||||
int maxelem;
|
||||
void *elem[0];
|
||||
} VECTOR, *LPVECTOR;
|
||||
|
||||
LPVECTOR VectorInit(unsigned int size);
|
||||
LPVECTOR VectorAdd(LPVECTOR *vector, void *item);
|
||||
int VectorRemove(LPVECTOR vector, void *item);
|
||||
void VectorRemoveItem(LPVECTOR vector, int index);
|
||||
void VectorClear(LPVECTOR vector);
|
||||
void VectorDelete(LPVECTOR vector);
|
||||
|
||||
#endif // VECTOR_HEADER
|
Loading…
Reference in New Issue