Add some more improvements to the map tool.

master
Rene Jochum 2011-07-27 06:27:31 +02:00
parent 4a227a1b5b
commit 064c7fcd85
8 changed files with 233 additions and 207 deletions

View File

@ -9,15 +9,28 @@ if (NOT CMAKE_BUILD_TYPE)
FORCE)
endif ()
find_package(PhysFS 2 REQUIRED)
# For Static builds
IF(LIBTYPE STREQUAL "STATIC")
ADD_DEFINITIONS("-DQT_STATIC")
ADD_DEFINITIONS("-DQT_NODLL")
SET(CMAKE_EXE_LINKER_FLAGS -static)
SET(QT_IS_STATIC 1)
SET(QT_CONFIG "static")
find_package(PNG REQUIRED)
find_package(ZLIB REQUIRED)
find_package(JPEG REQUIRED)
find_package(TIFF REQUIRED)
SET(QT_DEPS ${JPEG_LIBRARY} ${TIFF_LIBRARY} "mng" "lcms")
endif()
set(QT_USE_IMPORTED_TARGETS TRUE)
find_package(Qt4 REQUIRED)
include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS})
find_package(PNG 1.5 REQUIRED)
find_package(PhysFS 2 REQUIRED)
# Ugly OS-X Fix, should find a better way.
IF(${CMAKE_SYSTEM_NAME} MATCHES "^Darwin")
SET(QT_QTCORE_LIBRARY "-framework QtCore")
@ -61,35 +74,35 @@ set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin")
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR} "${CMAKE_SOURCE_DIR}/../.." ${PNG_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} ${QT_INCLUDES} ${PHYSFS_INCLUDE_DIR})
set(MAPTOOLS_LIBS ${PNG_LIBRARIES} ${PHYSFS_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY})
set(MAPTOOLS_LIBS ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${PHYSFS_LIBRARY} ${QT_LIBRARIES} ${QT_DEPS})
# map2lnd
# ADD_EXECUTABLE(map2lnd
# map2lnd.cpp
# mapload.cpp)
# TARGET_LINK_LIBRARIES(map2lnd ${MAPTOOLS_LIBS})
ADD_EXECUTABLE(map2lnd
map2lnd.cpp
maplib.cpp
mapload.cpp)
TARGET_LINK_LIBRARIES(map2lnd ${MAPTOOLS_LIBS})
# map2png
# ADD_EXECUTABLE(map2png
# map2png.cpp
# mapload.cpp
# pngsave.cpp)
# TARGET_LINK_LIBRARIES(map2png ${MAPTOOLS_LIBS})
ADD_EXECUTABLE(map2png
map2png.cpp
maplib.cpp
mapload.cpp
pngsave.cpp)
TARGET_LINK_LIBRARIES(map2png ${MAPTOOLS_LIBS})
# map2preview
ADD_EXECUTABLE(map2preview
map2preview.cpp
maplib.cpp
mapload.cpp
pngsave.cpp
wzconfig.cpp)
TARGET_LINK_LIBRARIES(map2preview ${MAPTOOLS_LIBS})
# map2png
# mapconv
ADD_EXECUTABLE(mapconv
mapconv.cpp
maplib.cpp
mapload.cpp
pngsave.cpp)
mapload.cpp)
TARGET_LINK_LIBRARIES(mapconv ${MAPTOOLS_LIBS})

21
tools/map/make_win32.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/sh
OLDPATH="$(pwd)"
MYPATH="$(cd -P -- "$(dirname -- "$0")" && pwd -P)"
MINGW_ENV="/opt/mingw"
# cd "${MYPATH}/../.."
# make clean
# ./autogen.sh
# ./configure --host=i686-pc-mingw32 --enable-static PKG_CONFIG=i686-pc-mingw32-pkg-config \
# CC_FOR_BUILD="gcc" CXX_FOR_BUILD="g++" \
# CFLAGS="-pipe -m32 -march=i686 -O2 -g -gstabs -g3" \
# CXXFLAGS="-pipe -m32 -march=i686 -O2 -g -gstabs -g3 -fno-exceptions" \
# --with-installer-version="2.46.0.0" --disable-debug
cd ${MYPATH}
cmake . -B$PWD/build -DCMAKE_BUILD_TYPE=Debug3 \
-DCMAKE_TOOLCHAIN_FILE=${MINGW_ENV}/usr/i686-pc-mingw32/share/cmake/mingw-cross-env-conf.cmake \
-DLIBTYPE=STATIC
make -C$PWD/build -j4 VERBOSE=1 all
cd ${OLDPATH}

