1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-05 19:45:33 +00:00

Merge commit 'ape/master'

This commit is contained in:
Marc Zinnschlag 2010-08-16 20:39:16 +02:00
commit e69a924036
4 changed files with 706 additions and 531 deletions

View file

@ -14,6 +14,11 @@ IF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
SET(ICONV_FIND_QUIETLY TRUE) SET(ICONV_FIND_QUIETLY TRUE)
ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
IF(WIN32)
SET(ICONV_INCLUDE_DIR $ENV{ICONV_INCLUDE_DIR})
SET(ICONV_LIBRARIES $ENV{ICONV_LIBRARIES})
ENDIF(WIN32)
FIND_PATH(ICONV_INCLUDE_DIR iconv.h) FIND_PATH(ICONV_INCLUDE_DIR iconv.h)
FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv c) FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv c)

View file

@ -9,7 +9,10 @@
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
#include <errno.h> #include <errno.h>
#include <iconv.h>
#ifndef __WIN32__
#include <iconv.h>
#endif
#include <libs/mangle/stream/stream.hpp> #include <libs/mangle/stream/stream.hpp>
#include <libs/mangle/stream/servers/file_stream.hpp> #include <libs/mangle/stream/servers/file_stream.hpp>
@ -618,89 +621,93 @@ public:
return convertToUTF8(res); return convertToUTF8(res);
} }
// Convert a string from the encoding used by Morrowind to UTF-8 // Convert a string from the encoding used by Morrowind to UTF-8
std::string convertToUTF8(std::string input) std::string convertToUTF8 (std::string input)
{
std::string output = "";
//create convert description
iconv_t cd = iconv_open("UTF-8", "WINDOWS-1252");
if (cd == (iconv_t)-1) //error handling
{ {
std::string errMsg = "Creating description for UTF-8 converting failed: "; #ifdef __WIN32__
return input;
#else
std::string output = "";
switch (errno) //detailed error messages (maybe it contains too much detail :) //create convert description
{ iconv_t cd = iconv_open ("UTF-8", "WINDOWS-1252");
case EMFILE:
errMsg += "{OPEN_MAX} files descriptors are currently open in the calling process.";
case ENFILE:
errMsg += "Too many files are currently open in the system.";
case ENOMEM:
errMsg +="Insufficient storage space is available.";
case EINVAL:
errMsg += "The conversion specified by fromcode and tocode is not supported by the implementation.";
default: if (cd == (iconv_t)-1) //error handling
errMsg += "Unknown Error\n";
}
fail(errMsg);
}
else
{
const size_t inputSize = input.size();
if (inputSize) //input is not empty
{
//convert function doesn't accept const char *, therefore copy content into an char *
std::vector<char> inputBuffer(input.begin(), input.end());
char *inputBufferBegin = &inputBuffer[0];
size_t inputBytesLeft = inputSize; //bytes to convert
static const size_t outputSize = 1000;
size_t outputBytesLeft;
char outputBuffer[outputSize];
char *outputBufferBegin;
while (inputBytesLeft > 0 )
{ {
outputBytesLeft = outputSize; std::string errMsg = "Creating description for UTF-8 converting failed: ";
outputBufferBegin = outputBuffer;
if (iconv(cd, &inputBufferBegin, &inputBytesLeft, &outputBufferBegin, &outputBytesLeft) == (size_t)-1) switch (errno) //detailed error messages (maybe it contains too much detail :)
{
switch (errno)
{ {
case E2BIG: //outputBuffer is full case EMFILE:
output += std::string(outputBuffer, outputSize); errMsg += "{OPEN_MAX} files descriptors are currently open in the calling process.";
break; case ENFILE:
case EILSEQ: errMsg += "Too many files are currently open in the system.";
fail("Iconv: Invalid multibyte sequence.\n"); case ENOMEM:
break; errMsg +="Insufficient storage space is available.";
case EINVAL: case EINVAL:
fail("Iconv: Incomplete multibyte sequence.\n"); errMsg += "The conversion specified by fromcode and tocode is not supported by the implementation.";
break;
default: default:
fail("Iconv: Unknown Error\n"); errMsg += "Unknown Error\n";
} }
} fail (errMsg);
}
else
{
const size_t inputSize = input.size();
if (inputSize) //input is not empty
{
//convert function doesn't accept const char *, therefore copy content into an char *
std::vector<char> inputBuffer (input.begin(), input.end());
char *inputBufferBegin = &inputBuffer[0];
size_t inputBytesLeft = inputSize; //bytes to convert
static const size_t outputSize = 1000;
size_t outputBytesLeft;
char outputBuffer[outputSize];
char *outputBufferBegin;
while (inputBytesLeft > 0)
{
outputBytesLeft = outputSize;
outputBufferBegin = outputBuffer;
if (iconv (cd, &inputBufferBegin, &inputBytesLeft, &outputBufferBegin, &outputBytesLeft) == (size_t)-1)
{
switch (errno)
{
case E2BIG: //outputBuffer is full
output += std::string (outputBuffer, outputSize);
break;
case EILSEQ:
fail ("Iconv: Invalid multibyte sequence.\n");
break;
case EINVAL:
fail ("Iconv: Incomplete multibyte sequence.\n");
break;
default:
fail ("Iconv: Unknown Error\n");
}
}
}
//read only relevant bytes from outputBuffer
output += std::string (outputBuffer, outputSize - outputBytesLeft);
}
} }
//read only relevant bytes from outputBuffer iconv_close (cd);
output += std::string(outputBuffer, outputSize - outputBytesLeft);
} return output;
} }
#endif
iconv_close (cd);
return output;
}
void skip(int bytes) { esm->seek(esm->tell()+bytes); } void skip(int bytes) { esm->seek(esm->tell()+bytes); }
uint64_t getOffset() { return esm->tell(); } uint64_t getOffset() { return esm->tell(); }

