Merge remote-tracking branch 'greye/widechar'

deque
Marc Zinnschlag 11 years ago
commit 244eb11651

@ -119,6 +119,7 @@ set(OENGINE_OGRE
)
set(OENGINE_GUI
${LIBDIR}/openengine/gui/loglistener.cpp
${LIBDIR}/openengine/gui/manager.cpp
${LIBDIR}/openengine/gui/layout.hpp
)
@ -224,6 +225,9 @@ endif ()
set(BOOST_COMPONENTS system filesystem program_options)
if(WIN32)
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale)
endif(WIN32)
IF(BOOST_STATIC)
set(Boost_USE_STATIC_LIBS ON)

@ -41,11 +41,11 @@ Launcher::MainDialog::MainDialog(QWidget *parent)
// Check if the font is installed
if (!fonts.contains("EB Garamond")) {
QString font = QString::fromStdString(mCfgMgr.getGlobalDataPath().string()) + QString("resources/mygui/EBGaramond-Regular.ttf");
QString font = QString::fromUtf8(mCfgMgr.getGlobalDataPath().string().c_str()) + QString("resources/mygui/EBGaramond-Regular.ttf");
file.setFileName(font);
if (!file.exists()) {
font = QString::fromStdString(mCfgMgr.getLocalPath().string()) + QString("resources/mygui/EBGaramond-Regular.ttf");
font = QString::fromUtf8(mCfgMgr.getLocalPath().string().c_str()) + QString("resources/mygui/EBGaramond-Regular.ttf");
}
fontDatabase.addApplicationFont(font);
@ -243,7 +243,7 @@ bool Launcher::MainDialog::showFirstRunDialog()
}
// Create the file if it doesn't already exist, else the importer will fail
QString path = QString::fromStdString(mCfgMgr.getUserConfigPath().string()) + QString("openmw.cfg");
QString path = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()) + QString("openmw.cfg");
QFile file(path);
if (!file.exists()) {
@ -358,7 +358,7 @@ bool Launcher::MainDialog::setupLauncherSettings()
{
mLauncherSettings.setMultiValueEnabled(true);
QString userPath = QString::fromStdString(mCfgMgr.getUserConfigPath().string());
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
QStringList paths;
paths.append(QString("launcher.cfg"));
@ -464,8 +464,8 @@ bool Launcher::expansions(Launcher::UnshieldThread& cd)
bool Launcher::MainDialog::setupGameSettings()
{
QString userPath = QString::fromStdString(mCfgMgr.getUserConfigPath().string());
QString globalPath = QString::fromStdString(mCfgMgr.getGlobalPath().string());
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
QString globalPath = QString::fromUtf8(mCfgMgr.getGlobalPath().string().c_str());
// Load the user config file first, separately
// So we can write it properly, uncontaminated
@ -594,7 +594,7 @@ bool Launcher::MainDialog::setupGameSettings()
while(expansions(cd));
selectedFile = QString::fromStdString(cd.GetMWEsmPath());
selectedFile = QString::fromUtf8(cd.GetMWEsmPath().c_str());
}
#endif // WIN32
@ -615,8 +615,8 @@ bool Launcher::MainDialog::setupGraphicsSettings()
{
mGraphicsSettings.setMultiValueEnabled(false);
QString userPath = QString::fromStdString(mCfgMgr.getUserConfigPath().string());
QString globalPath = QString::fromStdString(mCfgMgr.getGlobalPath().string());
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
QString globalPath = QString::fromUtf8(mCfgMgr.getGlobalPath().string().c_str());
QFile localDefault(QString("settings-default.cfg"));
QFile globalDefault(globalPath + QString("settings-default.cfg"));
@ -702,7 +702,7 @@ bool Launcher::MainDialog::writeSettings()
mGraphicsPage->saveSettings();
mDataFilesPage->saveSettings();
QString userPath = QString::fromStdString(mCfgMgr.getUserConfigPath().string());
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
QDir dir(userPath);
if (!dir.exists()) {

@ -45,7 +45,8 @@ void Launcher::GameSettings::validatePaths()
Files::PathContainer dataDirs;
foreach (const QString &path, paths) {
dataDirs.push_back(Files::PathContainer::value_type(path.toStdString()));
QByteArray bytes = path.toUtf8();
dataDirs.push_back(Files::PathContainer::value_type(std::string(bytes.constData(), bytes.length())));
}
// Parse the data dirs to convert the tokenized paths
@ -53,7 +54,7 @@ void Launcher::GameSettings::validatePaths()
mDataDirs.clear();
for (Files::PathContainer::iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) {
QString path = QString::fromStdString(it->string());
QString path = QString::fromUtf8(it->string().c_str());
path.remove(QChar('\"'));
QDir dir(path);
@ -68,12 +69,13 @@ void Launcher::GameSettings::validatePaths()
return;
dataDirs.clear();
dataDirs.push_back(Files::PathContainer::value_type(local.toStdString()));
QByteArray bytes = local.toUtf8();
dataDirs.push_back(Files::PathContainer::value_type(std::string(bytes.constData(), bytes.length())));
mCfgMgr.processPaths(dataDirs);
if (!dataDirs.empty()) {
QString path = QString::fromStdString(dataDirs.front().string());
QString path = QString::fromUtf8(dataDirs.front().string().c_str());
path.remove(QChar('\"'));
QDir dir(path);

@ -1,6 +1,6 @@
#include "unshieldthread.hpp"
#include <fstream>
#include <boost/filesystem/fstream.hpp>
#include <components/misc/stringops.hpp>
namespace bfs = boost::filesystem;
@ -49,7 +49,7 @@ namespace
std::string read_to_string(const bfs::path& path)
{
std::ifstream strstream(path.c_str(), std::ios::in | std::ios::binary);
bfs::ifstream strstream(path, std::ios::in | std::ios::binary);
std::string str;
strstream.seekg(0, std::ios::end);
@ -201,7 +201,7 @@ namespace
add_setting("Archives", "Archive 1", "Bloodmoon.bsa", ini);
}
std::ofstream inistream(ini_path.c_str());
bfs::ofstream inistream((ini_path));
inistream << ini;
inistream.close();
}

@ -1,6 +1,5 @@
#include "importer.hpp"
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/stream.hpp>
#include <iostream>
#include <string>
#include <map>
@ -9,6 +8,10 @@
#include <sstream>
#include <components/misc/stringops.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/fstream.hpp>
namespace bfs = boost::filesystem;
MwIniImporter::MwIniImporter()
: mVerbose(false)
@ -661,7 +664,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::string& filenam
std::string section("");
MwIniImporter::multistrmap map;
boost::iostreams::stream<boost::iostreams::file_source>file(filename.c_str());
bfs::ifstream file((bfs::path(filename)));
ToUTF8::Utf8Encoder encoder(mEncoding);
std::string line;
@ -674,6 +677,10 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::string& filenam
line = line.substr(0, line.length()-1);
}
if(line.empty()) {
continue;
}
if(line[0] == '[') {
int pos = line.find(']');
if(pos < 2) {
@ -690,10 +697,6 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::string& filenam
line = line.substr(0,comment_pos);
}
if(line.empty()) {
continue;
}
int pos = line.find("=");
if(pos < 1) {
continue;
@ -720,7 +723,7 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::string& filenam
std::cout << "load cfg file: " << filename << std::endl;
MwIniImporter::multistrmap map;
boost::iostreams::stream<boost::iostreams::file_source>file(filename.c_str());
bfs::ifstream file((bfs::path(filename)));
std::string line;
while (std::getline(file, line)) {
@ -858,7 +861,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini) co
}
}
void MwIniImporter::writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, const multistrmap &cfg) {
void MwIniImporter::writeToFile(std::ostream &out, const multistrmap &cfg) {
for(multistrmap::const_iterator it=cfg.begin(); it != cfg.end(); ++it) {
for(std::vector<std::string>::const_iterator entry=it->second.begin(); entry != it->second.end(); ++entry) {

@ -1,12 +1,11 @@
#ifndef MWINIIMPORTER_IMPORTER
#define MWINIIMPORTER_IMPORTER 1
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/stream.hpp>
#include <string>
#include <map>
#include <vector>
#include <exception>
#include <iosfwd>
#include <components/to_utf8/to_utf8.hpp>
@ -24,7 +23,7 @@ class MwIniImporter {
void mergeFallback(multistrmap &cfg, const multistrmap &ini) const;
void importGameFiles(multistrmap &cfg, const multistrmap &ini) const;
void importArchives(multistrmap &cfg, const multistrmap &ini) const;
static void writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, const multistrmap &cfg);
static void writeToFile(std::ostream &out, const multistrmap &cfg);
private:
static void insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value);

@ -1,14 +1,58 @@
#include "importer.hpp"
#include <iostream>
#include <string>
#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/fstream.hpp>
namespace bpo = boost::program_options;
namespace bfs = boost::filesystem;
#ifndef _WIN32
int main(int argc, char *argv[]) {
#else
// Include on Windows only
#include <boost/locale.hpp>
class utf8argv
{
public:
utf8argv(int argc, wchar_t *wargv[])
{
args.reserve(argc);
argv = new const char *[argc];
for (int i = 0; i < argc; ++i) {
args.push_back(boost::locale::conv::utf_to_utf<char>(wargv[i]));
argv[i] = args.back().c_str();
}
}
~utf8argv() { delete[] argv; }
char **get() const { return const_cast<char **>(argv); }
private:
const char **argv;
std::vector<std::string> args;
};
/* The only way to pass Unicode on Winodws with CLI is to use wide
characters interface which presents UTF-16 encoding. The rest of
OpenMW application stack assumes UTF-8 encoding, therefore this
conversion.
For boost::filesystem::path::imbue see components/files/windowspath.cpp
*/
int wmain(int argc, wchar_t *wargv[]) {
utf8argv converter(argc, wargv);
char **argv = converter.get();
boost::filesystem::path::imbue(boost::locale::generator().generate(""));
#endif
bpo::options_description desc("Syntax: mwiniimporter <options> inifile configfile\nAllowed options");
bpo::positional_options_description p_desc;
desc.add_options()
@ -94,7 +138,7 @@ int main(int argc, char *argv[]) {
}
std::cout << "write to: " << outputFile << std::endl;
boost::iostreams::stream<boost::iostreams::file_sink> file(outputFile);
bfs::ofstream file((bfs::path(outputFile)));
importer.writeToFile(file, cfg);
return 0;

@ -145,6 +145,10 @@ if(WIN32)
endif(WIN32)
set(BOOST_COMPONENTS system filesystem program_options thread wave)
if(WIN32)
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale)
endif(WIN32)
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED)

@ -27,7 +27,9 @@ void CSMDoc::OpenSaveStage::perform (int stage, Messages& messages)
{
mState.start (mDocument, mProjectFile);
mState.getStream().open ((mProjectFile ? mState.getPath() : mState.getTmpPath()).string().c_str());
mState.getStream().open (
mProjectFile ? mState.getPath() : mState.getTmpPath(),
std::ios::binary);
if (!mState.getStream().is_open())
throw std::runtime_error ("failed to open stream for saving");
@ -260,4 +262,4 @@ void CSMDoc::FinalSavingStage::perform (int stage, Messages& messages)
mDocument.getUndoStack().setClean();
}
}
}

@ -47,7 +47,7 @@ const boost::filesystem::path& CSMDoc::SavingState::getTmpPath() const
return mTmpPath;
}
std::ofstream& CSMDoc::SavingState::getStream()
boost::filesystem::ofstream& CSMDoc::SavingState::getStream()
{
return mStream;
}
@ -60,4 +60,4 @@ ESM::ESMWriter& CSMDoc::SavingState::getWriter()
bool CSMDoc::SavingState::isProjectFile() const
{
return mProjectFile;
}
}

@ -4,6 +4,7 @@
#include <fstream>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/fstream.hpp>
#include <components/esm/esmwriter.hpp>
@ -20,7 +21,7 @@ namespace CSMDoc
boost::filesystem::path mPath;
boost::filesystem::path mTmpPath;
ToUTF8::Utf8Encoder mEncoder;
std::ofstream mStream;
boost::filesystem::ofstream mStream;
ESM::ESMWriter mWriter;
boost::filesystem::path mProjectPath;
bool mProjectFile;
@ -39,7 +40,7 @@ namespace CSMDoc
const boost::filesystem::path& getTmpPath() const;
std::ofstream& getStream();
boost::filesystem::ofstream& getStream();
ESM::ESMWriter& getWriter();
@ -50,4 +51,4 @@ namespace CSMDoc
}
#endif
#endif

@ -83,6 +83,10 @@ add_openmw_dir (mwbase
# Main executable
set(BOOST_COMPONENTS system filesystem program_options thread wave)
if(WIN32)
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale)
endif(WIN32)
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
IF(OGRE_STATIC)

@ -236,7 +236,7 @@ void OMW::Engine::addArchive (const std::string& archive) {
// Set resource dir
void OMW::Engine::setResourceDir (const boost::filesystem::path& parResDir)
{
mResDir = boost::filesystem::system_complete(parResDir);
mResDir = parResDir;
}
// Set start cell name (only interiors for now)

@ -1,5 +1,8 @@
#include "console.hpp"
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <components/compiler/exception.hpp>
#include <components/compiler/extensions0.hpp>
@ -194,7 +197,8 @@ namespace MWGui
void Console::executeFile (const std::string& path)
{
std::ifstream stream (path.c_str());
namespace bfs = boost::filesystem;
bfs::ifstream stream ((bfs::path(path)));
if (!stream.is_open())
printError ("failed to open file: " + path);

@ -12,6 +12,8 @@
#include <OgreImage.h>
#include <boost/filesystem/fstream.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/journal.hpp"
@ -185,7 +187,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
else
slot = mCharacterManager.getCurrentCharacter()->updateSlot (slot, profile);
std::ofstream stream (slot->mPath.string().c_str(), std::ios::binary);
boost::filesystem::ofstream stream (slot->mPath, std::ios::binary);
ESM::ESMWriter writer;

@ -25,6 +25,9 @@
#include <stdexcept>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/fstream.hpp>
#include "../files/constrainedfiledatastream.hpp"
using namespace std;
@ -72,7 +75,8 @@ void BSAFile::readHeader()
*/
assert(!isLoaded);
std::ifstream input(filename.c_str(), std::ios_base::binary);
namespace bfs = boost::filesystem;
bfs::ifstream input(bfs::path(filename), std::ios_base::binary);
// Total archive size
size_t fsize = 0;

@ -1,12 +1,12 @@
#include "configurationmanager.hpp"
#include <string>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/algorithm/string/erase.hpp>
#include <boost/filesystem/fstream.hpp>
/**
* \namespace Files
@ -125,7 +125,7 @@ void ConfigurationManager::loadConfig(const boost::filesystem::path& path,
{
std::cout << "Loading config file: " << cfgFile.string() << "... ";
std::ifstream configFileStream(cfgFile.string().c_str());
boost::filesystem::ifstream configFileStream(cfgFile);
if (configFileStream.is_open())
{
boost::program_options::store(boost::program_options::parse_config_file(

@ -206,6 +206,8 @@ size_t LowLevelFile::read (void * data, size_t size)
}
#elif FILE_API == FILE_API_WIN32
#include <boost/locale.hpp>
/*
*
* Implementation of LowLevelFile methods using Win32 API calls
@ -227,9 +229,10 @@ void LowLevelFile::open (char const * filename)
{
assert (mHandle == INVALID_HANDLE_VALUE);
HANDLE handle = CreateFileA (filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
std::wstring wname = boost::locale::conv::utf_to_utf<wchar_t>(filename);
HANDLE handle = CreateFileW (wname.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if (handle == NULL)
if (handle == INVALID_HANDLE_VALUE)
{
std::ostringstream os;
os << "Failed to open '" << filename << "' for reading.";

@ -60,10 +60,10 @@ namespace Files
{
boost::filesystem::path path = *dirIter;
if (!equal (extension, boost::filesystem::path (path.extension()).string()))
if (!equal (extension, path.extension().string()))
continue;
std::string filename = boost::filesystem::path (path.filename()).string();
std::string filename = path.filename().string();
TIter result = mFiles.find (filename);

@ -10,8 +10,12 @@
#pragma comment(lib, "Shlwapi.lib")
#include <boost/locale.hpp>
namespace bconv = boost::locale::conv;
/**
* FIXME: Someone with Windows system should check this and correct if necessary
* FIXME: MAX_PATH is irrelevant for extended-length paths, i.e. \\?\...
*/
/**
@ -23,22 +27,29 @@ namespace Files
WindowsPath::WindowsPath(const std::string& application_name)
: mName(application_name)
{
/* Since on Windows boost::path.string() returns string of narrow
characters in local encoding, it is required to path::imbue()
with UTF-8 encoding (generated for empty name from boost::locale)
to handle Unicode in platform-agnostic way using std::string.
See boost::filesystem and boost::locale reference for details.
*/
boost::filesystem::path::imbue(boost::locale::generator().generate(""));
}
boost::filesystem::path WindowsPath::getUserConfigPath() const
{
boost::filesystem::path userPath(".");
TCHAR path[MAX_PATH];
WCHAR path[MAX_PATH + 1];
memset(path, 0, sizeof(path));
if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, path)))
if(SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, path)))
{
PathAppend(path, TEXT("My Games"));
userPath = boost::filesystem::path(path);
userPath = boost::filesystem::path(bconv::utf_to_utf<char>(path));
}
return userPath / mName;
return userPath / "My Games" / mName;
}
boost::filesystem::path WindowsPath::getUserDataPath() const
@ -51,12 +62,12 @@ boost::filesystem::path WindowsPath::getGlobalConfigPath() const
{
boost::filesystem::path globalPath(".");
TCHAR path[MAX_PATH];
WCHAR path[MAX_PATH + 1];
memset(path, 0, sizeof(path));
if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES | CSIDL_FLAG_CREATE, NULL, 0, path)))
if(SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROGRAM_FILES | CSIDL_FLAG_CREATE, NULL, 0, path)))
{
globalPath = boost::filesystem::path(path);
globalPath = boost::filesystem::path(bconv::utf_to_utf<char>(path));
}
return globalPath / mName;

