mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 16:15:31 +00:00
Merge remote-tracking branch 'greye/widechar'
This commit is contained in:
commit
244eb11651
30 changed files with 444 additions and 82 deletions
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
24
extern/oics/tinyxml.cpp
vendored
24
extern/oics/tinyxml.cpp
vendored
|
@ -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 )
|
||||
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;
|
||||
return 0;
|
||||
#else
|
||||
return fopen( filename, mode );
|
||||
#endif
|
||||
|
|
55
extern/shiny/Main/Preprocessor.cpp
vendored
55
extern/shiny/Main/Preprocessor.cpp
vendored
|
@ -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;
|
||||
|
||||
|
|
39
libs/openengine/gui/loglistener.cpp
Normal file
39
libs/openengine/gui/loglistener.cpp
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
37
libs/openengine/gui/loglistener.hpp
Normal file
37
libs/openengine/gui/loglistener.hpp
Normal file
|
@ -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…
Reference in a new issue