View File

@ -5,10 +5,9 @@
// gcc -o ~/bin/map2lnd map2lnd.c mapload.c -I. -lphysfs -g -I../../lib/framework -Wall
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
// Tool framework
#include "maplib.h"
#include "mapload.h"
#define GRDLANDVERSION 4

View File

@ -1,26 +1,13 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
// Physfs
#include <physfs.h>
// framework
#include "physfs_ext.h"
#include "wzglobal.h"
// tool "framework"
#include "maplib.h"
#include "pngsave.h"
#include "mapload.h"
int main(int argc, char **argv)
{
char filename[PATH_MAX] = { '\0' };
char pngfile[PATH_MAX] = { '\0' };
char *p_filename = filename;
char *delim;
int namelength;
char *filename, *p_filename;
char *base, tmpFile[PATH_MAX];
GAMEMAP *map;
if (argc != 2)
@ -29,62 +16,54 @@ int main(int argc, char **argv)
return -1;
}
PHYSFS_init(argv[0]);
PHYSFS_addToSearchPath(".", 1);
strcat(p_filename, "multiplay/maps/");
p_filename += strlen("multiplay/maps/");
delim = strrchr(argv[1], PHYSFS_getDirSeparator()[0]);
if (delim)
{
delim++;
strcpy(p_filename, delim);
namelength = strlen(filename);
if (namelength >= 3 && strcmp(&filename[namelength-3], ".wz")==0)
{
// remove ".wz" from end
filename[namelength-3] = '\0';
}
strcpy(pngfile, delim);
strcat(pngfile, ".png");
PHYSFS_addToSearchPath(argv[0], 1);
}
else
{
strcpy(pngfile, argv[1]);
namelength = strlen(pngfile);
if (namelength >= 3 && strcmp(&pngfile[namelength-3], ".wz")==0)
{
// remove ".wz" from end
pngfile[namelength-3] = '\0';
}
strcpy(p_filename, pngfile);
strcat(pngfile, ".png");
}
physfs_init(argv[0]);
filename = physfs_addmappath(argv[1]);
p_filename = strrchr(filename, '/');
if (p_filename)
{
p_filename++;
base = strdup(p_filename);
}
else
{
base = strdup(filename);
}
if (!PHYSFS_exists(base))
{
PHYSFS_mkdir(base);
}
map = mapLoad(filename);
if (map)
free(filename);
if (!map)
{
uint x, y;
uint8_t *pixels = (uint8_t *)malloc(map->width * map->height);
return EXIT_FAILURE;
}
uint x, y;
uint8_t *pixels = (uint8_t *)malloc(map->width * map->height);
for (x = 0; x < map->width; x++)
{
for (y = 0; y < map->height; y++)
{
MAPTILE *psTile = mapTile(map, x, y);
int pixpos = y * map->width + x;
for (x = 0; x < map->width; x++)
{
for (y = 0; y < map->height; y++)
{
MAPTILE *psTile = mapTile(map, x, y);
int pixpos = y * map->width + x;
pixels[pixpos++] = psTile->height;
}
}
savePngI8(pngfile, pixels, map->width * 4, map->height * 4);
free(pixels);
}
mapFree(map);
pixels[pixpos++] = psTile->height;
}
}
strcpy(tmpFile, base);
strcat(tmpFile, "/height.png");
savePngI8(tmpFile, pixels, map->width, map->height);
free(pixels);
mapFree(map);
physfs_shutdown();
return 0;
}

View File