@ -1,11 +1,15 @@
#include "ogreinit.hpp"
#include <string>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <OgreRoot.h>
#include <OgreParticleEmitterFactory.h>
#include <OgreParticleSystemManager.h>
#include <OgreLogManager.h>
#include <OgreLog.h>
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#include <OSX/macUtils.h>
@ -13,8 +17,54 @@
#include <components/nifogre/particles.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/fstream.hpp>
#include "ogreplugin.hpp"
namespace bfs = boost::filesystem;
namespace
{
/** \brief Custom Ogre::LogListener interface implementation being
able to portably handle UTF-8 encoded path.
Effectively this is used in conjunction with default listener,
but since on every message messageLogged() set 'skip' flag to
true, there should be no troubles sharing same file.
*/
class LogListener : public Ogre::LogListener
{
bfs::ofstream file;
char buffer[16];
public:
LogListener(const std::string &path)
: file((bfs::path(path)))
{
memset(buffer, sizeof(buffer), 0);
}
void timestamp()
{
int local = time(0) % 86400;
int sec = local % 60;
int min = (local / 60) % 60;
int hrs = local / 3600;
sprintf(buffer, "%02d:%02d:%02d: ", hrs, min, sec);
}
virtual void messageLogged(const std::string &msg, Ogre::LogMessageLevel lvl, bool mask, const std::string &logName, bool &skip)
{
timestamp();
file << buffer << msg << std::endl;
skip = true;
}
};
}
namespace OgreInit
{
@ -43,6 +93,11 @@ namespace OgreInit
new Ogre::LogManager;
Ogre::Log *log = Ogre::LogManager::getSingleton().createLog(logPath);
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
// Use custom listener only on Windows
log->addListener(new LogListener(logPath));
#endif
// Disable logging to cout/cerr
log->setDebugOutputEnabled(false);
@ -141,11 +196,6 @@ namespace OgreInit
pluginDir = OGRE_PLUGIN_DIR_REL;
#endif
}
boost::filesystem::path absPluginPath = boost::filesystem::absolute(boost::filesystem::path(pluginDir));
pluginDir = absPluginPath.string();
Files::loadOgrePlugin(pluginDir, "RenderSystem_GL", *mRoot);
Files::loadOgrePlugin(pluginDir, "RenderSystem_GLES2", *mRoot);
Files::loadOgrePlugin(pluginDir, "RenderSystem_GL3Plus", *mRoot);

