Blueprint export

master
bzt 2019-12-14 20:50:40 +01:00
parent f598e658a8
commit 3be5cf1752
17 changed files with 122 additions and 21 deletions

View File

@ -115,6 +115,7 @@ Main editor window:
| <kbd>Shift</kbd> + <kbd>S</kbd> | open save as window |
| <kbd>P</kbd> | save preview PNG |
| <kbd>Shift</kbd> + <kbd>P</kbd> | save preview with structure cut in half |
| <kbd>E</kbd> | export blueprint PNG |
| <kbd>R</kbd> | change orientation, rotate entire structure CCW |
| <kbd>Shift</kbd> + <kbd>R</kbd> | change orientation, rotate entire structure CW |
| <kbd>F</kbd> | flip the entire structure along the Z axis |

BIN
examples/Notre_Dame_bp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
examples/Old_Mine_bp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
examples/Pantheon_bp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -129,7 +129,7 @@ void blocks_parse()
{
stbi__context sc;
stbi__result_info ri;
int w, h, l, r;
int w, h, l, r, g, b, n;
unsigned int numfiles = 0, i, j, k, m, *tmp;
char **files = NULL, *used, c, *s, *e;
unsigned int size;
@ -267,6 +267,16 @@ void blocks_parse()
free(blocks[j].img);
blocks[j].img = (unsigned char*)tmp;
}
for(m = r = g = b = n = 0; (int)m < w * h * 4; m += 4) {
if(blocks[j].img[m+3] >= 127) {
r += blocks[j].img[m+0];
g += blocks[j].img[m+1];
b += blocks[j].img[m+2];
n++;
}
}
if(n) blocks[j].color = 0xFF000000 | (((b/n) & 0xFF) << 16) | (((g/n) & 0xFF) << 8) | ((r/n) & 0xFF);
else blocks[j].color = 0xFFFF0000;
l++;
if(!dx || !dz || (!memcmp(s, "Cobblestone", 11) && s[11] != '_' && s[11] != ' ')) {
detcube(32, 32, blocks[j].img);
@ -289,7 +299,7 @@ void blocks_parse()
for(s = e; *e && *e != '\r' && *e != '\n' && *e != c; e++)
if(*e == '\\' || (*e == '\"' && e[1] == '\"')) { e++; continue; }
while(*s <= ' ') s++;
for(i = 0; s < e && i < 8;) {
for(i = 0; s < e && i < 4;) {
blocks[j].blockids[i] = atoi(s);
if(blocks[j].blockids[i]) i++;
while(*s >= '0' && *s <= '9') s++;

View File

@ -343,6 +343,7 @@ void edit_key(SDL_Event *event)
case SDLK_s: if(!shift) sdldo(1); break;
case SDLK_p: sdldo(2); break;
case SDLK_r: sdldo(4 - shift); break;
case SDLK_e: sdldo(12); break;
case SDLK_g: gndlayer = currlayer; break;
case SDLK_d:
if(nodes[currlayer][cz][cx].param0) {

View File

@ -40,6 +40,7 @@ char *dict[NUMLANGS][NUMTEXTS + 1] = {
"dump layers to output",
"save preview",
"save preview, cut structure in half",
"save blueprint",
"generate slab and stairs from block image",
"generate block images from texture data",
"replace block type mapping",
@ -57,10 +58,12 @@ char *dict[NUMLANGS][NUMTEXTS + 1] = {
"Unable to load MTS file",
"Unsupported file format",
"Unable to save preview",
"Unable to save blueprint",
"No biome specific blocks in this structure.",
"File saved.",
"File loaded.",
"Preview saved.",
"Blueprint saved.",
"Rotated block images generated.",
"North",
"Current Layer",
@ -117,6 +120,7 @@ char *dict[NUMLANGS][NUMTEXTS + 1] = {
"kidumpolja a rétegeket a kimenetre",
"előnézeti képet ment",
"előnézet félbevágott struktúráról",
"tervrajz mentése",
"palló és lépcső generálás blokk képből",
"blokk képek generálása textúra adatokból",
"lecseréli a palettát",
@ -134,10 +138,12 @@ char *dict[NUMLANGS][NUMTEXTS + 1] = {
"Nem sikerült betölteni az MTS fájlt",
"Nem támogatott fájl formátum",
"Nem sikerült elmenteni az előnézeti képet",
"Nem sikerült elmenteni a tervrajzot",
"Nincs biom specifikus blokk a struktúrában",
"Fájl lemente.",
"Fájl betöltve.",
"Előnézeti kép lementve.",
"Tervrajz lementve.",
"Elforgatott blokk képek kigenerálva.",
"Észak",
"Aktuális szint",
@ -194,6 +200,7 @@ char *dict[NUMLANGS][NUMTEXTS + 1] = {
"volcar capas a la salida",
"guardar vista previa",
"guardar vista previa, cortar la estructura por la mitad",
"guardar plano",
"generar losas y escaleras desde la imagen de bloque",
"generar imágenes de bloque a partir de datos de textura",
"reemplazar el mapeo de tipo de bloque",
@ -211,10 +218,12 @@ char *dict[NUMLANGS][NUMTEXTS + 1] = {
"No se puede cargar el archivo MTS",
"Formato de archivo no soportado",
"No se puede guardar la vista previa",
"No se puede guardar el plano",
"No hay bloques específicos de bioma en esta estructura.",
"Archivo guardado.",
"Archivo cargado.",
"Vista previa guardada.",
"Plano guardado",
"Imágenes de bloque rotadas generadas.",
"Norte",
"Capa actual",
@ -271,6 +280,7 @@ char *dict[NUMLANGS][NUMTEXTS + 1] = {
"vider les couches à la sortie",
"enregistrer l'aperçu",
"enregistrer l'aperçu, couper la structure en deux",
"enregister le plan",
"générer une dalle et des escaliers à partir d'une image de bloc",
"générer des images de bloc à partir de données de texture",
"remplacer la correspondance de type de bloc",
@ -288,10 +298,12 @@ char *dict[NUMLANGS][NUMTEXTS + 1] = {
"Impossible de charger le fichier MTS",
"Format de fichier non pris en charge",
"Impossible d'enregistrer l'aperçu",
"Impossible d'enregistrer le plan",
"Pas de blocs spécifiques au biome dans cette structure.",
"Fichier enregistré.",
"Fichier enchargé.",
"Aperçu enregistré.",
"Plan enregistré.",
"Images de bloc pivotées générées.",
"Nord",
"Couche actuelle",
@ -348,6 +360,7 @@ char *dict[NUMLANGS][NUMTEXTS + 1] = {
"Dump Layeren zu Konsole",
"Vorschau speichern",
"Vorschau speichern, Struktur halbieren",
"Blaupause spaichern",
"Erzeugen von Platten und Treppen aus dem Blockbild",
"Blockbilder aus Texturdaten erzeugen",
"Blocktypzuordnung ersetzen",
@ -365,10 +378,12 @@ char *dict[NUMLANGS][NUMTEXTS + 1] = {
"MTS-Datei kann nicht geladen werden",
"Nicht unterstütztes Dateiformat",
"Vorschau kann nicht gespeichert werden",
"Blaupause kann nicht gespeichert werden",
"Keine biomspezifischen Blöcke in dieser Struktur.",
"Datei gespeichert",
"Datei gespeichert.",
"Datei geladen.",
"Vorschau gespeichert.",
"Blaupause gespeichert.",
"Gedrehte Blockbilder erzeugt.",
"Norden",
"Aktuelle Ebene",
@ -387,7 +402,7 @@ char *dict[NUMLANGS][NUMTEXTS + 1] = {
"Z-Ebene einfügen",
"Z-Schicht entfernen",
"Rückgängig machen",
"Redo",
"Wiederholen",
"Hineinzoomen",
"Rauszoomen",
"Wählen Sie Pinsel",
@ -425,6 +440,7 @@ char *dict[NUMLANGS][NUMTEXTS + 1] = {
"zrzuć warstwy na wyjście",
"zapisz podgląd",
"zapisz podgląd, wytnij strukturę na pół",
"zapisz plan",
"generuj płytę i schody z obrazu bloku",
"generować obrazy bloków z danych tekstury",
"zastąpić mapowanie typów bloków",
@ -442,10 +458,12 @@ char *dict[NUMLANGS][NUMTEXTS + 1] = {
"Nie można załadować pliku MTS",
"Niewspierany format pliku",
"Nie można zapisać podglądu",
"Nie można zapisać planu",
"Brak bloków specyficznych dla biomu w tej strukturze.",
"Plik zapisany.",
"Plik załadowany.",
"Podgląd zapisany.",
"Plan zapisany.",
"Wygenerowano obrócone obrazy blokowe.",
"Północ",
"Bieżąca warstwa",
@ -502,6 +520,7 @@ char *dict[NUMLANGS][NUMTEXTS + 1] = {
"выгрузить слои на вывод",
"сохранить предварительный просмотр",
"сохранить предварительный просмотр, разрезать структуру пополам",
"сохранить план",
"генерировать плиты и лестницы из изображения блока",
"генерировать блочные изображения из данных текстуры",
"заменить отображение типа блока",
@ -519,10 +538,12 @@ char *dict[NUMLANGS][NUMTEXTS + 1] = {
"Невозможно загрузить файл MTS",
"Неподдерживаемый формат файла",
"Невозможно сохранить предварительный просмотр",
"Невозможно сохранить план",
"В этой структуре нет биом-специфических блоков.",
"Файл сохранен",
"Файл сохранен.",
"Файл загружен.",
"Предварительный просмотр сохранен.",
"План сохранен.",
"Созданы повернутые изображения блоков.",
"К северу",
"Текущий слой",

View File

@ -33,6 +33,7 @@ enum {
INF_DUMP,
INF_PRE1,
INF_PRE2,
INF_BPRINT,
INF_GEN,
INF_BLK,
INF_MAP,
@ -50,10 +51,12 @@ enum {
ERR_LOAD,
ERR_BADFILE,
ERR_PREVIEW,
ERR_BPRINT,
ERR_NOBIOM,
SAVED,
LOADED,
PREVIEWSAVED,
BPRINTSAVED,
IMGSGEN,
NORTH,
CURRLAYER,

View File

@ -165,21 +165,21 @@ int main(int argc, char** argv, char** envp)
/* get blocks data */
blocks_getdir(argv, envp);
#ifdef _MacOSX_
#ifndef __WIN32__
/* MacOSX does not allow specifying arguments when started from Launchpad,
* and it won't show the output in a terminal either. So fake home dir. */
if(argc < 2) { argc++; argv[1] = "~"; }
if(argc < 2 && !isatty(1)) { argc++; argv[1] = "~"; }
#endif
if(argc < 2) {
usage: printf("MineTest Schematics Editor by bzt Copyright (C) 2019 MIT license\r\n\r\n"
"./mtsedit [-h] [-v] [-l lang] [-d|-p|-P] [-m map] <.mts|.schematic> [out.mts]\r\n"
"./mtsedit [-h] [-v] [-l lang] [-d|-p|-P|-b] [-m map] <.mts|.schematic> [out.mts]\r\n"
"./mtsedit -g <block.png>\r\n"
"./mtsedit -t <blockimgs.csv> [blockid]\r\n"
"./mtsedit -i [Minetest mods dir]\r\n"
"\r\n -v: %s\r\n -l lang: %s\r\n -d: %s\r\n -p: %s\r\n -P: %s\r\n -m map: %s\r\n -g: %s\r\n"
"\r\n -v: %s\r\n -l lang: %s\r\n -d: %s\r\n -p: %s\r\n -P: %s\r\n -b: %s\r\n -m map: %s\r\n -g: %s\r\n"
" -t: %s\r\n -i: %s\r\n out.mts: %s\r\n",
lang[INF_VERB], lang[INF_LANG], lang[INF_DUMP], lang[INF_PRE1], lang[INF_PRE2], lang[INF_MAP],
lang[INF_VERB], lang[INF_LANG], lang[INF_DUMP], lang[INF_PRE1], lang[INF_PRE2], lang[INF_BPRINT], lang[INF_MAP],
lang[INF_GEN], lang[INF_BLK], lang[INF_MOD], lang[INF_OUT]);
exit(0);
}
@ -191,10 +191,11 @@ usage: printf("MineTest Schematics Editor by bzt Copyright (C) 2019 MIT license
case 'd': opt = 1; break;
case 'p': opt = 2; break;
case 'P': opt = 3; break;
case 'g': opt = 4; break;
case 't': opt = 5; break;
case 'i': opt = 6; break;
case 'm': if(!opt) { opt = 7; } newmap = argv[++j]; break;
case 'b': opt = 4; break;
case 'g': opt = 5; break;
case 't': opt = 6; break;
case 'i': opt = 7; break;
case 'm': if(!opt) { opt = 8; } newmap = argv[++j]; break;
case 'l': j++; break;
default: goto usage; break;
}
@ -216,8 +217,8 @@ usage: printf("MineTest Schematics Editor by bzt Copyright (C) 2019 MIT license
if(!tmpblk) error(lang[ERR_MEM]);
mts_x = mts_y = mts_z = 0;
if(i+1 < argc && argv[i+1] && !opt) opt = 7;
if(opt && (opt < 4 || opt == 7)) {
if(i+1 < argc && argv[i+1] && !opt) opt = 8;
if(opt && (opt < 5 || opt == 8)) {
blocks_parse();
readschem();
if(!mts_y || !mts_y || !mts_x)
@ -245,9 +246,10 @@ usage: printf("MineTest Schematics Editor by bzt Copyright (C) 2019 MIT license
case 1: ret = mts_dump(); break;
case 2:
case 3: ret = mts_view(opt-2); break;
case 4: ret = stairgen(); break;
case 5: ret = blockgen(argv[i+1]); break;
case 6:
case 4: ret = mts_blueprint(); break;
case 5: ret = stairgen(); break;
case 6: ret = blockgen(argv[i+1]); break;
case 7: /* handle this in sdl.c, because extern does not know sizeof() */
case 0:
/* start the main user interface */
ret = sdlmain(opt);

View File

@ -71,6 +71,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <limits.h>
@ -96,7 +97,8 @@ typedef struct {
int numref;
char numpar2;
char dobiome;
unsigned char blockids[8];
uint32_t color;
unsigned char blockids[4];
unsigned char *img;
unsigned char *dr;
unsigned char *tr;
@ -204,6 +206,7 @@ void schem_load(unsigned char *data, unsigned int size);
void mts_load(unsigned char *data, unsigned int size);
int mts_save();
int mts_view(int type);
int mts_blueprint();
int mts_dump();
int mts_getbounds(int sanitize, unsigned short *tr, unsigned short *tr2);
void mts_layerprob(int diff);

View File

@ -411,6 +411,65 @@ int mts_view(int type)
return 1;
}
/**
* Export a PNG blueprint file
*/
int mts_blueprint()
{
int i, w, h, x, y, z;
char pngfile[MAXPATHLEN], *c;
unsigned char *buff = NULL;
uint32_t *dst;
SDL_Surface *bprint;
FILE *f;
status = lang[ERR_PREVIEW];
mts_getbounds(0, NULL, NULL);
if(mix > max) return 1;
bound_valid = 0;
/* calculate dimensions and create images */
w = maz - miz + 3;
h = (may - miy + 1) * (max - mix + 2) + 3;
bprint = SDL_CreateRGBSurface(0, w, h, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000);
memset(bprint->pixels, 0, w * h * 4);
dst = (uint32_t*)bprint->pixels;
/* generate blueprint into surface */
for(i = w, y = may; y >= miy; y--, i += w) {
for(x = mix; x <= max; x++) {
i++;
for(z = maz; z >= miz; z--, i++)
if(nodes[y][z][x].param0)
dst[i] = blocks[nodes[y][z][x].param0].color;
if(y == gndlayer)
dst[i] = 0xFF0000FF;
i++;
}
dst[i] = y == gndlayer ? 0xFF0000FF : 0xFF000000;
}
/* write result to PNG file */
buff = (unsigned char *)stbi_write_png_to_mem(bprint->pixels, bprint->pitch, bprint->w, bprint->h, 4, &i);
SDL_FreeSurface(bprint);
if(buff) {
strcpy(pngfile, mtsfile);
c = strrchr(pngfile, '.');
if(!c) c = &pngfile[strlen(pngfile)];
strcpy(c, "_bp.png");
f = fopen(pngfile,"wb");
if(f) {
fwrite(buff, i, 1, f);
fclose(f);
status = lang[BPRINTSAVED];
fprintf(stderr, "mtsedit: %s: %s\r\n", pngfile, status);
}
free(buff);
return 0;
}
return 1;
}
/**
* Dump structure
*/

View File

@ -67,7 +67,7 @@ void schem_load(unsigned char *data, unsigned int size)
for(x = 0; x < mts_x; x++, d++) {
if(!*d) continue;
for(i = 1, k = 0; i < numblocks; i++)
for(j = 0; j < 8; j++)
for(j = 0; j < 4; j++)
if(blocks[i].blockids[j] == *d) { k = i; i = numblocks; break; }
if(k) {
nodes[y+min_y][z+min_z][x+min_x].param0 = k;

View File

@ -325,6 +325,7 @@ void sdldo(int opt)
case 9: hist_prepare(HIST_DELZ, cz); mts_delz(cz); hist_commit(); break;
case 10: hist_prepare(HIST_ADDX, cx); mts_addx(cx, shift); hist_commit(); break;
case 11: hist_prepare(HIST_DELX, cx); mts_delx(cx); hist_commit(); break;
case 12: mts_blueprint(); break;
}
SDL_SetCursor(pointer);
SDL_ShowCursor(0); systemcursor = 0;