@ -1,13 +1,3 @@
/*
g++ -Wall -I. -DQT_SHARED -I/usr/include/qt4 -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui \
-o map2preview map2preview.cpp mapload.c pngsave.c wzconfig.cpp \
-lz -lphysfs -lpng -I../../lib/framework -L/usr/local/lib -lQtCore -lQtGui
*/
// Mingw
// i686-pc-mingw32-g++ -O0 -g --static -o map2preview.exe map2preview.cpp mapload.c pngsave.c -I. -I../../lib/framework -L/opt/mingw/usr/i686-pc-mingw32/lib -lpng15 -lz -lphysfs -lshfolder -lshlwapi -lpsapi -lshell32 -lws2_32 -liphlpapi -Wall
// tool "framework"
#include "maplib.h"
@ -203,10 +193,6 @@ int main(int argc, char **argv)
{
base = strdup(filename);
}
if (!PHYSFS_exists(base))
{
PHYSFS_mkdir(base);
}
map = mapLoad(filename);
free(filename);
@ -277,16 +263,18 @@ int main(int argc, char **argv)
}
else
{
debug(LOG_ERROR, "Cannot add structure data, please convert base data first.\nUse mapconf for that.");
debug(LOG_ERROR, "Cannot add structure data, please convert base data first.\nUse \"mapconv %s\" for that.", argv[1]);
}
strcpy(tmpFile, base);
strcat(tmpFile, "/preview.png");
strcat(tmpFile, ".png");
QImage image(imageData, mapWidth, mapHeight, QImage::Format_RGB888);
image.scaled(previewWidth, previewHeight, Qt::KeepAspectRatio).save(tmpFile, "PNG");
// savePng(tmpFile, imageData, previewWidth, previewHeight);
free(imageData);
mapFree(map);
physfs_shutdown();

View File

@ -34,7 +34,7 @@ GAMEMAP *mapLoad(char *filename)
bool littleEndian = true;
PHYSFS_file *fp = NULL;
bool counted[MAX_PLAYERS];
uint16_t *pType;
uint16_t pType;
// this cries out for a class based design
#define readU8(v) ( littleEndian ? PHYSFS_readULE8(fp, v) : PHYSFS_readUBE8(fp, v) )
@ -291,15 +291,15 @@ featfailure:
for (i = 0; i < map->numTerrainTypes; i++)
{
readU16(pType);
readU16(&pType);
if (*pType > TER_MAX)
if (pType > TER_MAX)
{
debug(LOG_ERROR, "loadTerrainTypeMap: terrain type out of range");
goto terrainfailure;
}
terrainTypes[i] = (uint8_t)*pType;
terrainTypes[i] = (uint8_t)pType;
}
if (terrainTypes[0] == 1 && terrainTypes[1] == 0 && terrainTypes[2] == 2)

View File