@ -1,13 +1,19 @@
#include "settings.hpp"
#include <fstream>
#include <stdexcept>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/fstream.hpp>
#include <OgreResourceGroupManager.h>
#include <OgreStringConverter.h>
#include <OgreDataStream.h>
#include <components/files/constrainedfiledatastream.hpp>
using namespace Settings;
namespace bfs = boost::filesystem;
Ogre::ConfigFile Manager::mFile = Ogre::ConfigFile();
Ogre::ConfigFile Manager::mDefaultFile = Ogre::ConfigFile();
CategorySettingVector Manager::mChangedSettings = CategorySettingVector();
@ -15,17 +21,19 @@ CategorySettingValueMap Manager::mNewSettings = CategorySettingValueMap();
void Manager::loadUser (const std::string& file)
{
mFile.load(file);
Ogre::DataStreamPtr stream = openConstrainedFileDataStream(file.c_str());
mFile.load(stream);
}
void Manager::loadDefault (const std::string& file)
{
mDefaultFile.load(file);
Ogre::DataStreamPtr stream = openConstrainedFileDataStream(file.c_str());
mDefaultFile.load(stream);
}
void Manager::saveUser(const std::string& file)
{
std::fstream fout(file.c_str(), std::ios::out);
bfs::ofstream fout((bfs::path(file)));
Ogre::ConfigFile::SectionIterator seci = mFile.getSectionIterator();

@ -1,7 +1,8 @@
#include "translation.hpp"
#include <components/misc/stringops.hpp>
#include <fstream>
#include <boost/filesystem/fstream.hpp>
#include <components/misc/stringops.hpp>
namespace Translation
{
@ -28,9 +29,8 @@ namespace Translation
if (dataFileCollections.getCollection (extension).doesExist (fileName))
{
std::string path = dataFileCollections.getCollection (extension).getPath (fileName).string();
std::ifstream stream (path.c_str());
boost::filesystem::ifstream stream (
dataFileCollections.getCollection (extension).getPath (fileName));
if (!stream.is_open())
throw std::runtime_error ("failed to open translation file: " + fileName);

@ -31,18 +31,34 @@ distribution.
#include "tinyxml.h"
#ifdef _WIN32
#include <Windows.h> // import MultiByteToWideChar
#endif
bool TiXmlBase::condenseWhiteSpace = true;
// Microsoft compiler security
FILE* TiXmlFOpen( const char* filename, const char* mode )
{
#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
#if defined(_WIN32)
FILE* fp = 0;
errno_t err = fopen_s( &fp, filename, mode );
if ( !err && fp )
return fp;
return 0;
size_t len = strlen(filename);
wchar_t *wname = new wchar_t[len + 1];
memset(wname, 0, sizeof(*wname) * (len + 1));
wchar_t wmode[32] = { 0 };
MultiByteToWideChar(CP_UTF8, 0, filename, len, wname, len);
MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, sizeof(wmode) / sizeof(*wmode));
#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
errno_t err = _wfopen_s( &fp, wname, wmode );
#else
fp = _wfopen(wname, wmode);
#endif
delete[] wname;
return fp;
#else
return fopen( filename, mode );
#endif

@ -4,6 +4,59 @@
#include <boost/wave/cpplexer/cpp_lex_token.hpp>
#include <boost/wave/cpplexer/cpp_lex_iterator.hpp>
#include <boost/filesystem/fstream.hpp>
/*
Almost exact copy of load_file_to_string policy found in
boost::wave headers with the only change that it uses
boost::filesystem facility to handle UTF-8 paths used
throughout OpenMW (bfs::fstream, bfs::path).
Original namespace is used due to required bost::wave
internal symbols.
*/
namespace boost {
namespace wave {
namespace iteration_context_policies {
struct load_utf8_path_to_string
{
template <typename IterContextT>
class inner
{
public:
template <typename PositionT>
static void init_iterators(IterContextT &iter_ctx,
PositionT const &act_pos, language_support language)
{
typedef typename IterContextT::iterator_type iterator_type;
namespace bfs = boost::filesystem;
// read in the file
bfs::ifstream instream(bfs::path(iter_ctx.filename.c_str()));
if (!instream.is_open()) {
BOOST_WAVE_THROW_CTX(iter_ctx.ctx, preprocess_exception,
bad_include_file, iter_ctx.filename.c_str(), act_pos);
return;
}
instream.unsetf(std::ios::skipws);
iter_ctx.instring.assign(
std::istreambuf_iterator<char>(instream.rdbuf()),
std::istreambuf_iterator<char>());
iter_ctx.first = iterator_type(
iter_ctx.instring.begin(), iter_ctx.instring.end(),
PositionT(iter_ctx.filename), language);
iter_ctx.last = iterator_type();
}
private:
std::string instring;
};
};
} } }
namespace sh
{
std::string Preprocessor::preprocess (std::string source, const std::string& includePath, std::vector<std::string> definitions, const std::string& name)
@ -29,7 +82,7 @@ namespace sh
// match the iterator type used during construction of the context
// instance (see below). It is the type of the underlying input stream.
typedef boost::wave::context<std::string::iterator, lex_iterator_type
, boost::wave::iteration_context_policies::load_file_to_string,
, boost::wave::iteration_context_policies::load_utf8_path_to_string,
emit_custom_line_directives_hooks>
context_type;

@ -0,0 +1,39 @@
#include "loglistener.hpp"
#include <iomanip>
#include <time.h>
#include <boost/filesystem/path.hpp>
namespace MyGUI
{
void CustomLogListener::open()
{
mStream.open(boost::filesystem::path(mFileName), std::ios_base::out);
}
void CustomLogListener::close()
{
if (mStream.is_open())
mStream.close();
}
void CustomLogListener::flush()
{
if (mStream.is_open())
mStream.flush();
}
void CustomLogListener::log(const std::string& _section, LogLevel _level, const struct tm* _time, const std::string& _message, const char* _file, int _line)
{
if (mStream.is_open())
{
const char* separator = " | ";
mStream << std::setw(2) << std::setfill('0') << _time->tm_hour << ":"
<< std::setw(2) << std::setfill('0') << _time->tm_min << ":"
<< std::setw(2) << std::setfill('0') << _time->tm_sec << separator
<< _section << separator << _level.print() << separator
<< _message << separator << _file << separator << _line << std::endl;
}
}
}

@ -0,0 +1,37 @@
#ifndef OPENENGINE_MYGUI_LOGLISTENER_H
#define OPENENGINE_MYGUI_LOGLISTENER_H
#include <string>
#include <boost/filesystem/fstream.hpp>
#include <MyGUI_ILogListener.h>
namespace MyGUI
{
/// \brief Custom MyGUI::ILogListener interface implementation
/// being able to portably handle UTF-8 encoded path.
class CustomLogListener : public ILogListener
{
public:
CustomLogListener(const std::string &name)
: mFileName(name)
{}
~CustomLogListener() {}
virtual void open();
virtual void close();
virtual void flush();
virtual void log(const std::string& _section, LogLevel _level, const struct tm* _time, const std::string& _message, const char* _file, int _line);
const std::string& getFileName() const { return mFileName; }
private:
boost::filesystem::ofstream mStream;
std::string mFileName;
};
}
#endif

@ -1,9 +1,14 @@
#include "manager.hpp"
#include "loglistener.hpp"
#include <MyGUI_Gui.h>
#include <MyGUI_OgrePlatform.h>
#include <MyGUI_Timer.h>
#include <MyGUI_LevelLogFilter.h>
#include <MyGUI_LogSource.h>
#include <MyGUI_ConsoleLogListener.h>
#include <cassert>
#include <extern/shiny/Main/Factory.hpp>
@ -554,8 +559,34 @@ public:
}
};
}
/// \brief Helper class holding data that required during
/// MyGUI log creation
class LogFacility
{
ConsoleLogListener mConsole;
CustomLogListener mFile;
LevelLogFilter mFilter;
LogSource mSource;
public:
LogFacility(const std::string &output, bool console)
: mFile(output)
{
mConsole.setEnabled(console);
mFilter.setLoggingLevel(LogLevel::Info);
mSource.addLogListener(&mFile);
mSource.addLogListener(&mConsole);
mSource.setLogFilter(&mFilter);
mSource.open();
}
LogSource *getSource() { return &mSource; }
};
}
void MyGUIManager::setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool logging, const std::string& logDir)
{
@ -586,10 +617,10 @@ void MyGUIManager::setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool
mRenderManager = new MyGUI::OgreRenderManager();
mDataManager = new MyGUI::FixedOgreDataManager();
LogManager::getInstance().setSTDOutputEnabled(logging);
if (!theLogFile.empty())
LogManager::getInstance().createDefaultSource(theLogFile);
// Do not use default log since it don't support Unicode path on Windows.
// Instead, manually create log source using LogFacility and pass it.
mLogFacility = new MyGUI::LogFacility(theLogFile, logging);
LogManager::getInstance().addLogSource(mLogFacility->getSource());
if (mShaderRenderManager)
mShaderRenderManager->initialise(wnd, mgr);
@ -648,5 +679,7 @@ void MyGUIManager::shutdown()
delete mLogManager;
mLogManager = NULL;
}
delete mLogFacility;
mGui = NULL;
}