File diff suppressed because it is too large Load diff

View file

@ -27,6 +27,27 @@
#include <OgreResource.h> #include <OgreResource.h>
#include <OgreMesh.h> #include <OgreMesh.h>
#include <assert.h> #include <assert.h>
#include <string>
class BoundsFinder;
namespace Nif
{
class Node;
class Transformation;
class NiTriShape;
class Vector;
class Matrix;
}
namespace Mangle
{
namespace VFS
{
class OgreVFS;
}
}
/** Manual resource loader for NIF meshes. This is the main class /** Manual resource loader for NIF meshes. This is the main class
responsible for translating the internal NIF mesh structure into responsible for translating the internal NIF mesh structure into
@ -43,12 +64,66 @@
very resource intensive, and can safely be done for a large number very resource intensive, and can safely be done for a large number
of meshes at load time. of meshes at load time.
*/ */
struct NIFLoader : Ogre::ManualResourceLoader class NIFLoader : Ogre::ManualResourceLoader
{ {
void loadResource(Ogre::Resource *resource); public:
static NIFLoader& getSingleton();
static NIFLoader* getSingletonPtr();
static Ogre::MeshPtr load(const std::string &name, virtual void loadResource(Ogre::Resource *resource);
const std::string &group="General");
static Ogre::MeshPtr load(const std::string &name,
const std::string &group="General");
Ogre::Vector3 convertVector3(const Nif::Vector& vec);
Ogre::Quaternion convertRotation(const Nif::Matrix& rot);
private:
NIFLoader() : resourceGroup("General") {}
NIFLoader(NIFLoader& n) {}
void warn(std::string msg);
void fail(std::string msg);
void handleNode( Nif::Node *node, int flags,
const Nif::Transformation *trafo, BoundsFinder &bounds, Ogre::Bone *parentBone);
void handleNiTriShape(Nif::NiTriShape *shape, int flags, BoundsFinder &bounds);
void createOgreSubMesh(Nif::NiTriShape *shape, const Ogre::String &material);
void createMaterial(const Ogre::String &name,
const Nif::Vector &ambient,
const Nif::Vector &diffuse,
const Nif::Vector &specular,
const Nif::Vector &emissive,
float glossiness, float alpha,
float alphaFlags, float alphaTest,
const Ogre::String &texName);
void findRealTexture(Ogre::String &texName);
Ogre::String getUniqueName(const Ogre::String &input);
//returns the skeleton name of this mesh
std::string getSkeletonName()
{
return resourceName + ".skel";
}
// This is the interface to the Ogre resource system. It allows us to
// load NIFs from BSAs, in the file system and in any other place we
// tell Ogre to look (eg. in zip or rar files.) It's also used to
// check for the existence of texture files, so we can exchange the
// extension from .tga to .dds if the texture is missing.
Mangle::VFS::OgreVFS *vfs;
std::string resourceName;
std::string resourceGroup;
// pointer to the ogre mesh which is currently build
Ogre::Mesh *mesh;
Ogre::SkeletonPtr skel;
}; };
#endif #endif