@ -1,106 +1,132 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
// Framework
#include "maplib.h"
#include <png.h>
#include "pngsave.h"
#define debug(x, ...) printf(__VA_ARGS__); printf("\n");
/**************************************************************************
Save given buffer type to file.
**************************************************************************/
bool savePngInternal(const char *filename, unsigned char *pixels, int w, int h, int bitdepth, int color_type)
static inline void PNGWriteCleanup(png_infop *info_ptr, png_structp *png_ptr, FILE* fileHandle)
{
png_structp pngp;
png_infop infop;
int y;
FILE *fp;
png_bytep *row_pointers;
int const bytes = bitdepth / 8;
if (filename == NULL || *filename == '\0' || pixels == NULL)
{
return false;
}
if (!(fp = fopen(filename, "wb")))
{
debug(LOG_ERROR, "%s won't open for writing!", filename);
return false;
}
pngp = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!pngp)
{
debug(LOG_ERROR, "fgl_save_pixmap: Failed to create PNG write struct");
fclose(fp);
return false;
}
infop = png_create_info_struct(pngp);
if (!infop)
{
debug(LOG_ERROR, "fgl_save_pixmap: Failed to create PNG info struct");
fclose(fp);
png_destroy_write_struct(&pngp, NULL);
return false;
}
if (setjmp(png_jmpbuf(pngp)))
{
debug(LOG_ERROR, "fgl_save_pixmap: Failed to initialize IO during PNG save");
fclose(fp);
png_destroy_write_struct(&pngp, NULL);
return false;
}
png_init_io(pngp, fp);
/* write header */
if (setjmp(png_jmpbuf(pngp)))
{
debug(LOG_ERROR, "fgl_save_pixmap: Failed to write PNG header");
fclose(fp);
png_destroy_write_struct(&pngp, NULL);
return false;
}
png_set_IHDR(pngp, infop, w, h, bitdepth, color_type,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);
png_write_info(pngp, infop);
/* Create pointers to each row of the data, as libpng wants it */
row_pointers = (png_byte **)malloc(sizeof(png_bytep) * h);
for (y = 0; y < h; y++)
{
row_pointers[y] = pixels + (y * w * bytes);
}
if (setjmp(png_jmpbuf(pngp)))
{
debug(LOG_ERROR, "fgl_save_pixmap: Failed to write PNG body");
fclose(fp);
png_destroy_write_struct(&pngp, NULL);
return false;
}
png_write_image(pngp, row_pointers);
if (setjmp(png_jmpbuf(pngp)))
{
debug(LOG_ERROR, "fgl_save_pixmap: Failed to finalize PNG");
fclose(fp);
png_destroy_write_struct(&pngp, NULL);
return false;
}
png_write_end(pngp, NULL);
free(row_pointers);
fclose(fp);
png_destroy_write_struct(&pngp, NULL);
return true;
if (*info_ptr != NULL)
png_destroy_info_struct(*png_ptr, info_ptr);
if (*png_ptr != NULL)
png_destroy_write_struct(png_ptr, NULL);
if (fileHandle != NULL)
fclose(fileHandle);
}
static bool savePngInternal(const char *fileName, unsigned char *pixels, int w, int h, int bitdepth, int color_type)
{
unsigned char** scanlines = NULL;
png_infop info_ptr = NULL;
png_structp png_ptr = NULL;
FILE *fp;
if (fileName == NULL || *fileName == '\0' || pixels == NULL)
{
return false;
}
if (!(fp = fopen(fileName, "wb")))
{
debug(LOG_ERROR, "%s won't open for writing!", fileName);
return false;
}
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL)
{
debug(LOG_ERROR, "savePng: Unable to create png struct\n");
PNGWriteCleanup(&info_ptr, &png_ptr, fp);
return false;
}
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{
debug(LOG_ERROR, "savePng: Unable to create png info struct\n");
PNGWriteCleanup(&info_ptr, &png_ptr, fp);
return false;
}
// If libpng encounters an error, it will jump into this if-branch
if (setjmp(png_jmpbuf(png_ptr)))
{
debug(LOG_ERROR, "savePng: Error encoding PNG data\n");
PNGWriteCleanup(&info_ptr, &png_ptr, fp);
return false;
}
else
{
unsigned int channelsPerPixel = 3;
unsigned int currentRow, row_stride;
if (color_type == PNG_COLOR_TYPE_GRAY)
{
channelsPerPixel = 1;
}
row_stride = w * channelsPerPixel * bitdepth / 8;
scanlines = (unsigned char **)malloc(sizeof(unsigned char *) * h);
if (scanlines == NULL)
{
debug(LOG_ERROR, "pie_PNGSaveFile: Couldn't allocate memory\n");
PNGWriteCleanup(&info_ptr, &png_ptr, fp);
return false;
}
png_init_io(png_ptr, fp);
//png_set_write_fn(png_ptr, fp, wzpng_write_data, wzpng_flush_data);
// Set the compression level of ZLIB
// Right now we stick with the default, since that one is the
// fastest which still produces acceptable filesizes.
// The highest compression level hardly produces smaller files than default.
//
// Below are some benchmarks done while taking screenshots at 1280x1024
// Z_NO_COMPRESSION:
// black (except for GUI): 398 msec
// 381, 391, 404, 360 msec
//
// Z_BEST_SPEED:
// black (except for GUI): 325 msec
// 611, 406, 461, 608 msec
//
// Z_DEFAULT_COMPRESSION:
// black (except for GUI): 374 msec
// 1154, 1121, 627, 790 msec
//
// Z_BEST_COMPRESSION:
// black (except for GUI): 439 msec
// 1600, 1078, 1613, 1700 msec
// Not calling this function is equal to using the default
// so to spare some CPU cycles we comment this out.
// png_set_compression_level(png_ptr, Z_DEFAULT_COMPRESSION);
png_set_IHDR(png_ptr, info_ptr, w, h, bitdepth,
color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(png_ptr, info_ptr);
// Create an array of scanlines
for (currentRow = 0; currentRow < h; ++currentRow)
{
// We're filling the scanline from the bottom up here,
// otherwise we'd have a vertically mirrored image.
scanlines[currentRow] = pixels + row_stride * (h - currentRow - 1);
}
png_write_image(png_ptr, (png_bytepp)scanlines);
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
png_write_end(png_ptr, NULL);
}
free(scanlines);
PNGWriteCleanup(&info_ptr, &png_ptr, fp);
return true;
}
/**************************************************************************
Save an RGBA8888 image buffer to a PNG file.

View File

@ -1,9 +1,9 @@
#ifndef TOOLS_MAP_WZCONFIG_H
#define TOOLS_MAP_WZCONFIG_H
#include <qt4/QtCore/QSettings>
#include <qt4/QtCore/QString>
#include <qt4/QtCore/QStringList>
#include <QtCore/QSettings>
#include <QtCore/QString>
#include <QtCore/QStringList>
struct Rotation;
struct Vector3i;