summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorJared Adams <jaxad0127@gmail.com>2010-06-13 13:16:16 -0600
committerJared Adams <jaxad0127@gmail.com>2010-06-13 13:16:16 -0600
commite8bea8a6edf69e824a922adeb5e697111ceabe90 (patch)
treedb1937956bc585b300f2a2c8312af4ad5bf924de /tools
parent593fd2b831304c8e421589aab0fb158e4b7e9c35 (diff)
parent0b15a3ad32838134384524ce4af95d65b0b4e5da (diff)
downloadMana-e8bea8a6edf69e824a922adeb5e697111ceabe90.tar.gz
Mana-e8bea8a6edf69e824a922adeb5e697111ceabe90.tar.bz2
Mana-e8bea8a6edf69e824a922adeb5e697111ceabe90.tar.xz
Mana-e8bea8a6edf69e824a922adeb5e697111ceabe90.zip
Merge remote branch '1.0/1.0'
Conflicts: data/graphics/CMakeLists.txt data/graphics/Makefile.am src/client.cpp
Diffstat (limited to 'tools')
-rw-r--r--tools/dyecmd/CMakeLists.txt28
-rw-r--r--tools/dyecmd/src/CMakeLists.txt59
-rwxr-xr-x[-rw-r--r--]tools/dyecmd/src/dye.cpp96
-rwxr-xr-x[-rw-r--r--]tools/dyecmd/src/dye.h19
-rwxr-xr-x[-rw-r--r--]tools/dyecmd/src/dyecmd.cpp132
-rwxr-xr-x[-rw-r--r--]tools/dyecmd/src/imagewriter.cpp24
-rwxr-xr-x[-rw-r--r--]tools/dyecmd/src/imagewriter.h0
7 files changed, 238 insertions, 120 deletions
diff --git a/tools/dyecmd/CMakeLists.txt b/tools/dyecmd/CMakeLists.txt
new file mode 100644
index 00000000..48566648
--- /dev/null
+++ b/tools/dyecmd/CMakeLists.txt
@@ -0,0 +1,28 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+PROJECT(MANA_DYECOMMAND)
+
+IF (NOT VERSION)
+ SET(VERSION 1.0.0)
+ENDIF()
+
+STRING(REPLACE "." " " _VERSION ${VERSION})
+SEPARATE_ARGUMENTS(_VERSION)
+LIST(LENGTH _VERSION _LEN)
+IF(NOT (_LEN EQUAL 4 OR _LEN EQUAL 3))
+ MESSAGE(FATAL_ERROR "Version needs to be in the form MAJOR.MINOR.RELEASE[.BUILD]")
+ENDIF()
+
+LIST(GET _VERSION 0 VER_MAJOR)
+LIST(GET _VERSION 1 VER_MINOR)
+LIST(GET _VERSION 2 VER_RELEASE)
+IF(_LEN EQUAL 4)
+ LIST(GET _VERSION 3 VER_BUILD)
+ELSE()
+ SET(VER_BUILD 0)
+ENDIF()
+
+# where to look for cmake modules
+SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/Modules)
+
+ADD_SUBDIRECTORY(src)
diff --git a/tools/dyecmd/src/CMakeLists.txt b/tools/dyecmd/src/CMakeLists.txt
new file mode 100644
index 00000000..f8e717b7
--- /dev/null
+++ b/tools/dyecmd/src/CMakeLists.txt
@@ -0,0 +1,59 @@
+FIND_PACKAGE(SDL REQUIRED)
+FIND_PACKAGE(SDL_image REQUIRED)
+FIND_PACKAGE(PNG REQUIRED)
+
+IF (CMAKE_COMPILER_IS_GNUCXX)
+ # Help getting compilation warnings
+ SET(CMAKE_CXX_FLAGS "-Wall")
+ IF (WIN32)
+ # This includes enough debug information to get something useful
+ # from Dr. Mingw while keeping binary size down. Almost useless
+ # with gdb, though.
+ SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -ggdb0 -gstabs2")
+ ENDIF()
+ENDIF()
+
+SET(FLAGS "-DPACKAGE_VERSION=\\\"${VERSION}\\\"")
+SET(FLAGS "${FLAGS} -DPKG_DATADIR=\\\"${PKG_DATADIR}/\\\"")
+SET(FLAGS "${FLAGS} -DLOCALEDIR=\\\"${LOCALEDIR}/\\\"")
+
+IF (CMAKE_BUILD_TYPE)
+ STRING(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_TOLOWER)
+ IF((CMAKE_BUILD_TYPE_TOLOWER MATCHES debug) OR
+ (CMAKE_BUILD_TYPE_TOLOWER MATCHES relwithdebinfo))
+ SET(FLAGS "${FLAGS} -DDEBUG")
+ ENDIF()
+ENDIF()
+
+INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${SDL_INCLUDE_DIR}
+ ${SDLIMAGE_INCLUDE_DIR}
+ ${PNG_INCLUDE_DIR}
+ )
+
+# Fix some stuff that gets not hidden by mainline modules
+MARK_AS_ADVANCED(SDLIMAGE_INCLUDE_DIR)
+MARK_AS_ADVANCED(SDLIMAGE_LIBRARY)
+MARK_AS_ADVANCED(SDLMAIN_LIBRARY)
+MARK_AS_ADVANCED(SDL_INCLUDE_DIR)
+MARK_AS_ADVANCED(SDL_LIBRARY)
+
+SET(SRCS
+ dye.cpp
+ dye.h
+ dyecmd.cpp
+ imagewriter.cpp
+ imagewriter.h
+ )
+
+SET (PROGRAMS dyecmd)
+
+ADD_EXECUTABLE(dyecmd WIN32 ${SRCS})
+
+TARGET_LINK_LIBRARIES(dyecmd
+ ${SDL_LIBRARY}
+ ${SDLIMAGE_LIBRARY}
+ ${PNG_LIBRARIES})
+
+SET_TARGET_PROPERTIES(dyecmd PROPERTIES COMPILE_FLAGS "${FLAGS}")
diff --git a/tools/dyecmd/src/dye.cpp b/tools/dyecmd/src/dye.cpp
index 76b759cc..77da2ebb 100644..100755
--- a/tools/dyecmd/src/dye.cpp
+++ b/tools/dyecmd/src/dye.cpp
@@ -21,16 +21,20 @@
#include <algorithm>
#include <sstream>
+#include <iostream>
#include "dye.h"
Palette::Palette(const std::string &description)
{
+ mLoaded = false;
int size = description.length();
if (size == 0) return;
if (description[0] != '#')
{
- throw;
+ std::cout << "Missing # in the palette description "
+ << "in the third parameter." << std::endl;
+ return;
}
int pos = 1;
@@ -42,25 +46,41 @@ Palette::Palette(const std::string &description)
{
char c = description[pos + i];
int n;
- if ('0' <= c && c <= '9') n = c - '0';
- else if ('A' <= c && c <= 'F') n = c - 'A' + 10;
- else if ('a' <= c && c <= 'f') n = c - 'a' + 10;
+ if ('0' <= c && c <= '9')
+ n = c - '0';
+ else if ('A' <= c && c <= 'F')
+ n = c - 'A' + 10;
+ else if ('a' <= c && c <= 'f')
+ n = c - 'a' + 10;
else
- throw;
+ {
+ std::cout << "invalid Hexadecimal description: "
+ << description << std::endl;
+ return;
+ }
v = (v << 4) | n;
}
Color c = { { v >> 16, v >> 8, v } };
mColors.push_back(c);
pos += 6;
- if (pos == size) return;
- if (description[pos] != ',') break;
+ if (pos == size)
+ {
+ mLoaded = true;
+ return;
+ }
+ if (description[pos] != ',')
+ break;
+
++pos;
}
+
+ mLoaded = true;
}
void Palette::getColor(int intensity, int color[3]) const
{
+ // Return implicit black
if (intensity == 0)
{
color[0] = 0;
@@ -107,6 +127,7 @@ void Palette::getColor(int intensity, int color[3]) const
Dye::Dye(const std::string &description)
{
+ mLoaded = false;
for (int i = 0; i < 7; ++i)
mPalettes[i] = 0;
@@ -121,7 +142,9 @@ Dye::Dye(const std::string &description)
next_pos = length;
if (next_pos <= pos + 3 || description[pos + 1] != ':')
{
- throw;
+ std::cout << "Dyeing: Missing ':' in channel description."
+ << std::endl;
+ return;
}
int i = 0;
switch (description[pos])
@@ -134,12 +157,21 @@ Dye::Dye(const std::string &description)
case 'C': i = 5; break;
case 'W': i = 6; break;
default:
- throw;
+ std::cout << "Dyeing: Invalid channel. Not in [R,G,Y,B,M,C,W]"
+ << std::endl;
+ return;
}
- mPalettes[i] = new Palette(description.substr(pos + 2, next_pos - pos - 2));
+ mPalettes[i] = new Palette(
+ description.substr(pos + 2, next_pos - pos - 2));
+
+ if (!mPalettes[i]->loaded())
+ return;
+
++next_pos;
}
while (next_pos < length);
+
+ mLoaded = true;
}
Dye::~Dye()
@@ -168,47 +200,3 @@ void Dye::update(int color[3]) const
if (mPalettes[i - 1])
mPalettes[i - 1]->getColor(cmax, color);
}
-
-void Dye::instantiate(std::string &target, const std::string &palettes)
-{
- std::string::size_type next_pos = target.find('|');
- if (next_pos == std::string::npos || palettes.empty()) return;
- ++next_pos;
-
- std::ostringstream s;
- s << target.substr(0, next_pos);
- std::string::size_type last_pos = target.length(), pal_pos = 0;
- do
- {
- std::string::size_type pos = next_pos;
- next_pos = target.find(';', pos);
- if (next_pos == std::string::npos) next_pos = last_pos;
- if (next_pos == pos + 1 && pal_pos != std::string::npos)
- {
- std::string::size_type pal_next_pos = palettes.find(';', pal_pos);
- s << target[pos] << ':';
- if (pal_next_pos == std::string::npos)
- {
- s << palettes.substr(pal_pos);
- s << target.substr(next_pos);
- pal_pos = std::string::npos;
- break;
- }
- s << palettes.substr(pal_pos, pal_next_pos - pal_pos);
- pal_pos = pal_next_pos + 1;
- }
- else if (next_pos > pos + 2)
- {
- s << target.substr(pos, next_pos - pos);
- }
- else
- {
- throw;
- }
- s << target[next_pos];
- ++next_pos;
- }
- while (next_pos < last_pos);
-
- target = s.str();
-}
diff --git a/tools/dyecmd/src/dye.h b/tools/dyecmd/src/dye.h
index 5a8fe1b5..922f3370 100644..100755
--- a/tools/dyecmd/src/dye.h
+++ b/tools/dyecmd/src/dye.h
@@ -45,11 +45,19 @@ class Palette
*/
void getColor(int intensity, int color[3]) const;
+ /**
+ * Tells if the palette was successfully loaded.
+ */
+ bool loaded() const
+ { return mLoaded; }
+
private:
struct Color { unsigned char value[3]; };
std::vector< Color > mColors;
+
+ bool mLoaded;
};
/**
@@ -73,15 +81,15 @@ class Dye
~Dye();
/**
- * Modifies a pixel color.
+ * Tells if the dye description was successfully loaded.
*/
- void update(int color[3]) const;
+ bool loaded() const
+ { return mLoaded; }
/**
- * Fills the blank in a dye placeholder with some palette names.
+ * Modifies a pixel color.
*/
- static void instantiate(std::string &target,
- const std::string &palettes);
+ void update(int color[3]) const;
private:
@@ -91,6 +99,7 @@ class Dye
* Red, Green, Yellow, Blue, Magenta, White (or rather gray).
*/
Palette *mPalettes[7];
+ bool mLoaded;
};
#endif
diff --git a/tools/dyecmd/src/dyecmd.cpp b/tools/dyecmd/src/dyecmd.cpp
index ebecf9f1..5e06e500 100644..100755
--- a/tools/dyecmd/src/dyecmd.cpp
+++ b/tools/dyecmd/src/dyecmd.cpp
@@ -23,19 +23,20 @@
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
-
-
#include "dye.h"
#include "imagewriter.h"
using namespace std;
// return values
-#define RETURN_OK 1
-#define INVALID_PARAMETER_LIST 100
-#define INVALID_INPUT_IMAGE 101
-#define INVALID_OUTPUT_IMAGE 102
-#define INVALID_DYE_PARAMETER 105
+enum ReturnValues
+{
+ RETURN_OK = 0,
+ INVALID_PARAMETER_LIST = 100,
+ INVALID_INPUT_IMAGE = 101,
+ INVALID_OUTPUT_IMAGE = 102,
+ INVALID_DYE_PARAMETER = 105
+};
SDL_Surface* recolor(SDL_Surface* tmpImage, Dye* dye)
{
@@ -51,71 +52,104 @@ SDL_Surface* recolor(SDL_Surface* tmpImage, Dye* dye)
rgba.alpha = 255;
SDL_Surface *surf = SDL_ConvertSurface(tmpImage, &rgba, SDL_SWSURFACE);
- //SDL_FreeSurface(tmpImage);
+ //SDL_FreeSurface(tmpImage); <-- We'll free the surface later.
Uint32 *pixels = static_cast< Uint32 * >(surf->pixels);
for (Uint32 *p_end = pixels + surf->w * surf->h; pixels != p_end; ++pixels)
{
- int alpha = *pixels & 255;
+ int alpha = (*pixels >> rgba.Ashift) & 255;
if (!alpha) continue;
int v[3];
- v[0] = (*pixels >> 24) & 255;
- v[1] = (*pixels >> 16) & 255;
- v[2] = (*pixels >> 8 ) & 255;
+
+ v[0] = (*pixels >> rgba.Rshift) & 255;
+ v[1] = (*pixels >> rgba.Gshift) & 255;
+ v[2] = (*pixels >> rgba.Bshift) & 255;
dye->update(v);
+
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
*pixels = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | alpha;
+#else
+ *pixels = v[0] | (v[1] << 8) | (v[2] << 16) | (alpha << 24);
+#endif
}
return surf;
}
+void printHelp()
+{
+ cout << endl
+ << "This tool is used to dye item graphics used by the Mana client "
+ << "according to the specification described here: "
+ << endl << "http://doc.manasource.org/image_dyeing_system"
+ << endl << endl <<
+ "The tool expects 3 parameters:" << endl
+ << "dyecmd <source_image> <target_image> <dye_string>" << endl
+ << "e.g.:" << endl
+ << "dyecmd \"armor-legs-shorts.png\" "
+ <<"\"armor-legs-shorts2.png\" \"W:#222255,6666ff\"" << std::endl;
+}
+
int main(int argc, char* argv[])
{
Dye* dye = NULL;
- SDL_Surface* source = NULL;
+ SDL_Surface* source = NULL, *target = NULL;
+ ReturnValues returnValue = RETURN_OK;
- // not enough or to many parameters
- if (argc != 4)
+ if (argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")))
{
- cout << INVALID_PARAMETER_LIST << " - INVALID_PARAMETER_LIST";
- exit(INVALID_PARAMETER_LIST);
+ printHelp();
}
-
- try
+ // not enough or to many parameters
+ else if (argc != 4)
{
- dye = new Dye(argv[3]);
+ cout << INVALID_PARAMETER_LIST << " - INVALID_PARAMETER_LIST";
+ printHelp();
+ returnValue = INVALID_PARAMETER_LIST;
}
- catch (exception &e)
+ else
{
- cout << INVALID_DYE_PARAMETER << " - INVALID_DYE_PARAMETER";
- exit(INVALID_DYE_PARAMETER);
- }
+ // Start dyeing process.
+ string inputFile = argv[1];
+ string outputFile = argv[2];
+ string dyeDescription = argv[3];
- try
- {
- source = IMG_Load(argv[1]);
- if (!source)
+ dye = new Dye(dyeDescription);
+ if (!dye->loaded())
{
- throw;
+ cout << INVALID_DYE_PARAMETER << " - INVALID_DYE_PARAMETER";
+ printHelp();
+ returnValue = INVALID_DYE_PARAMETER;
}
- }
- catch (exception &e)
- {
- cout << INVALID_INPUT_IMAGE << " - INVALID_INPUT_IMAGE";
- exit(INVALID_INPUT_IMAGE);
- }
-
- SDL_Surface* target = recolor(source, dye);
-
- if (!ImageWriter::writePNG(target, argv[2]))
- {
- cout << INVALID_OUTPUT_IMAGE << " - INVALID_OUTPUT_IMAGE";
- exit(INVALID_OUTPUT_IMAGE);
- }
-
- SDL_FreeSurface(source);
- SDL_FreeSurface(target);
- delete dye;
-
- return 0;
+ else
+ {
+ source = IMG_Load(inputFile.c_str());
+ if (!source)
+ {
+ cout << INVALID_INPUT_IMAGE << " - INVALID_INPUT_IMAGE";
+ printHelp();
+ returnValue = INVALID_INPUT_IMAGE;
+ }
+ else
+ {
+ target = recolor(source, dye);
+
+ if (!ImageWriter::writePNG(target, outputFile))
+ {
+ cout << INVALID_OUTPUT_IMAGE << " - INVALID_OUTPUT_IMAGE";
+ printHelp();
+ returnValue = INVALID_OUTPUT_IMAGE;
+ }
+ } // Valid source image file
+ } // Valid dye parameter
+ } // Parameters ok
+
+ if (source)
+ SDL_FreeSurface(source);
+ if (target)
+ SDL_FreeSurface(target);
+ if (dye)
+ delete dye;
+
+ return returnValue;
}
diff --git a/tools/dyecmd/src/imagewriter.cpp b/tools/dyecmd/src/imagewriter.cpp
index 669b3567..d237abbf 100644..100755
--- a/tools/dyecmd/src/imagewriter.cpp
+++ b/tools/dyecmd/src/imagewriter.cpp
@@ -22,6 +22,7 @@
#include "imagewriter.h"
#include <png.h>
+#include <iostream>
#include <string>
#include <SDL/SDL.h>
@@ -32,8 +33,8 @@ bool ImageWriter::writePNG(SDL_Surface *surface,
FILE *fp = fopen(filename.c_str(), "wb");
if (!fp)
{
- // todo
- // logger->log("could not open file %s for writing", filename.c_str());
+ std::cout << "PNG writer: Could not open file for writing: "
+ << filename << std::endl;
return false;
}
@@ -49,8 +50,8 @@ bool ImageWriter::writePNG(SDL_Surface *surface,
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (!png_ptr)
{
- // todo
- // logger->log("Had trouble creating png_structp");
+ std::cout << "PNG writer: Had trouble creating png_structp"
+ << std::endl;
return false;
}
@@ -58,16 +59,15 @@ bool ImageWriter::writePNG(SDL_Surface *surface,
if (!info_ptr)
{
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
- // todo
- // logger->log("Could not create png_info");
+ std::cout << "PNG writer: Could not create png_info" << std::endl;
return false;
}
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
- // todo
- // logger->log("problem writing to %s", filename.c_str());
+ std::cout << "PNG writer: problem writing to : "
+ << filename << std::endl;
return false;
}
@@ -86,8 +86,9 @@ bool ImageWriter::writePNG(SDL_Surface *surface,
row_pointers = new png_bytep[surface->h];
if (!row_pointers)
{
- // todo
- // logger->log("Had trouble converting surface to row pointers");
+ std::cout
+ << "PNG writer: Had trouble converting surface to row pointers"
+ << std::endl;
return false;
}
@@ -105,9 +106,8 @@ bool ImageWriter::writePNG(SDL_Surface *surface,
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
- if (SDL_MUSTLOCK(surface)) {
+ if (SDL_MUSTLOCK(surface))
SDL_UnlockSurface(surface);
- }
return true;
}
diff --git a/tools/dyecmd/src/imagewriter.h b/tools/dyecmd/src/imagewriter.h
index a8bcdf57..a8bcdf57 100644..100755
--- a/tools/dyecmd/src/imagewriter.h
+++ b/tools/dyecmd/src/imagewriter.h