@ -10,6 +10,7 @@ namespace MyGUI
class OgreDataManager;
class OgreRenderManager;
class ShaderBasedRenderManager;
class LogFacility;
}
namespace Ogre
@ -25,6 +26,7 @@ namespace GUI
{
MyGUI::Gui *mGui;
MyGUI::LogManager* mLogManager;
MyGUI::LogFacility* mLogFacility;
MyGUI::OgreDataManager* mDataManager;
MyGUI::OgreRenderManager* mRenderManager;
MyGUI::ShaderBasedRenderManager* mShaderRenderManager;

@ -15,6 +15,9 @@
#include <components/ogreinit/ogreinit.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/fstream.hpp>
#include <cassert>
#include <stdexcept>
@ -48,7 +51,41 @@ void OgreRenderer::update(float dt)
void OgreRenderer::screenshot(const std::string &file)
{
mWindow->writeContentsToFile(file);
/* Since Ogre uses narrow character interfaces, it does not support
Unicode paths on Windows. Therefore we had to implement screenshot
saving manually.
*/
namespace bfs = boost::filesystem;
bfs::ofstream out(bfs::path(file), std::ios::binary);
Ogre::Image image;
Ogre::PixelFormat pf = mWindow->suggestPixelFormat();
int w = mWindow->getWidth();
int h = mWindow->getHeight();
image.loadDynamicImage(
OGRE_ALLOC_T(Ogre::uchar, w * h * Ogre::PixelUtil::getNumElemBytes(pf), Ogre::MEMCATEGORY_GENERAL),
w, h, 1, pf, true
);
mWindow->copyContentsToMemory(image.getPixelBox());
Ogre::DataStreamPtr stream = image.encode("png");
Ogre::MemoryDataStream *mem = dynamic_cast<Ogre::MemoryDataStream *>(stream.get());
if (mem != 0) { // likely
const char *ptr = reinterpret_cast<char *>(mem->getCurrentPtr());
out.write(ptr, mem->size());
}
else {
char buf[4096];
size_t size = stream->size();
while (size > 0) {
size_t chunk = (size > sizeof(buf)) ? sizeof(buf) : size;
stream->read(buf, chunk);
out.write(buf, chunk);
size -= chunk;
}
}
}
float OgreRenderer::getFPS()

Loading…
Cancel
Save