forked from teamnwah/openmw-tes3coop
Merge branch 'config'
This commit is contained in:
commit
b2b09320fc
32 changed files with 1010 additions and 820 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -7,3 +7,7 @@ Docs/mainpage.hpp
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
*/CMakeFiles
|
*/CMakeFiles
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
|
moc_*.cxx
|
||||||
|
cmake_install.cmake
|
||||||
|
*.[ao]
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@ include (OpenMWMacros)
|
||||||
# Version
|
# Version
|
||||||
|
|
||||||
set (OPENMW_VERSION_MAJOR 0)
|
set (OPENMW_VERSION_MAJOR 0)
|
||||||
set (OPENMW_VERSION_MINOR 11)
|
set (OPENMW_VERSION_MINOR 12)
|
||||||
set (OPENMW_VERSION_RELEASE 1)
|
set (OPENMW_VERSION_RELEASE 0)
|
||||||
|
|
||||||
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
|
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
|
||||||
|
|
||||||
|
@ -423,9 +423,6 @@ endif()
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set(INSTALL_SUBDIR OpenMW)
|
set(INSTALL_SUBDIR OpenMW)
|
||||||
|
|
||||||
#install(FILES ${MISC_FILES} DESTINATION ../MacOS)
|
|
||||||
#install(DIRECTORY "${APP_BUNDLE_DIR}/Contents/Plugins" DESTINATION ..)
|
|
||||||
#install(DIRECTORY "${APP_BUNDLE_DIR}/Contents/Resources/resources" DESTINATION ../Resources)
|
|
||||||
install(DIRECTORY "${APP_BUNDLE_DIR}" USE_SOURCE_PERMISSIONS DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(DIRECTORY "${APP_BUNDLE_DIR}" USE_SOURCE_PERMISSIONS DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
install(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
|
@ -433,9 +430,6 @@ if (APPLE)
|
||||||
install(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
install(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
set(CPACK_GENERATOR "DragNDrop")
|
set(CPACK_GENERATOR "DragNDrop")
|
||||||
# set(CPACK_BUNDLE_PLIST "${CMAKE_SOURCE_DIR}/files/mac/Info.plist")
|
|
||||||
# set(CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/files/mac/openmw.icns")
|
|
||||||
# set(CPACK_BUNDLE_NAME "OpenMW")
|
|
||||||
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
|
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
|
set(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO})
|
set(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO})
|
||||||
|
@ -445,11 +439,13 @@ if (APPLE)
|
||||||
set(PLUGINS "")
|
set(PLUGINS "")
|
||||||
|
|
||||||
# Scan Plugins dir for *.dylibs
|
# Scan Plugins dir for *.dylibs
|
||||||
file(GLOB ALL_PLUGINS "${APP_BUNDLE_DIR}/Contents/Plugins/*.dylib")
|
set(PLUGIN_SEARCH_ROOT "${APP_BUNDLE_DIR}/Contents/Plugins")
|
||||||
|
file(GLOB_RECURSE ALL_PLUGINS "${PLUGIN_SEARCH_ROOT}/*.dylib")
|
||||||
|
|
||||||
|
set(PLUGIN_INSTALL_BASE "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}/Contents/Plugins")
|
||||||
foreach(PLUGIN ${ALL_PLUGINS})
|
foreach(PLUGIN ${ALL_PLUGINS})
|
||||||
get_filename_component(PLUGIN_FILENAME ${PLUGIN} NAME)
|
string(REPLACE "${PLUGIN_SEARCH_ROOT}/" "" PLUGIN_RELATIVE "${PLUGIN}")
|
||||||
set(PLUGINS ${PLUGINS} "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}/Contents/Plugins/${PLUGIN_FILENAME}")
|
set(PLUGINS ${PLUGINS} "${PLUGIN_INSTALL_BASE}/${PLUGIN_RELATIVE}")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
#For now, search unresolved dependencies only in default system paths, so if you put unresolveable (i.e. with @executable_path in id name) lib or framework somewhere else, it would fail
|
#For now, search unresolved dependencies only in default system paths, so if you put unresolveable (i.e. with @executable_path in id name) lib or framework somewhere else, it would fail
|
||||||
|
|
|
@ -41,8 +41,10 @@ source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER} ${LAUNCHER_HEADER_MOC
|
||||||
find_package(Qt4 REQUIRED)
|
find_package(Qt4 REQUIRED)
|
||||||
set(QT_USE_QTGUI 1)
|
set(QT_USE_QTGUI 1)
|
||||||
|
|
||||||
#find_package(PNG REQUIRED)
|
if (NOT APPLE) # this dependency can be completely removed, but now it only tested on OS X
|
||||||
#include_directories(${PNG_INCLUDE_DIR})
|
find_package(PNG REQUIRED)
|
||||||
|
include_directories(${PNG_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
QT4_ADD_RESOURCES(RCC_SRCS resources.qrc)
|
QT4_ADD_RESOURCES(RCC_SRCS resources.qrc)
|
||||||
QT4_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC})
|
QT4_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC})
|
||||||
|
@ -51,14 +53,14 @@ include(${QT_USE_FILE})
|
||||||
|
|
||||||
# list here plugins that can't be detected statically, but loaded in runtime
|
# list here plugins that can't be detected statically, but loaded in runtime
|
||||||
# it needed for packaging automatisation
|
# it needed for packaging automatisation
|
||||||
#set(USED_QT_PLUGINS imageformats/libqgif
|
set(USED_QT_PLUGINS imageformats/libqgif
|
||||||
# imageformats/libqico
|
imageformats/libqico
|
||||||
# imageformats/libqjpeg
|
imageformats/libqjpeg
|
||||||
# imageformats/libqmng
|
imageformats/libqmng
|
||||||
# imageformats/libqsvg
|
imageformats/libqsvg
|
||||||
# imageformats/libqtga
|
imageformats/libqtga
|
||||||
# imageformats/libqtiff)
|
imageformats/libqtiff)
|
||||||
# It seems that launcher works without this plugins, but it loads them into memory if they exists
|
# It seems that launcher works without this plugins, but it loads them if they exists
|
||||||
|
|
||||||
# Main executable
|
# Main executable
|
||||||
add_executable(omwlauncher
|
add_executable(omwlauncher
|
||||||
|
@ -71,7 +73,7 @@ target_link_libraries(omwlauncher
|
||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
${OGRE_LIBRARIES}
|
${OGRE_LIBRARIES}
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
# ${PNG_LIBRARY}
|
${PNG_LIBRARY}
|
||||||
components
|
components
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -86,10 +88,10 @@ if (APPLE)
|
||||||
"${APP_BUNDLE_DIR}/../launcher.cfg")
|
"${APP_BUNDLE_DIR}/../launcher.cfg")
|
||||||
|
|
||||||
# copy used QT plugins into ${APP_BUNDLE_DIR}/Contents/Plugins
|
# copy used QT plugins into ${APP_BUNDLE_DIR}/Contents/Plugins
|
||||||
#foreach(PLUGIN ${USED_QT_PLUGINS})
|
foreach(PLUGIN ${USED_QT_PLUGINS})
|
||||||
# get_filename_component(PLUGIN_FILENAME ${PLUGIN} NAME)
|
get_filename_component(PLUGIN_FILENAME ${PLUGIN} NAME)
|
||||||
# configure_file("${QT_PLUGINS_DIR}/${PLUGIN}.dylib" "${APP_BUNDLE_DIR}/Contents/Plugins/${PLUGIN_FILENAME}.dylib" COPYONLY)
|
configure_file("${QT_PLUGINS_DIR}/${PLUGIN}.dylib" "${APP_BUNDLE_DIR}/Contents/Plugins/${PLUGIN}.dylib" COPYONLY)
|
||||||
#endforeach()
|
endforeach()
|
||||||
|
|
||||||
else()
|
else()
|
||||||
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
|
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include <components/esm/esm_reader.hpp>
|
#include <components/esm/esm_reader.hpp>
|
||||||
#include <components/files/collections.hpp>
|
#include <components/files/collections.hpp>
|
||||||
#include <components/files/multidircollection.hpp>
|
#include <components/files/multidircollection.hpp>
|
||||||
#include <components/cfg/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
#include "datafilespage.hpp"
|
#include "datafilespage.hpp"
|
||||||
#include "lineedit.hpp"
|
#include "lineedit.hpp"
|
||||||
|
@ -26,7 +26,9 @@ bool rowSmallerThan(const QModelIndex &index1, const QModelIndex &index2)
|
||||||
return index1.row() <= index2.row();
|
return index1.row() <= index2.row();
|
||||||
}
|
}
|
||||||
|
|
||||||
DataFilesPage::DataFilesPage(QWidget *parent) : QWidget(parent)
|
DataFilesPage::DataFilesPage(Files::ConfigurationManager& cfg, QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, mCfgMgr(cfg)
|
||||||
{
|
{
|
||||||
mDataFilesModel = new QStandardItemModel(); // Contains all plugins with masters
|
mDataFilesModel = new QStandardItemModel(); // Contains all plugins with masters
|
||||||
mPluginsModel = new PluginsModel(); // Contains selectable plugins
|
mPluginsModel = new PluginsModel(); // Contains selectable plugins
|
||||||
|
@ -133,6 +135,8 @@ void DataFilesPage::setupDataFiles(const QStringList &paths, bool strict)
|
||||||
dataDirs.push_back(boost::filesystem::path(currentPath.toStdString()));
|
dataDirs.push_back(boost::filesystem::path(currentPath.toStdString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mCfgMgr.processPaths(dataDirs);
|
||||||
|
|
||||||
// Create a file collection for the dataDirs
|
// Create a file collection for the dataDirs
|
||||||
Files::Collections mFileCollections(dataDirs, strict);
|
Files::Collections mFileCollections(dataDirs, strict);
|
||||||
|
|
||||||
|
@ -236,13 +240,11 @@ void DataFilesPage::setupDataFiles(const QStringList &paths, bool strict)
|
||||||
|
|
||||||
void DataFilesPage::setupConfig()
|
void DataFilesPage::setupConfig()
|
||||||
{
|
{
|
||||||
Cfg::ConfigurationManager cfg;
|
QString config = (mCfgMgr.getLocalPath() / "launcher.cfg").string().c_str();
|
||||||
|
|
||||||
QString config = (cfg.getRuntimeConfigPath() / "launcher.cfg").string().c_str();
|
|
||||||
QFile file(config);
|
QFile file(config);
|
||||||
|
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
config = QString::fromStdString((cfg.getLocalConfigPath() / "launcher.cfg").string());
|
config = QString::fromStdString((mCfgMgr.getUserPath() / "launcher.cfg").string());
|
||||||
}
|
}
|
||||||
|
|
||||||
file.setFileName(config); // Just for displaying information
|
file.setFileName(config); // Just for displaying information
|
||||||
|
|
|
@ -19,12 +19,14 @@ class PluginsModel;
|
||||||
class PluginsView;
|
class PluginsView;
|
||||||
class ComboBox;
|
class ComboBox;
|
||||||
|
|
||||||
|
namespace Files { struct ConfigurationManager; }
|
||||||
|
|
||||||
class DataFilesPage : public QWidget
|
class DataFilesPage : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DataFilesPage(QWidget *parent = 0);
|
DataFilesPage(Files::ConfigurationManager& cfg, QWidget *parent = 0);
|
||||||
|
|
||||||
ComboBox *mProfilesComboBox;
|
ComboBox *mProfilesComboBox;
|
||||||
QSettings *mLauncherConfig;
|
QSettings *mLauncherConfig;
|
||||||
|
@ -81,6 +83,8 @@ private:
|
||||||
QAction *mCheckAction;
|
QAction *mCheckAction;
|
||||||
QAction *mUncheckAction;
|
QAction *mUncheckAction;
|
||||||
|
|
||||||
|
Files::ConfigurationManager& mCfgMgr;
|
||||||
|
|
||||||
void addPlugins(const QModelIndex &index);
|
void addPlugins(const QModelIndex &index);
|
||||||
void removePlugins(const QModelIndex &index);
|
void removePlugins(const QModelIndex &index);
|
||||||
void uncheckPlugins();
|
void uncheckPlugins();
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
|
|
||||||
#include "graphicspage.hpp"
|
#include "graphicspage.hpp"
|
||||||
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
GraphicsPage::GraphicsPage(QWidget *parent) : QWidget(parent)
|
GraphicsPage::GraphicsPage(Files::ConfigurationManager& cfg, QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, mCfgMgr(cfg)
|
||||||
{
|
{
|
||||||
QGroupBox *rendererGroup = new QGroupBox(tr("Renderer"), this);
|
QGroupBox *rendererGroup = new QGroupBox(tr("Renderer"), this);
|
||||||
|
|
||||||
|
@ -147,21 +150,21 @@ void GraphicsPage::createPages()
|
||||||
|
|
||||||
void GraphicsPage::setupConfig()
|
void GraphicsPage::setupConfig()
|
||||||
{
|
{
|
||||||
QString ogreCfg = mCfg.getOgreConfigPath().string().c_str();
|
QString ogreCfg = mCfgMgr.getOgreConfigPath().string().c_str();
|
||||||
QFile file(ogreCfg);
|
QFile file(ogreCfg);
|
||||||
mOgreConfig = new QSettings(ogreCfg, QSettings::IniFormat);
|
mOgreConfig = new QSettings(ogreCfg, QSettings::IniFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsPage::setupOgre()
|
void GraphicsPage::setupOgre()
|
||||||
{
|
{
|
||||||
QString pluginCfg = mCfg.getPluginsConfigPath().string().c_str();
|
QString pluginCfg = mCfgMgr.getPluginsConfigPath().string().c_str();
|
||||||
QFile file(pluginCfg);
|
QFile file(pluginCfg);
|
||||||
|
|
||||||
// Create a log manager so we can surpress debug text to stdout/stderr
|
// Create a log manager so we can surpress debug text to stdout/stderr
|
||||||
Ogre::LogManager* logMgr = OGRE_NEW Ogre::LogManager;
|
Ogre::LogManager* logMgr = OGRE_NEW Ogre::LogManager;
|
||||||
logMgr->createLog((mCfg.getLogPath().string() + "/launcherOgre.log"), true, false, false);
|
logMgr->createLog((mCfgMgr.getLogPath().string() + "/launcherOgre.log"), true, false, false);
|
||||||
|
|
||||||
QString ogreCfg = QString::fromStdString(mCfg.getOgreConfigPath().string());
|
QString ogreCfg = QString::fromStdString(mCfgMgr.getOgreConfigPath().string());
|
||||||
file.setFileName(ogreCfg);
|
file.setFileName(ogreCfg);
|
||||||
|
|
||||||
//we need to check that the path to the configuration file exists before we
|
//we need to check that the path to the configuration file exists before we
|
||||||
|
|
|
@ -7,19 +7,20 @@
|
||||||
#include <OgreRenderSystem.h>
|
#include <OgreRenderSystem.h>
|
||||||
#include <OgreConfigFile.h>
|
#include <OgreConfigFile.h>
|
||||||
#include <OgreConfigDialog.h>
|
#include <OgreConfigDialog.h>
|
||||||
#include <components/cfg/configurationmanager.hpp>
|
|
||||||
|
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
class QStackedWidget;
|
class QStackedWidget;
|
||||||
class QSettings;
|
class QSettings;
|
||||||
|
|
||||||
|
namespace Files { struct ConfigurationManager; }
|
||||||
|
|
||||||
class GraphicsPage : public QWidget
|
class GraphicsPage : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GraphicsPage(QWidget *parent = 0);
|
GraphicsPage(Files::ConfigurationManager& cfg, QWidget *parent = 0);
|
||||||
|
|
||||||
QSettings *mOgreConfig;
|
QSettings *mOgreConfig;
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ public slots:
|
||||||
void rendererChanged(const QString &renderer);
|
void rendererChanged(const QString &renderer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Cfg::ConfigurationManager mCfg;
|
Files::ConfigurationManager& mCfgMgr;
|
||||||
Ogre::Root *mOgre;
|
Ogre::Root *mOgre;
|
||||||
Ogre::RenderSystem *mSelectedRenderSystem;
|
Ogre::RenderSystem *mSelectedRenderSystem;
|
||||||
Ogre::RenderSystem *mOpenGLRenderSystem;
|
Ogre::RenderSystem *mOpenGLRenderSystem;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
#include "maindialog.hpp"
|
#include "maindialog.hpp"
|
||||||
|
|
||||||
|
@ -17,6 +18,15 @@ int main(int argc, char *argv[])
|
||||||
dir.cdUp();
|
dir.cdUp();
|
||||||
dir.cdUp();
|
dir.cdUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// force Qt to load only LOCAL plugins, don't touch system Qt installation
|
||||||
|
QDir pluginsPath(QCoreApplication::applicationDirPath());
|
||||||
|
pluginsPath.cdUp();
|
||||||
|
pluginsPath.cd("Plugins");
|
||||||
|
|
||||||
|
QStringList libraryPaths;
|
||||||
|
libraryPaths << pluginsPath.path() << QCoreApplication::applicationDirPath();
|
||||||
|
app.setLibraryPaths(libraryPaths);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QDir::setCurrent(dir.absolutePath());
|
QDir::setCurrent(dir.absolutePath());
|
||||||
|
|
|
@ -152,20 +152,14 @@ QStringList MainDialog::readConfig(const QString &fileName)
|
||||||
void MainDialog::createPages()
|
void MainDialog::createPages()
|
||||||
{
|
{
|
||||||
mPlayPage = new PlayPage(this);
|
mPlayPage = new PlayPage(this);
|
||||||
mGraphicsPage = new GraphicsPage(this);
|
mGraphicsPage = new GraphicsPage(mCfgMgr, this);
|
||||||
mDataFilesPage = new DataFilesPage(this);
|
mDataFilesPage = new DataFilesPage(mCfgMgr, this);
|
||||||
|
|
||||||
// Retrieve all data entries from the configs
|
// Retrieve all data entries from the configs
|
||||||
QStringList dataDirs;
|
QStringList dataDirs;
|
||||||
|
|
||||||
// Global location
|
// Global location
|
||||||
QFile file(QString::fromStdString((mCfg.getGlobalConfigPath()/"openmw.cfg").string()));
|
QFile file(QString::fromStdString((mCfgMgr.getGlobalPath()/"openmw.cfg").string()));
|
||||||
if (file.exists()) {
|
|
||||||
dataDirs = readConfig(file.fileName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// User location
|
|
||||||
file.setFileName(QString::fromStdString((mCfg.getLocalConfigPath()/"openmw.cfg").string()));
|
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
dataDirs = readConfig(file.fileName());
|
dataDirs = readConfig(file.fileName());
|
||||||
}
|
}
|
||||||
|
@ -177,6 +171,12 @@ void MainDialog::createPages()
|
||||||
dataDirs = readConfig(file.fileName());
|
dataDirs = readConfig(file.fileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// User location
|
||||||
|
file.setFileName(QString::fromStdString((mCfgMgr.getUserPath()/"openmw.cfg").string()));
|
||||||
|
if (file.exists()) {
|
||||||
|
dataDirs = readConfig(file.fileName());
|
||||||
|
}
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
if (!dataDirs.isEmpty()) {
|
if (!dataDirs.isEmpty()) {
|
||||||
|
@ -328,7 +328,7 @@ void MainDialog::writeConfig()
|
||||||
dataFiles.append(mDataFilesPage->checkedPlugins());
|
dataFiles.append(mDataFilesPage->checkedPlugins());
|
||||||
|
|
||||||
// Open the config as a QFile
|
// Open the config as a QFile
|
||||||
QFile file(QString::fromStdString((mCfg.getLocalConfigPath()/"openmw.cfg").string()));
|
QFile file(QString::fromStdString((mCfgMgr.getUserPath()/"openmw.cfg").string()));
|
||||||
|
|
||||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
||||||
// File cannot be opened or created
|
// File cannot be opened or created
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
#include <components/cfg/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
class QListWidget;
|
class QListWidget;
|
||||||
class QListWidgetItem;
|
class QListWidgetItem;
|
||||||
|
@ -47,7 +47,7 @@ private:
|
||||||
QStringList mDataDirs;
|
QStringList mDataDirs;
|
||||||
bool mStrict;
|
bool mStrict;
|
||||||
|
|
||||||
Cfg::ConfigurationManager mCfg;
|
Files::ConfigurationManager mCfgMgr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,7 +18,9 @@
|
||||||
#include <components/esm_store/cell_store.hpp>
|
#include <components/esm_store/cell_store.hpp>
|
||||||
#include <components/bsa/bsa_archive.hpp>
|
#include <components/bsa/bsa_archive.hpp>
|
||||||
#include <components/esm/esm_reader.hpp>
|
#include <components/esm/esm_reader.hpp>
|
||||||
#include <components/files/path.hpp>
|
#include <components/files/fixedpath.hpp>
|
||||||
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
#include <components/nifbullet/bullet_nif_loader.hpp>
|
#include <components/nifbullet/bullet_nif_loader.hpp>
|
||||||
#include <components/nifogre/ogre_nif_loader.hpp>
|
#include <components/nifogre/ogre_nif_loader.hpp>
|
||||||
|
|
||||||
|
@ -173,7 +175,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
OMW::Engine::Engine(Cfg::ConfigurationManager& configurationManager)
|
OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
||||||
: mOgre (0)
|
: mOgre (0)
|
||||||
, mPhysicEngine (0)
|
, mPhysicEngine (0)
|
||||||
, mFpsLevel(0)
|
, mFpsLevel(0)
|
||||||
|
@ -214,15 +216,16 @@ OMW::Engine::~Engine()
|
||||||
void OMW::Engine::loadBSA()
|
void OMW::Engine::loadBSA()
|
||||||
{
|
{
|
||||||
const Files::MultiDirCollection& bsa = mFileCollections.getCollection (".bsa");
|
const Files::MultiDirCollection& bsa = mFileCollections.getCollection (".bsa");
|
||||||
|
std::string dataDirectory;
|
||||||
for (Files::MultiDirCollection::TIter iter (bsa.begin()); iter!=bsa.end(); ++iter)
|
for (Files::MultiDirCollection::TIter iter(bsa.begin()); iter!=bsa.end(); ++iter)
|
||||||
{
|
{
|
||||||
std::cout << "Adding " << iter->second.string() << std::endl;
|
std::cout << "Adding " << iter->second.string() << std::endl;
|
||||||
Bsa::addBSA (iter->second.string());
|
Bsa::addBSA(iter->second.string());
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "Data dir " << mDataDir.string() << std::endl;
|
dataDirectory = iter->second.parent_path().string();
|
||||||
Bsa::addDir(mDataDir.string(), mFSStrict);
|
std::cout << "Data dir " << dataDirectory << std::endl;
|
||||||
|
Bsa::addDir(dataDirectory, mFSStrict);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add resources directory
|
// add resources directory
|
||||||
|
@ -245,7 +248,7 @@ void OMW::Engine::setDataDirs (const Files::PathContainer& dataDirs)
|
||||||
{
|
{
|
||||||
/// \todo remove mDataDir, once resources system can handle multiple directories
|
/// \todo remove mDataDir, once resources system can handle multiple directories
|
||||||
assert (!dataDirs.empty());
|
assert (!dataDirs.empty());
|
||||||
mDataDir = dataDirs.back();
|
mDataDirs = dataDirs;
|
||||||
mFileCollections = Files::Collections (dataDirs, !mFSStrict);
|
mFileCollections = Files::Collections (dataDirs, !mFSStrict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,7 +361,7 @@ void OMW::Engine::go()
|
||||||
mEnvironment.mSoundManager = new MWSound::SoundManager(mOgre->getRoot(),
|
mEnvironment.mSoundManager = new MWSound::SoundManager(mOgre->getRoot(),
|
||||||
mOgre->getCamera(),
|
mOgre->getCamera(),
|
||||||
mEnvironment.mWorld->getStore(),
|
mEnvironment.mWorld->getStore(),
|
||||||
(mDataDir),
|
mDataDirs,
|
||||||
mUseSound, mFSStrict, mEnvironment);
|
mUseSound, mFSStrict, mEnvironment);
|
||||||
|
|
||||||
// Create script system
|
// Create script system
|
||||||
|
@ -467,7 +470,7 @@ void OMW::Engine::screenshot()
|
||||||
// Count screenshots.
|
// Count screenshots.
|
||||||
int shotCount = 0;
|
int shotCount = 0;
|
||||||
|
|
||||||
const std::string screenshotPath = mCfgMgr.getLocalConfigPath().string();
|
const std::string screenshotPath = mCfgMgr.getUserPath().string();
|
||||||
|
|
||||||
// Find the first unused filename with a do-while
|
// Find the first unused filename with a do-while
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#include <components/compiler/extensions.hpp>
|
#include <components/compiler/extensions.hpp>
|
||||||
#include <components/files/collections.hpp>
|
#include <components/files/collections.hpp>
|
||||||
#include <components/cfg/configurationmanager.hpp>
|
|
||||||
|
|
||||||
#include "mwworld/environment.hpp"
|
#include "mwworld/environment.hpp"
|
||||||
#include "mwworld/ptr.hpp"
|
#include "mwworld/ptr.hpp"
|
||||||
|
@ -54,13 +53,18 @@ namespace OEngine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Files
|
||||||
|
{
|
||||||
|
struct ConfigurationManager;
|
||||||
|
}
|
||||||
|
|
||||||
namespace OMW
|
namespace OMW
|
||||||
{
|
{
|
||||||
/// \brief Main engine class, that brings together all the components of OpenMW
|
/// \brief Main engine class, that brings together all the components of OpenMW
|
||||||
class Engine : private Ogre::FrameListener
|
class Engine : private Ogre::FrameListener
|
||||||
{
|
{
|
||||||
std::string mEncoding;
|
std::string mEncoding;
|
||||||
boost::filesystem::path mDataDir;
|
Files::PathContainer mDataDirs;
|
||||||
boost::filesystem::path mResDir;
|
boost::filesystem::path mResDir;
|
||||||
OEngine::Render::OgreRenderer *mOgre;
|
OEngine::Render::OgreRenderer *mOgre;
|
||||||
OEngine::Physic::PhysicEngine* mPhysicEngine;
|
OEngine::Physic::PhysicEngine* mPhysicEngine;
|
||||||
|
@ -104,7 +108,7 @@ namespace OMW
|
||||||
virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt);
|
virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Engine(Cfg::ConfigurationManager& configurationManager);
|
Engine(Files::ConfigurationManager& configurationManager);
|
||||||
virtual ~Engine();
|
virtual ~Engine();
|
||||||
|
|
||||||
/// Enable strict filesystem mode (do not fold case)
|
/// Enable strict filesystem mode (do not fold case)
|
||||||
|
@ -164,7 +168,7 @@ namespace OMW
|
||||||
void setAnimationVerbose(bool animverbose);
|
void setAnimationVerbose(bool animverbose);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Cfg::ConfigurationManager& mCfgMgr;
|
Files::ConfigurationManager& mCfgMgr;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
#include <components/files/fileops.hpp>
|
#include <components/files/fileops.hpp>
|
||||||
#include <components/files/path.hpp>
|
#include <components/files/fixedpath.hpp>
|
||||||
#include <components/files/collections.hpp>
|
#include <components/files/collections.hpp>
|
||||||
#include <components/cfg/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
#include "engine.hpp"
|
#include "engine.hpp"
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ using namespace std;
|
||||||
* \retval true - Everything goes OK
|
* \retval true - Everything goes OK
|
||||||
* \retval false - Error
|
* \retval false - Error
|
||||||
*/
|
*/
|
||||||
bool parseOptions (int argc, char** argv, OMW::Engine& engine, Cfg::ConfigurationManager& cfgMgr)
|
bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::ConfigurationManager& cfgMgr)
|
||||||
{
|
{
|
||||||
// Create a local alias for brevity
|
// Create a local alias for brevity
|
||||||
namespace bpo = boost::program_options;
|
namespace bpo = boost::program_options;
|
||||||
|
@ -160,6 +160,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Cfg::Configuratio
|
||||||
engine.enableFSStrict(variables["fs-strict"].as<bool>());
|
engine.enableFSStrict(variables["fs-strict"].as<bool>());
|
||||||
|
|
||||||
Files::PathContainer dataDirs(variables["data"].as<Files::PathContainer>());
|
Files::PathContainer dataDirs(variables["data"].as<Files::PathContainer>());
|
||||||
|
cfgMgr.processPaths(dataDirs);
|
||||||
|
|
||||||
std::string local(variables["data-local"].as<std::string>());
|
std::string local(variables["data-local"].as<std::string>());
|
||||||
if (!local.empty())
|
if (!local.empty())
|
||||||
|
@ -169,7 +170,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Cfg::Configuratio
|
||||||
|
|
||||||
if (dataDirs.empty())
|
if (dataDirs.empty())
|
||||||
{
|
{
|
||||||
dataDirs.push_back(cfgMgr.getLocalDataPath());
|
dataDirs.push_back(cfgMgr.getLocalPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
engine.setDataDirs(dataDirs);
|
engine.setDataDirs(dataDirs);
|
||||||
|
@ -224,7 +225,7 @@ int main(int argc, char**argv)
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Cfg::ConfigurationManager cfgMgr;
|
Files::ConfigurationManager cfgMgr;
|
||||||
OMW::Engine engine(cfgMgr);
|
OMW::Engine engine(cfgMgr);
|
||||||
|
|
||||||
if (parseOptions(argc, argv, engine, cfgMgr))
|
if (parseOptions(argc, argv, engine, cfgMgr))
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
|
|
||||||
#include <openengine/sound/sndmanager.hpp>
|
#include <openengine/sound/sndmanager.hpp>
|
||||||
|
@ -15,6 +13,7 @@ using namespace std;
|
||||||
#include <components/file_finder/file_finder.hpp>
|
#include <components/file_finder/file_finder.hpp>
|
||||||
#include <components/esm_store/store.hpp>
|
#include <components/esm_store/store.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include "../mwworld/environment.hpp"
|
#include "../mwworld/environment.hpp"
|
||||||
#include "../mwworld/world.hpp"
|
#include "../mwworld/world.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
#include "../mwworld/player.hpp"
|
||||||
|
@ -90,24 +89,28 @@ namespace MWSound
|
||||||
// relative to the sound dir, and translates them into full paths
|
// relative to the sound dir, and translates them into full paths
|
||||||
// of existing files in the filesystem, if they exist.
|
// of existing files in the filesystem, if they exist.
|
||||||
bool FSstrict;
|
bool FSstrict;
|
||||||
FileFinder::FileFinder files;
|
FileFinder::LessTreeFileFinder files;
|
||||||
FileFinder::FileFinderStrict strict;
|
FileFinder::StrictTreeFileFinder strict;
|
||||||
FileFinder::FileFinder musicpath;
|
FileFinder::LessTreeFileFinder musicpath;
|
||||||
FileFinder::FileFinderStrict musicpathStrict;
|
FileFinder::StrictTreeFileFinder musicpathStrict;
|
||||||
|
|
||||||
SoundImpl(Ogre::Root *root, Ogre::Camera *camera,
|
SoundImpl(Ogre::Root *root, Ogre::Camera *camera, const ESMS::ESMStore &str,
|
||||||
const ESMS::ESMStore &str,
|
const Files::PathContainer& soundDir,
|
||||||
const std::string &soundDir, const std::string &musicDir, bool fsstrict)
|
const Files::PathContainer& musicDir,
|
||||||
|
bool fsstrict)
|
||||||
: mgr(new OEManager(SoundFactoryPtr(new SOUND_FACTORY)))
|
: mgr(new OEManager(SoundFactoryPtr(new SOUND_FACTORY)))
|
||||||
, updater(mgr)
|
, updater(mgr)
|
||||||
, cameraTracker(mgr)
|
, cameraTracker(mgr)
|
||||||
, store(str)
|
, store(str)
|
||||||
, files(soundDir), strict(soundDir)
|
, FSstrict(fsstrict)
|
||||||
,musicpath(musicDir), musicpathStrict(musicDir)
|
, files(soundDir)
|
||||||
|
, strict(soundDir)
|
||||||
|
, musicpath(musicDir)
|
||||||
|
, musicpathStrict(musicDir)
|
||||||
{
|
{
|
||||||
FSstrict = fsstrict;
|
|
||||||
cout << "Sound output: " << SOUND_OUT << endl;
|
std::cout << "Sound output: " << SOUND_OUT << std::endl;
|
||||||
cout << "Sound decoder: " << SOUND_IN << endl;
|
std::cout << "Sound decoder: " << SOUND_IN << std::endl;
|
||||||
// Attach the camera to the camera tracker
|
// Attach the camera to the camera tracker
|
||||||
cameraTracker.followCamera(camera);
|
cameraTracker.followCamera(camera);
|
||||||
|
|
||||||
|
@ -136,36 +139,49 @@ namespace MWSound
|
||||||
|
|
||||||
bool hasFile(const std::string &str, bool music = false)
|
bool hasFile(const std::string &str, bool music = false)
|
||||||
{
|
{
|
||||||
if(FSstrict == false)
|
bool found = false;
|
||||||
|
if(!FSstrict)
|
||||||
{
|
{
|
||||||
if(music)
|
if(music)
|
||||||
{
|
{
|
||||||
if(musicpath.has(str)) return true;
|
found = musicpath.has(str);
|
||||||
|
|
||||||
// Not found? Try with .mp3
|
// Not found? Try with .mp3
|
||||||
return musicpath.has(toMp3(str));
|
if (!found)
|
||||||
|
{
|
||||||
|
found = musicpath.has(toMp3(str));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(files.has(str)) return true;
|
found = files.has(str);
|
||||||
return files.has(toMp3(str));
|
if (!found)
|
||||||
|
{
|
||||||
|
found = files.has(toMp3(str));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(music)
|
if(music)
|
||||||
{
|
{
|
||||||
if(musicpathStrict.has(str)) return true;
|
found = musicpathStrict.has(str);
|
||||||
|
|
||||||
// Not found? Try with .mp3
|
// Not found? Try with .mp3
|
||||||
return musicpathStrict.has(toMp3(str));
|
if (!found)
|
||||||
|
{
|
||||||
|
found = musicpathStrict.has(toMp3(str));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(strict.has(str)) return true;
|
found = strict.has(str);
|
||||||
return strict.has(toMp3(str));
|
if (!found)
|
||||||
|
{
|
||||||
|
found = strict.has(toMp3(str));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a Morrowind sound path (eg. Fx\funny.wav) to full path
|
// Convert a Morrowind sound path (eg. Fx\funny.wav) to full path
|
||||||
|
@ -258,13 +274,13 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
cout << "Error loading " << file << ", skipping.\n";
|
std::cout << "Error loading " << file << ", skipping.\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clears all the sub-elements of a given iterator, and then
|
// Clears all the sub-elements of a given iterator, and then
|
||||||
// removes it from 'sounds'.
|
// removes it from 'sounds'.
|
||||||
void clearAll(PtrMap::iterator it)
|
void clearAll(PtrMap::iterator& it)
|
||||||
{
|
{
|
||||||
IDMap::iterator sit = it->second.begin();
|
IDMap::iterator sit = it->second.begin();
|
||||||
|
|
||||||
|
@ -362,9 +378,9 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}; /* SoundImpl */
|
||||||
|
|
||||||
void SoundManager::streamMusicFull (const std::string& filename)
|
void SoundManager::streamMusicFull(const std::string& filename)
|
||||||
{
|
{
|
||||||
if(!mData) return;
|
if(!mData) return;
|
||||||
|
|
||||||
|
@ -381,20 +397,24 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundManager::SoundManager(Ogre::Root *root, Ogre::Camera *camera,
|
SoundManager::SoundManager(Ogre::Root *root, Ogre::Camera *camera,
|
||||||
const ESMS::ESMStore &store,
|
const ESMS::ESMStore &store, const Files::PathContainer& dataDirs,
|
||||||
boost::filesystem::path dataDir,
|
bool useSound, bool fsstrict, MWWorld::Environment& environment)
|
||||||
bool useSound, bool fsstrict, MWWorld::Environment& environment)
|
: mData(NULL)
|
||||||
: mData(NULL), fsStrict (fsstrict), mEnvironment (environment)
|
, fsStrict(fsstrict)
|
||||||
|
, mEnvironment(environment)
|
||||||
{
|
{
|
||||||
MP3Lookup(dataDir / "Music/Explore/");
|
for (Files::PathContainer::const_iterator it = dataDirs.begin(); it != dataDirs.end(); ++it)
|
||||||
if(useSound)
|
{
|
||||||
mData = new SoundImpl(root, camera, store, (dataDir / "Sound").string(), (dataDir / "Music").string(), fsstrict);
|
MP3Lookup((*it) / "Music/Explore/");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(useSound)
|
||||||
|
{
|
||||||
|
mData = new SoundImpl(root, camera, store, dataDirs /* Sound */, dataDirs /* Music */, fsstrict);
|
||||||
|
}
|
||||||
|
|
||||||
test.name = "";
|
test.name = "";
|
||||||
total = 0;
|
total = 0;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundManager::~SoundManager()
|
SoundManager::~SoundManager()
|
||||||
|
@ -407,14 +427,12 @@ namespace MWSound
|
||||||
{
|
{
|
||||||
if(mData->hasFile(filename, true))
|
if(mData->hasFile(filename, true))
|
||||||
{
|
{
|
||||||
std::string fullpath = mData->convertPath(filename, true);
|
streamMusicFull(mData->convertPath(filename, true));
|
||||||
streamMusicFull(fullpath);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoundManager::MP3Lookup(const boost::filesystem::path& dir)
|
||||||
void SoundManager::MP3Lookup(boost::filesystem::path dir)
|
{
|
||||||
{
|
|
||||||
boost::filesystem::directory_iterator dir_iter(dir), dir_end;
|
boost::filesystem::directory_iterator dir_iter(dir), dir_end;
|
||||||
|
|
||||||
std::string mp3extension = ".mp3";
|
std::string mp3extension = ".mp3";
|
||||||
|
@ -425,35 +443,30 @@ namespace MWSound
|
||||||
files.push_back(*dir_iter);
|
files.push_back(*dir_iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundManager::startRandomTitle()
|
void SoundManager::startRandomTitle()
|
||||||
{
|
{
|
||||||
std::vector<boost::filesystem::path>::iterator fileIter;
|
if(!files.empty())
|
||||||
|
|
||||||
if(files.size() > 0)
|
|
||||||
{
|
{
|
||||||
fileIter = files.begin();
|
Files::PathContainer::iterator fileIter = files.begin();
|
||||||
srand ( time(NULL) );
|
srand( time(NULL) );
|
||||||
int r = rand() % files.size() + 1; //old random code
|
int r = rand() % files.size() + 1; //old random code
|
||||||
|
|
||||||
for(int i = 1; i < r; i++)
|
std::advance(fileIter, r - 1);
|
||||||
{
|
|
||||||
fileIter++;
|
|
||||||
}
|
|
||||||
std::string music = fileIter->string();
|
std::string music = fileIter->string();
|
||||||
|
std::cout << "Playing " << music << "\n";
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::cout << "Playing " << music << "\n";
|
|
||||||
streamMusicFull(music);
|
streamMusicFull(music);
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch (std::exception &e)
|
||||||
{
|
{
|
||||||
std::cout << " Music Error: " << e.what() << "\n";
|
std::cout << " Music Error: " << e.what() << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SoundManager::isMusicPlaying()
|
bool SoundManager::isMusicPlaying()
|
||||||
{
|
{
|
||||||
|
@ -465,14 +478,12 @@ namespace MWSound
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundManager::SoundImpl SoundManager::getMData()
|
SoundManager::SoundImpl SoundManager::getMData()
|
||||||
{
|
{
|
||||||
// bool test = mData->music->isPlaying();
|
// bool test = mData->music->isPlaying();
|
||||||
return *mData;
|
return *mData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SoundManager::say (MWWorld::Ptr ptr, const std::string& filename)
|
void SoundManager::say (MWWorld::Ptr ptr, const std::string& filename)
|
||||||
{
|
{
|
||||||
// The range values are not tested
|
// The range values are not tested
|
||||||
|
@ -480,7 +491,7 @@ namespace MWSound
|
||||||
if(mData->hasFile(filename))
|
if(mData->hasFile(filename))
|
||||||
mData->add(mData->convertPath(filename), ptr, "_say_sound", 1, 1, 100, 20000, false);
|
mData->add(mData->convertPath(filename), ptr, "_say_sound", 1, 1, 100, 20000, false);
|
||||||
else
|
else
|
||||||
cout << "Sound file " << filename << " not found, skipping.\n";
|
std::cout << "Sound file " << filename << " not found, skipping.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SoundManager::sayDone (MWWorld::Ptr ptr) const
|
bool SoundManager::sayDone (MWWorld::Ptr ptr) const
|
||||||
|
@ -490,20 +501,20 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SoundManager::playSound (const std::string& soundId, float volume, float pitch)
|
void SoundManager::playSound(const std::string& soundId, float volume, float pitch)
|
||||||
{
|
{
|
||||||
if(!mData) return;
|
if(!mData) return;
|
||||||
// Play and forget
|
// Play and forget
|
||||||
float min, max;
|
float min, max;
|
||||||
const std::string &file = mData->lookup(soundId, volume, min, max);
|
const std::string &file = mData->lookup(soundId, volume, min, max);
|
||||||
if(file != "")
|
if (file != "")
|
||||||
{
|
{
|
||||||
SoundPtr snd = mData->mgr->load(file);
|
SoundPtr snd = mData->mgr->load(file);
|
||||||
snd->setVolume(volume);
|
snd->setVolume(volume);
|
||||||
snd->setRange(min,max);
|
snd->setRange(min,max);
|
||||||
snd->setPitch(pitch);
|
snd->setPitch(pitch);
|
||||||
snd->play();
|
snd->play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundManager::playSound3D (MWWorld::Ptr ptr, const std::string& soundId,
|
void SoundManager::playSound3D (MWWorld::Ptr ptr, const std::string& soundId,
|
||||||
|
@ -514,7 +525,7 @@ namespace MWSound
|
||||||
// Look up the sound in the ESM data
|
// Look up the sound in the ESM data
|
||||||
float min, max;
|
float min, max;
|
||||||
const std::string &file = mData->lookup(soundId, volume, min, max);
|
const std::string &file = mData->lookup(soundId, volume, min, max);
|
||||||
if(file != "")
|
if (file != "")
|
||||||
mData->add(file, ptr, soundId, volume, pitch, min, max, loop);
|
mData->add(file, ptr, soundId, volume, pitch, min, max, loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,18 +552,19 @@ namespace MWSound
|
||||||
|
|
||||||
void SoundManager::updateObject(MWWorld::Ptr ptr)
|
void SoundManager::updateObject(MWWorld::Ptr ptr)
|
||||||
{
|
{
|
||||||
if(!mData) return;
|
if (mData != NULL)
|
||||||
mData->updatePositions(ptr);
|
{
|
||||||
|
mData->updatePositions(ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundManager::update (float duration)
|
void SoundManager::update (float duration)
|
||||||
{
|
{
|
||||||
std::string effect;
|
|
||||||
|
|
||||||
MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayer().getPlayer().getCell();
|
MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayer().getPlayer().getCell();
|
||||||
|
|
||||||
//If the region has changed
|
//If the region has changed
|
||||||
if(!(current->cell->data.flags & current->cell->Interior) && timer.elapsed() >= 10){
|
if(!(current->cell->data.flags & current->cell->Interior) && timer.elapsed() >= 10)
|
||||||
|
{
|
||||||
timer.restart();
|
timer.restart();
|
||||||
if (test.name != current->cell->region)
|
if (test.name != current->cell->region)
|
||||||
{
|
{
|
||||||
|
@ -564,11 +576,12 @@ namespace MWSound
|
||||||
{
|
{
|
||||||
std::vector<ESM::Region::SoundRef>::iterator soundIter = test.soundList.begin();
|
std::vector<ESM::Region::SoundRef>::iterator soundIter = test.soundList.begin();
|
||||||
//mEnvironment.mSoundManager
|
//mEnvironment.mSoundManager
|
||||||
if(total == 0){
|
if(total == 0)
|
||||||
while (!(soundIter == test.soundList.end()))
|
{
|
||||||
|
while (soundIter != test.soundList.end())
|
||||||
{
|
{
|
||||||
ESM::NAME32 go = soundIter->sound;
|
|
||||||
int chance = (int) soundIter->chance;
|
int chance = (int) soundIter->chance;
|
||||||
|
//ESM::NAME32 go = soundIter->sound;
|
||||||
//std::cout << "Sound: " << go.name <<" Chance:" << chance << "\n";
|
//std::cout << "Sound: " << go.name <<" Chance:" << chance << "\n";
|
||||||
soundIter++;
|
soundIter++;
|
||||||
total += chance;
|
total += chance;
|
||||||
|
@ -578,7 +591,7 @@ namespace MWSound
|
||||||
int r = rand() % total; //old random code
|
int r = rand() % total; //old random code
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
soundIter = test.soundList.begin();
|
soundIter = test.soundList.begin();
|
||||||
while (!(soundIter == test.soundList.end()))
|
while (soundIter != test.soundList.end())
|
||||||
{
|
{
|
||||||
const ESM::NAME32 go = soundIter->sound;
|
const ESM::NAME32 go = soundIter->sound;
|
||||||
int chance = (int) soundIter->chance;
|
int chance = (int) soundIter->chance;
|
||||||
|
@ -586,13 +599,11 @@ namespace MWSound
|
||||||
soundIter++;
|
soundIter++;
|
||||||
if( r - pos < chance)
|
if( r - pos < chance)
|
||||||
{
|
{
|
||||||
effect = go.name;
|
|
||||||
//play sound
|
//play sound
|
||||||
std::cout << "Sound: " << go.name <<" Chance:" << chance << "\n";
|
std::cout << "Sound: " << go.name <<" Chance:" << chance << "\n";
|
||||||
mEnvironment.mSoundManager->playSound(effect, 20.0, 1.0);
|
mEnvironment.mSoundManager->playSound(go.name, 20.0, 1.0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
pos += chance;
|
pos += chance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,15 @@
|
||||||
#define GAME_SOUND_SOUNDMANAGER_H
|
#define GAME_SOUND_SOUNDMANAGER_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <boost/timer.hpp>
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
#include <openengine/sound/sndmanager.hpp>
|
#include <openengine/sound/sndmanager.hpp>
|
||||||
|
#include <components/files/multidircollection.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include <boost/timer.hpp>
|
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
|
@ -37,7 +38,7 @@ namespace MWSound
|
||||||
struct SoundImpl;
|
struct SoundImpl;
|
||||||
|
|
||||||
SoundImpl *mData;
|
SoundImpl *mData;
|
||||||
std::vector<boost::filesystem::path> files;
|
Files::PathContainer files;
|
||||||
bool fsStrict;
|
bool fsStrict;
|
||||||
MWWorld::Environment& mEnvironment;
|
MWWorld::Environment& mEnvironment;
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ namespace MWSound
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SoundManager(Ogre::Root*, Ogre::Camera*, const ESMS::ESMStore &store,
|
SoundManager(Ogre::Root*, Ogre::Camera*, const ESMS::ESMStore &store,
|
||||||
boost::filesystem::path dataDir, bool useSound, bool fsstrict,
|
const Files::PathContainer& dataDir, bool useSound, bool fsstrict,
|
||||||
MWWorld::Environment& environment);
|
MWWorld::Environment& environment);
|
||||||
~SoundManager();
|
~SoundManager();
|
||||||
|
|
||||||
|
@ -61,7 +62,7 @@ namespace MWSound
|
||||||
/// \param filename name of a sound file in "Music/" in the data directory.
|
/// \param filename name of a sound file in "Music/" in the data directory.
|
||||||
|
|
||||||
void startRandomTitle();
|
void startRandomTitle();
|
||||||
void MP3Lookup(boost::filesystem::path dir);
|
void MP3Lookup(const boost::filesystem::path& dir);
|
||||||
|
|
||||||
bool isMusicPlaying();
|
bool isMusicPlaying();
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,6 @@ add_component_dir (bsa
|
||||||
bsa_archive bsa_file
|
bsa_archive bsa_file
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (cfg
|
|
||||||
configurationmanager
|
|
||||||
)
|
|
||||||
|
|
||||||
add_component_dir (nif
|
add_component_dir (nif
|
||||||
controlled effect nif_types record controller extra node record_ptr data nif_file property
|
controlled effect nif_types record controller extra node record_ptr data nif_file property
|
||||||
)
|
)
|
||||||
|
@ -47,7 +43,7 @@ add_component_dir (misc
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (files
|
add_component_dir (files
|
||||||
linuxpath windowspath macospath path multidircollection collections fileops
|
linuxpath windowspath macospath fixedpath multidircollection collections fileops configurationmanager
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (compiler
|
add_component_dir (compiler
|
||||||
|
|
|
@ -1,157 +0,0 @@
|
||||||
#include "configurationmanager.hpp"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace Cfg
|
|
||||||
{
|
|
||||||
|
|
||||||
static const char* const openmwCfgFile = "openmw.cfg";
|
|
||||||
static const char* const ogreCfgFile = "ogre.cfg";
|
|
||||||
static const char* const pluginsCfgFile = "plugins.cfg";
|
|
||||||
|
|
||||||
|
|
||||||
ConfigurationManager::ConfigurationManager()
|
|
||||||
: mPath("openmw")
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* According to task #168 plugins.cfg file shall be located in global
|
|
||||||
* configuration path or in runtime configuration path.
|
|
||||||
*/
|
|
||||||
mPluginsCfgPath = mPath.getGlobalConfigPath() / pluginsCfgFile;
|
|
||||||
if (!boost::filesystem::is_regular_file(mPluginsCfgPath))
|
|
||||||
{
|
|
||||||
mPluginsCfgPath = mPath.getRuntimeConfigPath() / pluginsCfgFile;
|
|
||||||
if (!boost::filesystem::is_regular_file(mPluginsCfgPath))
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to find " << pluginsCfgFile << " file!" << std::endl;
|
|
||||||
mPluginsCfgPath.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* According to task #168 ogre.cfg file shall be located only
|
|
||||||
* in user configuration path.
|
|
||||||
*/
|
|
||||||
mOgreCfgPath = mPath.getLocalConfigPath() / ogreCfgFile;
|
|
||||||
|
|
||||||
mLogPath = mPath.getLocalConfigPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigurationManager::~ConfigurationManager()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::readConfiguration(boost::program_options::variables_map& variables,
|
|
||||||
boost::program_options::options_description& description)
|
|
||||||
{
|
|
||||||
loadConfig(mPath.getLocalConfigPath(), variables, description);
|
|
||||||
boost::program_options::notify(variables);
|
|
||||||
loadConfig(mPath.getRuntimeConfigPath(), variables, description);
|
|
||||||
boost::program_options::notify(variables);
|
|
||||||
loadConfig(mPath.getGlobalConfigPath(), variables, description);
|
|
||||||
boost::program_options::notify(variables);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::loadConfig(const boost::filesystem::path& path,
|
|
||||||
boost::program_options::variables_map& variables,
|
|
||||||
boost::program_options::options_description& description)
|
|
||||||
{
|
|
||||||
boost::filesystem::path cfgFile(path);
|
|
||||||
cfgFile /= std::string(openmwCfgFile);
|
|
||||||
if (boost::filesystem::is_regular_file(cfgFile))
|
|
||||||
{
|
|
||||||
std::cout << "Loading config file: " << cfgFile.string() << "... ";
|
|
||||||
|
|
||||||
std::ifstream configFileStream(cfgFile.string().c_str());
|
|
||||||
if (configFileStream.is_open())
|
|
||||||
{
|
|
||||||
boost::program_options::store(boost::program_options::parse_config_file(
|
|
||||||
configFileStream, description), variables);
|
|
||||||
|
|
||||||
std::cout << "done." << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "failed." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getGlobalConfigPath() const
|
|
||||||
{
|
|
||||||
return mPath.getGlobalConfigPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::setGlobalConfigPath(const boost::filesystem::path& newPath)
|
|
||||||
{
|
|
||||||
mPath.setGlobalConfigPath(newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getLocalConfigPath() const
|
|
||||||
{
|
|
||||||
return mPath.getLocalConfigPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::setLocalConfigPath(const boost::filesystem::path& newPath)
|
|
||||||
{
|
|
||||||
mPath.setLocalConfigPath(newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getRuntimeConfigPath() const
|
|
||||||
{
|
|
||||||
return mPath.getRuntimeConfigPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::setRuntimeConfigPath(const boost::filesystem::path& newPath)
|
|
||||||
{
|
|
||||||
mPath.setRuntimeConfigPath(newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getGlobalDataPath() const
|
|
||||||
{
|
|
||||||
return mPath.getGlobalDataPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::setGlobalDataPath(const boost::filesystem::path& newPath)
|
|
||||||
{
|
|
||||||
mPath.setGlobalDataPath(newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getLocalDataPath() const
|
|
||||||
{
|
|
||||||
return mPath.getLocalDataPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::setLocalDataPath(const boost::filesystem::path& newPath)
|
|
||||||
{
|
|
||||||
mPath.setLocalDataPath(newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getRuntimeDataPath() const
|
|
||||||
{
|
|
||||||
return mPath.getRuntimeDataPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationManager::setRuntimeDataPath(const boost::filesystem::path& newPath)
|
|
||||||
{
|
|
||||||
mPath.setRuntimeDataPath(newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getOgreConfigPath() const
|
|
||||||
{
|
|
||||||
return mOgreCfgPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getPluginsConfigPath() const
|
|
||||||
{
|
|
||||||
return mPluginsCfgPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getLogPath() const
|
|
||||||
{
|
|
||||||
return mLogPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* namespace Cfg */
|
|
|
@ -1,9 +1,11 @@
|
||||||
#ifndef FILE_FINDER_MAIN_H
|
#ifndef FILE_FINDER_MAIN_H
|
||||||
#define FILE_FINDER_MAIN_H
|
#define FILE_FINDER_MAIN_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "search.hpp"
|
#include "search.hpp"
|
||||||
#include "filename_less.hpp"
|
#include "filename_less.hpp"
|
||||||
#include <map>
|
#include <components/files/multidircollection.hpp>
|
||||||
|
|
||||||
namespace FileFinder
|
namespace FileFinder
|
||||||
{
|
{
|
||||||
|
@ -11,7 +13,8 @@ namespace FileFinder
|
||||||
template <typename LESS>
|
template <typename LESS>
|
||||||
class FileFinderT
|
class FileFinderT
|
||||||
{
|
{
|
||||||
std::map<std::string, std::string, LESS> table;
|
typedef std::map<std::string, std::string, LESS> TableContainer;
|
||||||
|
TableContainer table;
|
||||||
|
|
||||||
struct Inserter : ReturnPath
|
struct Inserter : ReturnPath
|
||||||
{
|
{
|
||||||
|
@ -35,12 +38,12 @@ public:
|
||||||
|
|
||||||
// Remember the original path length, so we can cut it away from
|
// Remember the original path length, so we can cut it away from
|
||||||
// the relative paths used as keys
|
// the relative paths used as keys
|
||||||
std::string pstring = path.string();
|
const std::string& pstring = path.string();
|
||||||
inserter.cut = pstring.size();
|
inserter.cut = pstring.size();
|
||||||
|
|
||||||
// If the path does not end in a slash, then boost will add one
|
// If the path does not end in a slash, then boost will add one
|
||||||
// later, which means one more character we have to remove.
|
// later, which means one more character we have to remove.
|
||||||
char last = pstring[pstring.size()-1];
|
char last = *pstring.rbegin();
|
||||||
if(last != '\\' && last != '/')
|
if(last != '\\' && last != '/')
|
||||||
inserter.cut++;
|
inserter.cut++;
|
||||||
|
|
||||||
|
@ -56,12 +59,84 @@ public:
|
||||||
// Find the full path from a relative path.
|
// Find the full path from a relative path.
|
||||||
const std::string &lookup(const std::string& file) const
|
const std::string &lookup(const std::string& file) const
|
||||||
{
|
{
|
||||||
return table.find(file)->second;
|
static std::string empty;
|
||||||
|
typename TableContainer::const_iterator it = table.find(file);
|
||||||
|
return (it != table.end()) ? it->second : empty;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
class LESS
|
||||||
|
>
|
||||||
|
struct TreeFileFinder
|
||||||
|
{
|
||||||
|
typedef TreeFileFinder<LESS> finder_t;
|
||||||
|
|
||||||
|
TreeFileFinder(const Files::PathContainer& paths, bool recurse = true)
|
||||||
|
{
|
||||||
|
struct : ReturnPath
|
||||||
|
{
|
||||||
|
finder_t *owner;
|
||||||
|
int cut;
|
||||||
|
|
||||||
|
void add(const boost::filesystem::path &pth)
|
||||||
|
{
|
||||||
|
std::string file = pth.string();
|
||||||
|
std::string key = file.substr(cut);
|
||||||
|
owner->mTable[key] = file;
|
||||||
|
}
|
||||||
|
} inserter;
|
||||||
|
|
||||||
|
inserter.owner = this;
|
||||||
|
|
||||||
|
for (Files::PathContainer::const_iterator it = paths.begin(); it != paths.end(); ++it)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Remember the original path length, so we can cut it away from
|
||||||
|
// the relative paths used as keys
|
||||||
|
const std::string& pstring = it->string();
|
||||||
|
inserter.cut = pstring.size();
|
||||||
|
|
||||||
|
// If the path does not end in a slash, then boost will add one
|
||||||
|
// later, which means one more character we have to remove.
|
||||||
|
char last = *pstring.rbegin();
|
||||||
|
if (last != '\\' && last != '/')
|
||||||
|
{
|
||||||
|
inserter.cut++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill the map
|
||||||
|
find(*it, inserter, recurse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has(const std::string& file) const
|
||||||
|
{
|
||||||
|
return mTable.find(file) != mTable.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& lookup(const std::string& file) const
|
||||||
|
{
|
||||||
|
static std::string empty;
|
||||||
|
typename TableContainer::const_iterator it = mTable.find(file);
|
||||||
|
return (it != mTable.end()) ? it->second : empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::map<std::string, std::string, LESS> TableContainer;
|
||||||
|
TableContainer mTable;
|
||||||
|
|
||||||
|
// Inserter inserter;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// The default is to use path_less for equality checks
|
// The default is to use path_less for equality checks
|
||||||
typedef FileFinderT<path_less> FileFinder;
|
typedef FileFinderT<path_less> FileFinder;
|
||||||
typedef FileFinderT<path_slash> FileFinderStrict;
|
typedef FileFinderT<path_slash> FileFinderStrict;
|
||||||
}
|
|
||||||
#endif
|
typedef TreeFileFinder<path_less> LessTreeFileFinder;
|
||||||
|
typedef TreeFileFinder<path_slash> StrictTreeFileFinder;
|
||||||
|
|
||||||
|
} /* namespace FileFinder */
|
||||||
|
#endif /* FILE_FINDER_MAIN_H */
|
||||||
|
|
|
@ -2,27 +2,35 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
void FileFinder::find(const boost::filesystem::path & dir_path, ReturnPath &ret, bool recurse)
|
||||||
using namespace boost::filesystem;
|
|
||||||
|
|
||||||
void FileFinder::find(const path & dir_path, ReturnPath &ret, bool recurse)
|
|
||||||
{
|
{
|
||||||
if ( !exists( dir_path ) )
|
if (boost::filesystem::exists(dir_path))
|
||||||
{
|
{
|
||||||
cout << "Path " << dir_path << " not found\n";
|
if (!recurse)
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
directory_iterator end_itr; // default construction yields past-the-end
|
|
||||||
for ( directory_iterator itr(dir_path);
|
|
||||||
itr != end_itr;
|
|
||||||
++itr )
|
|
||||||
{
|
|
||||||
if ( is_directory( *itr ) )
|
|
||||||
{
|
{
|
||||||
if(recurse) find(*itr, ret);
|
boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
|
||||||
|
for (boost::filesystem::directory_iterator itr(dir_path); itr != end_itr; ++itr)
|
||||||
|
{
|
||||||
|
if (!boost::filesystem::is_directory( *itr ))
|
||||||
|
{
|
||||||
|
ret.add(*itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret.add(*itr);
|
{
|
||||||
|
boost::filesystem::recursive_directory_iterator end_itr; // default construction yields past-the-end
|
||||||
|
for (boost::filesystem::recursive_directory_iterator itr(dir_path); itr != end_itr; ++itr)
|
||||||
|
{
|
||||||
|
if (!boost::filesystem::is_directory(*itr))
|
||||||
|
{
|
||||||
|
ret.add(*itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Path " << dir_path << " not found" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
178
components/files/configurationmanager.cpp
Normal file
178
components/files/configurationmanager.cpp
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
#include "configurationmanager.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \namespace Files
|
||||||
|
*/
|
||||||
|
namespace Files
|
||||||
|
{
|
||||||
|
|
||||||
|
static const char* const openmwCfgFile = "openmw.cfg";
|
||||||
|
static const char* const ogreCfgFile = "ogre.cfg";
|
||||||
|
static const char* const pluginsCfgFile = "plugins.cfg";
|
||||||
|
|
||||||
|
const char* const mwToken = "?mw?";
|
||||||
|
const char* const localToken = "?local?";
|
||||||
|
const char* const userToken = "?user?";
|
||||||
|
const char* const globalToken = "?global?";
|
||||||
|
|
||||||
|
ConfigurationManager::ConfigurationManager()
|
||||||
|
: mFixedPath("openmw")
|
||||||
|
{
|
||||||
|
setupTokensMapping();
|
||||||
|
|
||||||
|
mPluginsCfgPath = mFixedPath.getGlobalPath() / pluginsCfgFile;
|
||||||
|
if (!boost::filesystem::is_regular_file(mPluginsCfgPath))
|
||||||
|
{
|
||||||
|
mPluginsCfgPath = mFixedPath.getLocalPath() / pluginsCfgFile;
|
||||||
|
if (!boost::filesystem::is_regular_file(mPluginsCfgPath))
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to find " << pluginsCfgFile << " file!" << std::endl;
|
||||||
|
mPluginsCfgPath.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mOgreCfgPath = mFixedPath.getUserPath() / ogreCfgFile;
|
||||||
|
mLogPath = mFixedPath.getUserPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigurationManager::~ConfigurationManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationManager::setupTokensMapping()
|
||||||
|
{
|
||||||
|
mTokensMapping.insert(std::make_pair(mwToken, &FixedPath<>::getInstallPath));
|
||||||
|
mTokensMapping.insert(std::make_pair(localToken, &FixedPath<>::getLocalPath));
|
||||||
|
mTokensMapping.insert(std::make_pair(userToken, &FixedPath<>::getUserPath));
|
||||||
|
mTokensMapping.insert(std::make_pair(globalToken, &FixedPath<>::getGlobalDataPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationManager::readConfiguration(boost::program_options::variables_map& variables,
|
||||||
|
boost::program_options::options_description& description)
|
||||||
|
{
|
||||||
|
loadConfig(mFixedPath.getUserPath(), variables, description);
|
||||||
|
boost::program_options::notify(variables);
|
||||||
|
|
||||||
|
loadConfig(mFixedPath.getLocalPath(), variables, description);
|
||||||
|
boost::program_options::notify(variables);
|
||||||
|
loadConfig(mFixedPath.getGlobalPath(), variables, description);
|
||||||
|
boost::program_options::notify(variables);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationManager::processPaths(Files::PathContainer& dataDirs)
|
||||||
|
{
|
||||||
|
for (Files::PathContainer::iterator it = dataDirs.begin(); it != dataDirs.end(); ++it)
|
||||||
|
{
|
||||||
|
const std::string& path = it->string();
|
||||||
|
|
||||||
|
// Check if path contains a token
|
||||||
|
if (!path.empty() && *path.begin() == '?')
|
||||||
|
{
|
||||||
|
std::string::size_type pos = path.find('?', 1);
|
||||||
|
if (pos != std::string::npos && pos != 0)
|
||||||
|
{
|
||||||
|
TokensMappingContainer::iterator tokenIt = mTokensMapping.find(path.substr(0, pos + 1));
|
||||||
|
if (tokenIt != mTokensMapping.end())
|
||||||
|
{
|
||||||
|
boost::filesystem::path tempPath(((mFixedPath).*(tokenIt->second))());
|
||||||
|
if (pos < path.length() - 1)
|
||||||
|
{
|
||||||
|
// There is something after the token, so we should
|
||||||
|
// append it to the path
|
||||||
|
tempPath /= path.substr(pos + 1, path.length() - pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
*it = tempPath;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Clean invalid / unknown token, it will be removed outside the loop
|
||||||
|
(*it).clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!boost::filesystem::is_directory(*it))
|
||||||
|
{
|
||||||
|
(*it).clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dataDirs.erase(std::remove_if(dataDirs.begin(), dataDirs.end(),
|
||||||
|
boost::bind(&boost::filesystem::path::empty, _1)), dataDirs.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationManager::loadConfig(const boost::filesystem::path& path,
|
||||||
|
boost::program_options::variables_map& variables,
|
||||||
|
boost::program_options::options_description& description)
|
||||||
|
{
|
||||||
|
boost::filesystem::path cfgFile(path);
|
||||||
|
cfgFile /= std::string(openmwCfgFile);
|
||||||
|
if (boost::filesystem::is_regular_file(cfgFile))
|
||||||
|
{
|
||||||
|
std::cout << "Loading config file: " << cfgFile.string() << "... ";
|
||||||
|
|
||||||
|
std::ifstream configFileStream(cfgFile.string().c_str());
|
||||||
|
if (configFileStream.is_open())
|
||||||
|
{
|
||||||
|
boost::program_options::store(boost::program_options::parse_config_file(
|
||||||
|
configFileStream, description), variables);
|
||||||
|
|
||||||
|
std::cout << "done." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "failed." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getGlobalPath() const
|
||||||
|
{
|
||||||
|
return mFixedPath.getGlobalPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getUserPath() const
|
||||||
|
{
|
||||||
|
return mFixedPath.getUserPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getLocalPath() const
|
||||||
|
{
|
||||||
|
return mFixedPath.getLocalPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getGlobalDataPath() const
|
||||||
|
{
|
||||||
|
return mFixedPath.getGlobalDataPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getInstallPath() const
|
||||||
|
{
|
||||||
|
return mFixedPath.getInstallPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getOgreConfigPath() const
|
||||||
|
{
|
||||||
|
return mOgreCfgPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getPluginsConfigPath() const
|
||||||
|
{
|
||||||
|
return mPluginsCfgPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& ConfigurationManager::getLogPath() const
|
||||||
|
{
|
||||||
|
return mLogPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace Cfg */
|
|
@ -1,15 +1,18 @@
|
||||||
#ifndef COMPONENTS_CFG_CONFIGURATIONMANAGER_HPP
|
#ifndef COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP
|
||||||
#define COMPONENTS_CFG_CONFIGURATIONMANAGER_HPP
|
#define COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP
|
||||||
|
|
||||||
|
#include <tr1/unordered_map>
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
#include <components/files/path.hpp>
|
#include <components/files/fixedpath.hpp>
|
||||||
|
#include <components/files/collections.hpp>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \namespace Cfg
|
* \namespace Files
|
||||||
*/
|
*/
|
||||||
namespace Cfg
|
namespace Files
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,41 +25,43 @@ struct ConfigurationManager
|
||||||
|
|
||||||
void readConfiguration(boost::program_options::variables_map& variables,
|
void readConfiguration(boost::program_options::variables_map& variables,
|
||||||
boost::program_options::options_description& description);
|
boost::program_options::options_description& description);
|
||||||
|
void processPaths(Files::PathContainer& dataDirs);
|
||||||
|
|
||||||
const boost::filesystem::path& getGlobalConfigPath() const;
|
/**< Fixed paths */
|
||||||
void setGlobalConfigPath(const boost::filesystem::path& newPath);
|
const boost::filesystem::path& getGlobalPath() const;
|
||||||
|
const boost::filesystem::path& getUserPath() const;
|
||||||
const boost::filesystem::path& getLocalConfigPath() const;
|
const boost::filesystem::path& getLocalPath() const;
|
||||||
void setLocalConfigPath(const boost::filesystem::path& newPath);
|
|
||||||
|
|
||||||
const boost::filesystem::path& getRuntimeConfigPath() const;
|
|
||||||
void setRuntimeConfigPath(const boost::filesystem::path& newPath);
|
|
||||||
|
|
||||||
const boost::filesystem::path& getGlobalDataPath() const;
|
const boost::filesystem::path& getGlobalDataPath() const;
|
||||||
void setGlobalDataPath(const boost::filesystem::path& newPath);
|
const boost::filesystem::path& getUserDataPath() const;
|
||||||
|
|
||||||
const boost::filesystem::path& getLocalDataPath() const;
|
const boost::filesystem::path& getLocalDataPath() const;
|
||||||
void setLocalDataPath(const boost::filesystem::path& newPath);
|
const boost::filesystem::path& getInstallPath() const;
|
||||||
|
|
||||||
const boost::filesystem::path& getRuntimeDataPath() const;
|
|
||||||
void setRuntimeDataPath(const boost::filesystem::path& newPath);
|
|
||||||
|
|
||||||
const boost::filesystem::path& getOgreConfigPath() const;
|
const boost::filesystem::path& getOgreConfigPath() const;
|
||||||
const boost::filesystem::path& getPluginsConfigPath() const;
|
const boost::filesystem::path& getPluginsConfigPath() const;
|
||||||
const boost::filesystem::path& getLogPath() const;
|
const boost::filesystem::path& getLogPath() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef Files::FixedPath<> FixedPathType;
|
||||||
|
|
||||||
|
typedef const boost::filesystem::path& (FixedPathType::*path_type_f)() const;
|
||||||
|
typedef std::tr1::unordered_map<std::string, path_type_f> TokensMappingContainer;
|
||||||
|
|
||||||
void loadConfig(const boost::filesystem::path& path,
|
void loadConfig(const boost::filesystem::path& path,
|
||||||
boost::program_options::variables_map& variables,
|
boost::program_options::variables_map& variables,
|
||||||
boost::program_options::options_description& description);
|
boost::program_options::options_description& description);
|
||||||
|
|
||||||
Files::Path<> mPath;
|
void setupTokensMapping();
|
||||||
|
|
||||||
|
FixedPathType mFixedPath;
|
||||||
|
|
||||||
boost::filesystem::path mOgreCfgPath;
|
boost::filesystem::path mOgreCfgPath;
|
||||||
boost::filesystem::path mPluginsCfgPath;
|
boost::filesystem::path mPluginsCfgPath;
|
||||||
boost::filesystem::path mLogPath;
|
boost::filesystem::path mLogPath;
|
||||||
|
|
||||||
|
TokensMappingContainer mTokensMapping;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace Cfg */
|
} /* namespace Cfg */
|
||||||
|
|
||||||
#endif /* COMPONENTS_CFG_CONFIGURATIONMANAGER_HPP */
|
#endif /* COMPONENTS_FILES_CONFIGURATIONMANAGER_HPP */
|
145
components/files/fixedpath.hpp
Normal file
145
components/files/fixedpath.hpp
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
/**
|
||||||
|
* Open Morrowind - an opensource Elder Scrolls III: Morrowind
|
||||||
|
* engine implementation.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Open Morrowind Team
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file components/files/fixedpath.hpp */
|
||||||
|
|
||||||
|
#ifndef COMPONENTS_FILES_FIXEDPATH_HPP
|
||||||
|
#define COMPONENTS_FILES_FIXEDPATH_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
#if defined(__linux__) || defined(__FreeBSD__)
|
||||||
|
#include <components/files/linuxpath.hpp>
|
||||||
|
namespace Files { typedef LinuxPath TargetPathType; }
|
||||||
|
|
||||||
|
#elif defined(__WIN32) || defined(__WINDOWS__)
|
||||||
|
#include <components/files/windowspath.hpp>
|
||||||
|
namespace Files { typedef WindowsPath TargetPathType; }
|
||||||
|
|
||||||
|
#elif defined(macintosh) || defined(Macintosh) || defined(__APPLE__) || defined(__MACH__)
|
||||||
|
#include <components/files/macospath.hpp>
|
||||||
|
namespace Files { typedef MacOsPath TargetPathType; }
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Unknown platform!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \namespace Files
|
||||||
|
*/
|
||||||
|
namespace Files
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \struct Path
|
||||||
|
*
|
||||||
|
* \tparam P - Path strategy class type (depends on target system)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
template
|
||||||
|
<
|
||||||
|
class P = TargetPathType
|
||||||
|
>
|
||||||
|
struct FixedPath
|
||||||
|
{
|
||||||
|
typedef P PathType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Path constructor.
|
||||||
|
*
|
||||||
|
* \param [in] application_name - Name of the application
|
||||||
|
*/
|
||||||
|
FixedPath(const std::string& application_name)
|
||||||
|
: mPath()
|
||||||
|
, mUserPath(mPath.getUserPath())
|
||||||
|
, mGlobalPath(mPath.getGlobalPath())
|
||||||
|
, mLocalPath(mPath.getLocalPath())
|
||||||
|
, mGlobalDataPath(mPath.getGlobalDataPath())
|
||||||
|
, mInstallPath(mPath.getInstallPath())
|
||||||
|
{
|
||||||
|
if (!application_name.empty())
|
||||||
|
{
|
||||||
|
boost::filesystem::path suffix(application_name + std::string("/"));
|
||||||
|
|
||||||
|
mUserPath /= suffix;
|
||||||
|
mGlobalPath /= suffix;
|
||||||
|
mGlobalDataPath /= suffix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return path pointing to the user local configuration directory.
|
||||||
|
*
|
||||||
|
* \return boost::filesystem::path
|
||||||
|
*/
|
||||||
|
const boost::filesystem::path& getUserPath() const
|
||||||
|
{
|
||||||
|
return mUserPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return path pointing to the global (system) configuration directory.
|
||||||
|
*
|
||||||
|
* \return boost::filesystem::path
|
||||||
|
*/
|
||||||
|
const boost::filesystem::path& getGlobalPath() const
|
||||||
|
{
|
||||||
|
return mGlobalPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return path pointing to the directory where application was started.
|
||||||
|
*
|
||||||
|
* \return boost::filesystem::path
|
||||||
|
*/
|
||||||
|
const boost::filesystem::path& getLocalPath() const
|
||||||
|
{
|
||||||
|
return mLocalPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& getInstallPath() const
|
||||||
|
{
|
||||||
|
return mInstallPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::filesystem::path& getGlobalDataPath() const
|
||||||
|
{
|
||||||
|
return mGlobalDataPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PathType mPath;
|
||||||
|
|
||||||
|
boost::filesystem::path mUserPath; /**< User path */
|
||||||
|
boost::filesystem::path mGlobalPath; /**< Global path */
|
||||||
|
boost::filesystem::path mLocalPath; /**< It is the same directory where application was run */
|
||||||
|
|
||||||
|
boost::filesystem::path mGlobalDataPath; /**< Global application data path */
|
||||||
|
|
||||||
|
boost::filesystem::path mInstallPath;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace Files */
|
||||||
|
|
||||||
|
#endif /* COMPONENTS_FILES_FIXEDPATH_HPP */
|
|
@ -22,12 +22,13 @@
|
||||||
|
|
||||||
#include "linuxpath.hpp"
|
#include "linuxpath.hpp"
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__) || defined(__FreeBSD__)
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <boost/filesystem/fstream.hpp>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \namespace Files
|
* \namespace Files
|
||||||
|
@ -35,126 +36,123 @@
|
||||||
namespace Files
|
namespace Files
|
||||||
{
|
{
|
||||||
|
|
||||||
boost::filesystem::path LinuxPath::getLocalConfigPath() const
|
boost::filesystem::path LinuxPath::getUserPath() const
|
||||||
{
|
{
|
||||||
boost::filesystem::path localConfigPath(".");
|
boost::filesystem::path userPath(".");
|
||||||
boost::filesystem::path suffix("/");
|
boost::filesystem::path suffix("/");
|
||||||
|
|
||||||
const char* theDir = getenv("OPENMW_CONFIG");
|
const char* theDir = getenv("HOME");
|
||||||
if (theDir == NULL)
|
if (theDir == NULL)
|
||||||
{
|
{
|
||||||
theDir = getenv("XDG_CONFIG_HOME");
|
struct passwd* pwd = getpwuid(getuid());
|
||||||
if (theDir == NULL)
|
if (pwd != NULL)
|
||||||
{
|
{
|
||||||
theDir = getenv("HOME");
|
theDir = pwd->pw_dir;
|
||||||
if (theDir == NULL)
|
|
||||||
{
|
|
||||||
struct passwd* pwd = getpwuid(getuid());
|
|
||||||
if (pwd != NULL)
|
|
||||||
{
|
|
||||||
theDir = pwd->pw_dir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (theDir != NULL)
|
|
||||||
{
|
|
||||||
suffix = boost::filesystem::path("/.config/");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theDir != NULL) {
|
|
||||||
localConfigPath = boost::filesystem::path(theDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
localConfigPath /= suffix;
|
|
||||||
|
|
||||||
return localConfigPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::filesystem::path LinuxPath::getGlobalConfigPath() const
|
|
||||||
{
|
|
||||||
boost::filesystem::path globalConfigPath("/etc/xdg/");
|
|
||||||
|
|
||||||
char* theDir = getenv("XDG_CONFIG_DIRS");
|
|
||||||
if (theDir != NULL)
|
if (theDir != NULL)
|
||||||
{
|
{
|
||||||
// We take only first path from list
|
suffix = boost::filesystem::path("/.config/");
|
||||||
char* ptr = strtok(theDir, ":");
|
userPath = boost::filesystem::path(theDir);
|
||||||
if (ptr != NULL)
|
|
||||||
{
|
|
||||||
globalConfigPath = boost::filesystem::path(ptr);
|
|
||||||
globalConfigPath /= boost::filesystem::path("/");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return globalConfigPath;
|
userPath /= suffix;
|
||||||
|
|
||||||
|
return userPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path LinuxPath::getRuntimeConfigPath() const
|
boost::filesystem::path LinuxPath::getGlobalPath() const
|
||||||
|
{
|
||||||
|
boost::filesystem::path globalPath("/etc/");
|
||||||
|
return globalPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::filesystem::path LinuxPath::getLocalPath() const
|
||||||
{
|
{
|
||||||
return boost::filesystem::path("./");
|
return boost::filesystem::path("./");
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path LinuxPath::getLocalDataPath() const
|
|
||||||
{
|
|
||||||
boost::filesystem::path localDataPath(".");
|
|
||||||
boost::filesystem::path suffix("/");
|
|
||||||
|
|
||||||
const char* theDir = getenv("OPENMW_DATA");
|
|
||||||
if (theDir == NULL)
|
|
||||||
{
|
|
||||||
theDir = getenv("XDG_DATA_HOME");
|
|
||||||
if (theDir == NULL)
|
|
||||||
{
|
|
||||||
theDir = getenv("HOME");
|
|
||||||
if (theDir == NULL)
|
|
||||||
{
|
|
||||||
struct passwd* pwd = getpwuid(getuid());
|
|
||||||
if (pwd != NULL)
|
|
||||||
{
|
|
||||||
theDir = pwd->pw_dir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (theDir != NULL)
|
|
||||||
{
|
|
||||||
suffix = boost::filesystem::path("/.local/share/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (theDir != NULL) {
|
|
||||||
localDataPath = boost::filesystem::path(theDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
localDataPath /= suffix;
|
|
||||||
return localDataPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::filesystem::path LinuxPath::getGlobalDataPath() const
|
boost::filesystem::path LinuxPath::getGlobalDataPath() const
|
||||||
{
|
{
|
||||||
boost::filesystem::path globalDataPath("/usr/local/share/");
|
boost::filesystem::path globalDataPath("/usr/share/games/");
|
||||||
|
|
||||||
char* theDir = getenv("XDG_DATA_DIRS");
|
|
||||||
if (theDir != NULL)
|
|
||||||
{
|
|
||||||
// We take only first path from list
|
|
||||||
char* ptr = strtok(theDir, ":");
|
|
||||||
if (ptr != NULL)
|
|
||||||
{
|
|
||||||
globalDataPath = boost::filesystem::path(ptr);
|
|
||||||
globalDataPath /= boost::filesystem::path("/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return globalDataPath;
|
return globalDataPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path LinuxPath::getRuntimeDataPath() const
|
boost::filesystem::path LinuxPath::getInstallPath() const
|
||||||
{
|
{
|
||||||
return boost::filesystem::path("./data/");
|
boost::filesystem::path installPath;
|
||||||
}
|
|
||||||
|
|
||||||
|
char *homePath = getenv("HOME");
|
||||||
|
if (homePath == NULL)
|
||||||
|
{
|
||||||
|
struct passwd* pwd = getpwuid(getuid());
|
||||||
|
if (pwd != NULL)
|
||||||
|
{
|
||||||
|
homePath = pwd->pw_dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (homePath != NULL)
|
||||||
|
{
|
||||||
|
boost::filesystem::path wineDefaultRegistry(homePath);
|
||||||
|
wineDefaultRegistry /= ".wine/system.reg";
|
||||||
|
|
||||||
|
if (boost::filesystem::is_regular_file(wineDefaultRegistry))
|
||||||
|
{
|
||||||
|
boost::filesystem::ifstream file(wineDefaultRegistry);
|
||||||
|
bool isRegEntry = false;
|
||||||
|
std::string line;
|
||||||
|
std::string mwpath;
|
||||||
|
|
||||||
|
while (std::getline(file, line) && !line.empty())
|
||||||
|
{
|
||||||
|
if (line[0] == '[') // we found an entry
|
||||||
|
{
|
||||||
|
isRegEntry = (line.find("Softworks\\Morrowind]") != std::string::npos);
|
||||||
|
}
|
||||||
|
else if (isRegEntry)
|
||||||
|
{
|
||||||
|
if (line[0] == '"') // empty line means new registry key
|
||||||
|
{
|
||||||
|
std::string key = line.substr(1, line.find('"', 1) - 1);
|
||||||
|
if (strcasecmp(key.c_str(), "Installed Path") == 0)
|
||||||
|
{
|
||||||
|
std::string::size_type valuePos = line.find('=') + 2;
|
||||||
|
mwpath = line.substr(valuePos, line.rfind('"') - valuePos);
|
||||||
|
|
||||||
|
std::string::size_type pos = mwpath.find("\\");
|
||||||
|
while (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
mwpath.replace(pos, 2, "/");
|
||||||
|
pos = mwpath.find("\\", pos + 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mwpath.empty())
|
||||||
|
{
|
||||||
|
// Change drive letter to lowercase, so we could use
|
||||||
|
// ~/.wine/dosdevices symlinks
|
||||||
|
mwpath[0] = tolower(mwpath[0]);
|
||||||
|
installPath /= homePath;
|
||||||
|
installPath /= ".wine/dosdevices/";
|
||||||
|
installPath /= mwpath;
|
||||||
|
|
||||||
|
if (!boost::filesystem::is_directory(installPath))
|
||||||
|
{
|
||||||
|
installPath.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return installPath;
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace Files */
|
} /* namespace Files */
|
||||||
|
|
||||||
#endif /* defined(__linux__) */
|
#endif /* defined(__linux__) || defined(__FreeBSD__) */
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#ifndef COMPONENTS_FILES_LINUXPATH_H
|
#ifndef COMPONENTS_FILES_LINUXPATH_H
|
||||||
#define COMPONENTS_FILES_LINUXPATH_H
|
#define COMPONENTS_FILES_LINUXPATH_H
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__) || defined(__FreeBSD__)
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
@ -39,18 +39,18 @@ namespace Files
|
||||||
struct LinuxPath
|
struct LinuxPath
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* \brief Return path to the local configuration directory.
|
* \brief Return path to the user directory.
|
||||||
*
|
*
|
||||||
* \return boost::filesystem::path
|
* \return boost::filesystem::path
|
||||||
*/
|
*/
|
||||||
boost::filesystem::path getLocalConfigPath() const;
|
boost::filesystem::path getUserPath() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Return path to the global (system) configuration directory.
|
* \brief Return path to the global (system) configuration directory.
|
||||||
*
|
*
|
||||||
* \return boost::filesystem::path
|
* \return boost::filesystem::path
|
||||||
*/
|
*/
|
||||||
boost::filesystem::path getGlobalConfigPath() const;
|
boost::filesystem::path getGlobalPath() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Return path to the runtime configuration directory which is the
|
* \brief Return path to the runtime configuration directory which is the
|
||||||
|
@ -58,33 +58,25 @@ struct LinuxPath
|
||||||
*
|
*
|
||||||
* \return boost::filesystem::path
|
* \return boost::filesystem::path
|
||||||
*/
|
*/
|
||||||
boost::filesystem::path getRuntimeConfigPath() const;
|
boost::filesystem::path getLocalPath() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Return path to the local data directory.
|
* \brief
|
||||||
*
|
|
||||||
* \return boost::filesystem::path
|
|
||||||
*/
|
|
||||||
boost::filesystem::path getLocalDataPath() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Return path to the global (system) data directory.
|
|
||||||
*
|
*
|
||||||
* \return boost::filesystem::path
|
* \return boost::filesystem::path
|
||||||
*/
|
*/
|
||||||
boost::filesystem::path getGlobalDataPath() const;
|
boost::filesystem::path getGlobalDataPath() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Return runtime data path which is a location where
|
* \brief Gets the path of the installed Morrowind version if there is one.
|
||||||
* an application was started with 'data' suffix.
|
|
||||||
*
|
*
|
||||||
* \return boost::filesystem::path
|
* \return boost::filesystem::path
|
||||||
*/
|
*/
|
||||||
boost::filesystem::path getRuntimeDataPath() const;
|
boost::filesystem::path getInstallPath() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace Files */
|
} /* namespace Files */
|
||||||
|
|
||||||
#endif /* defined(__linux__) */
|
#endif /* defined(__linux__) || defined(__FreeBSD__) */
|
||||||
|
|
||||||
#endif /* COMPONENTS_FILES_LINUXPATH_H */
|
#endif /* COMPONENTS_FILES_LINUXPATH_H */
|
||||||
|
|
|
@ -28,15 +28,19 @@
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME: Someone with MacOS system should check this and correct if necessary
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \namespace Files
|
* \namespace Files
|
||||||
*/
|
*/
|
||||||
namespace Files
|
namespace Files
|
||||||
{
|
{
|
||||||
|
|
||||||
boost::filesystem::path MacOsPath::getLocalConfigPath() const
|
boost::filesystem::path MacOsPath::getUserPath() const
|
||||||
{
|
{
|
||||||
boost::filesystem::path localConfigPath(".");
|
boost::filesystem::path userPath(".");
|
||||||
boost::filesystem::path suffix("/");
|
boost::filesystem::path suffix("/");
|
||||||
|
|
||||||
const char* theDir = getenv("HOME");
|
const char* theDir = getenv("HOME");
|
||||||
|
@ -50,66 +54,102 @@ boost::filesystem::path MacOsPath::getLocalConfigPath() const
|
||||||
}
|
}
|
||||||
if (theDir != NULL)
|
if (theDir != NULL)
|
||||||
{
|
{
|
||||||
localConfigPath = boost::filesystem::path(theDir) / "Library/Preferences/";
|
userPath = boost::filesystem::path(theDir) / "Library/Preferences/";
|
||||||
}
|
}
|
||||||
|
|
||||||
localConfigPath /= suffix;
|
userPath /= suffix;
|
||||||
|
|
||||||
return localConfigPath;
|
return userPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path MacOsPath::getGlobalConfigPath() const
|
boost::filesystem::path MacOsPath::getGlobalPath() const
|
||||||
{
|
{
|
||||||
boost::filesystem::path globalConfigPath("/Library/Preferences/");
|
boost::filesystem::path globalPath("/Library/Preferences/");
|
||||||
return globalConfigPath;
|
return globalPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path MacOsPath::getRuntimeConfigPath() const
|
boost::filesystem::path MacOsPath::getLocalPath() const
|
||||||
{
|
{
|
||||||
return boost::filesystem::path("./");
|
return boost::filesystem::path("./");
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path MacOsPath::getLocalDataPath() const
|
|
||||||
{
|
|
||||||
boost::filesystem::path localDataPath(".");
|
|
||||||
boost::filesystem::path suffix("/");
|
|
||||||
|
|
||||||
const char* theDir = getenv("OPENMW_DATA");
|
|
||||||
if (theDir == NULL)
|
|
||||||
{
|
|
||||||
theDir = getenv("HOME");
|
|
||||||
if (theDir == NULL)
|
|
||||||
{
|
|
||||||
struct passwd* pwd = getpwuid(getuid());
|
|
||||||
if (pwd != NULL)
|
|
||||||
{
|
|
||||||
theDir = pwd->pw_dir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (theDir != NULL)
|
|
||||||
{
|
|
||||||
suffix = boost::filesystem::path("/Library/Application Support/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (theDir != NULL)
|
|
||||||
{
|
|
||||||
localDataPath = boost::filesystem::path(theDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
localDataPath /= suffix;
|
|
||||||
return localDataPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::filesystem::path MacOsPath::getGlobalDataPath() const
|
boost::filesystem::path MacOsPath::getGlobalDataPath() const
|
||||||
{
|
{
|
||||||
boost::filesystem::path globalDataPath("/Library/Application Support/");
|
boost::filesystem::path globalDataPath("/Library/Application Support/");
|
||||||
return globalDataPath;
|
return globalDataPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path MacOsPath::getRuntimeDataPath() const
|
boost::filesystem::path MacOsPath::getInstallPath() const
|
||||||
{
|
{
|
||||||
return boost::filesystem::path("./data/");
|
boost::filesystem::path installPath;
|
||||||
|
|
||||||
|
char *homePath = getenv("HOME");
|
||||||
|
if (homePath == NULL)
|
||||||
|
{
|
||||||
|
struct passwd* pwd = getpwuid(getuid());
|
||||||
|
if (pwd != NULL)
|
||||||
|
{
|
||||||
|
homePath = pwd->pw_dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (homePath != NULL)
|
||||||
|
{
|
||||||
|
boost::filesystem::path wineDefaultRegistry(homePath);
|
||||||
|
wineDefaultRegistry /= ".wine/system.reg";
|
||||||
|
|
||||||
|
if (boost::filesystem::is_regular_file(wineDefaultRegistry))
|
||||||
|
{
|
||||||
|
boost::filesystem::ifstream file(wineDefaultRegistry);
|
||||||
|
bool isRegEntry = false;
|
||||||
|
std::string line;
|
||||||
|
std::string mwpath;
|
||||||
|
|
||||||
|
while (std::getline(file, line) && !line.empty())
|
||||||
|
{
|
||||||
|
if (line[0] == '[') // we found an entry
|
||||||
|
{
|
||||||
|
isRegEntry = (line.find("Softworks\\Morrowind]") != std::string::npos);
|
||||||
|
}
|
||||||
|
else if (isRegEntry)
|
||||||
|
{
|
||||||
|
if (line[0] == '"') // empty line means new registry key
|
||||||
|
{
|
||||||
|
std::string key = line.substr(1, line.find('"', 1) - 1);
|
||||||
|
if (strcasecmp(key.c_str(), "Installed Path") == 0)
|
||||||
|
{
|
||||||
|
std::string::size_type valuePos = line.find('=') + 2;
|
||||||
|
mwpath = line.substr(valuePos, line.rfind('"') - valuePos);
|
||||||
|
|
||||||
|
std::string::size_type pos = mwpath.find("\\");
|
||||||
|
while (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
mwpath.replace(pos, 2, "/");
|
||||||
|
pos = mwpath.find("\\", pos + 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mwpath.empty())
|
||||||
|
{
|
||||||
|
// Change drive letter to lowercase, so we could use ~/.wine/dosdevice symlinks
|
||||||
|
mwpath[0] = tolower(mwpath[0]);
|
||||||
|
installPath /= homePath;
|
||||||
|
installPath /= ".wine/dosdevices/";
|
||||||
|
installPath /= mwpath;
|
||||||
|
|
||||||
|
if (!boost::filesystem::is_directory(installPath))
|
||||||
|
{
|
||||||
|
installPath.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return installPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,14 +43,14 @@ struct MacOsPath
|
||||||
*
|
*
|
||||||
* \return boost::filesystem::path
|
* \return boost::filesystem::path
|
||||||
*/
|
*/
|
||||||
boost::filesystem::path getLocalConfigPath() const;
|
boost::filesystem::path getUserPath() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Return path to the global (system) configuration directory.
|
* \brief Return path to the global (system) configuration directory.
|
||||||
*
|
*
|
||||||
* \return boost::filesystem::path
|
* \return boost::filesystem::path
|
||||||
*/
|
*/
|
||||||
boost::filesystem::path getGlobalConfigPath() const;
|
boost::filesystem::path getGlobalPath() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Return path to the runtime configuration directory which is the
|
* \brief Return path to the runtime configuration directory which is the
|
||||||
|
@ -58,29 +58,16 @@ struct MacOsPath
|
||||||
*
|
*
|
||||||
* \return boost::filesystem::path
|
* \return boost::filesystem::path
|
||||||
*/
|
*/
|
||||||
boost::filesystem::path getRuntimeConfigPath() const;
|
boost::filesystem::path getLocalPath() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Return path to the local data directory.
|
* \brief
|
||||||
*
|
|
||||||
* \return boost::filesystem::path
|
|
||||||
*/
|
|
||||||
boost::filesystem::path getLocalDataPath() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Return path to the global (system) data directory.
|
|
||||||
*
|
*
|
||||||
* \return boost::filesystem::path
|
* \return boost::filesystem::path
|
||||||
*/
|
*/
|
||||||
boost::filesystem::path getGlobalDataPath() const;
|
boost::filesystem::path getGlobalDataPath() const;
|
||||||
|
|
||||||
/**
|
boost::filesystem::path getInstallPath() const;
|
||||||
* \brief Return runtime data path which is a location where
|
|
||||||
* an application was started with 'data' suffix.
|
|
||||||
*
|
|
||||||
* \return boost::filesystem::path
|
|
||||||
*/
|
|
||||||
boost::filesystem::path getRuntimeDataPath() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace Files */
|
} /* namespace Files */
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace Files
|
||||||
/// \param foldCase Ignore filename case
|
/// \param foldCase Ignore filename case
|
||||||
|
|
||||||
boost::filesystem::path getPath (const std::string& file) const;
|
boost::filesystem::path getPath (const std::string& file) const;
|
||||||
///< Return full path (including filename) of \æ file.
|
///< Return full path (including filename) of \a file.
|
||||||
///
|
///
|
||||||
/// If the file does not exist, an exception is thrown. \a file must include
|
/// If the file does not exist, an exception is thrown. \a file must include
|
||||||
/// the extension.
|
/// the extension.
|
||||||
|
|
|
@ -1,232 +0,0 @@
|
||||||
/**
|
|
||||||
* Open Morrowind - an opensource Elder Scrolls III: Morrowind
|
|
||||||
* engine implementation.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2011 Open Morrowind Team
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \file components/files/path.hpp */
|
|
||||||
|
|
||||||
#ifndef COMPONENTS_FILES_PATH_HPP
|
|
||||||
#define COMPONENTS_FILES_PATH_HPP
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <boost/filesystem.hpp>
|
|
||||||
|
|
||||||
#if defined(__linux__)
|
|
||||||
#include <components/files/linuxpath.hpp>
|
|
||||||
namespace Files { typedef LinuxPath TargetPathType; }
|
|
||||||
|
|
||||||
#elif defined(__WIN32) || defined(__WINDOWS__) || defined (_WINDOWS)
|
|
||||||
#include <components/files/windowspath.hpp>
|
|
||||||
namespace Files { typedef WindowsPath TargetPathType; }
|
|
||||||
|
|
||||||
#elif defined(macintosh) || defined(Macintosh) || defined(__APPLE__) || defined(__MACH__)
|
|
||||||
#include <components/files/macospath.hpp>
|
|
||||||
namespace Files { typedef MacOsPath TargetPathType; }
|
|
||||||
|
|
||||||
#else
|
|
||||||
#error "Unknown platform!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \namespace Files
|
|
||||||
*/
|
|
||||||
namespace Files
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \struct Path
|
|
||||||
*
|
|
||||||
* \tparam P - Path strategy class type (depends on target system)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
template
|
|
||||||
<
|
|
||||||
class P = TargetPathType
|
|
||||||
>
|
|
||||||
struct Path
|
|
||||||
{
|
|
||||||
typedef P PathType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Path constructor.
|
|
||||||
*
|
|
||||||
* \param [in] application_name - Name of the application
|
|
||||||
*/
|
|
||||||
Path(const std::string& application_name)
|
|
||||||
: mPath()
|
|
||||||
, mLocalConfigPath(mPath.getLocalConfigPath())
|
|
||||||
, mGlobalConfigPath(mPath.getGlobalConfigPath())
|
|
||||||
, mRuntimeConfigPath(mPath.getRuntimeConfigPath())
|
|
||||||
, mLocalDataPath(mPath.getLocalDataPath())
|
|
||||||
, mGlobalDataPath(mPath.getGlobalDataPath())
|
|
||||||
, mRuntimeDataPath(mPath.getRuntimeDataPath())
|
|
||||||
{
|
|
||||||
if (!application_name.empty())
|
|
||||||
{
|
|
||||||
boost::filesystem::path suffix(application_name + std::string("/"));
|
|
||||||
|
|
||||||
mLocalConfigPath /= suffix;
|
|
||||||
mGlobalConfigPath /= suffix;
|
|
||||||
|
|
||||||
mLocalDataPath /= suffix;
|
|
||||||
mGlobalDataPath /= suffix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Return path pointing to the user local configuration directory.
|
|
||||||
*
|
|
||||||
* \return boost::filesystem::path
|
|
||||||
*/
|
|
||||||
const boost::filesystem::path& getLocalConfigPath() const
|
|
||||||
{
|
|
||||||
return mLocalConfigPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Sets new local configuration path.
|
|
||||||
*
|
|
||||||
* \param [in] path - New path
|
|
||||||
*/
|
|
||||||
void setLocalConfigPath(const boost::filesystem::path& path)
|
|
||||||
{
|
|
||||||
mLocalConfigPath = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Return path pointing to the global (system) configuration directory.
|
|
||||||
*
|
|
||||||
* \return boost::filesystem::path
|
|
||||||
*/
|
|
||||||
const boost::filesystem::path& getGlobalConfigPath() const
|
|
||||||
{
|
|
||||||
return mGlobalConfigPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Sets new global configuration path.
|
|
||||||
*
|
|
||||||
* \param [in] path - New path
|
|
||||||
*/
|
|
||||||
void setGlobalConfigPath(const boost::filesystem::path& path)
|
|
||||||
{
|
|
||||||
mGlobalConfigPath = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Return path pointing to the directory where application was started.
|
|
||||||
*
|
|
||||||
* \return boost::filesystem::path
|
|
||||||
*/
|
|
||||||
const boost::filesystem::path& getRuntimeConfigPath() const
|
|
||||||
{
|
|
||||||
return mRuntimeConfigPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Sets new runtime configuration path.
|
|
||||||
*
|
|
||||||
* \param [in] path - New path
|
|
||||||
*/
|
|
||||||
void setRuntimeConfigPath(const boost::filesystem::path& path)
|
|
||||||
{
|
|
||||||
mRuntimeConfigPath = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Return path pointing to the user local data directory.
|
|
||||||
*
|
|
||||||
* \return boost::filesystem::path
|
|
||||||
*/
|
|
||||||
const boost::filesystem::path& getLocalDataPath() const
|
|
||||||
{
|
|
||||||
return mLocalDataPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Sets new local data path.
|
|
||||||
*
|
|
||||||
* \param [in] path - New path
|
|
||||||
*/
|
|
||||||
void setLocalDataPath(const boost::filesystem::path& path)
|
|
||||||
{
|
|
||||||
mLocalDataPath = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Return path pointing to the global (system) data directory.
|
|
||||||
*
|
|
||||||
* \return boost::filesystem::path
|
|
||||||
*/
|
|
||||||
const boost::filesystem::path& getGlobalDataPath() const
|
|
||||||
{
|
|
||||||
return mGlobalDataPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Sets new global (system) data directory.
|
|
||||||
*
|
|
||||||
* \param [in] path - New path
|
|
||||||
*/
|
|
||||||
void setGlobalDataPath(const boost::filesystem::path& path)
|
|
||||||
{
|
|
||||||
mGlobalDataPath = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Return path pointing to the directory where application was started.
|
|
||||||
*
|
|
||||||
* \return boost::filesystem::path
|
|
||||||
*/
|
|
||||||
const boost::filesystem::path& getRuntimeDataPath() const
|
|
||||||
{
|
|
||||||
return mRuntimeDataPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Sets new runtime data directory.
|
|
||||||
*
|
|
||||||
* \param [in] path - New path
|
|
||||||
*/
|
|
||||||
void setRuntimeDataPath(const boost::filesystem::path& path)
|
|
||||||
{
|
|
||||||
mRuntimeDataPath = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PathType mPath;
|
|
||||||
|
|
||||||
boost::filesystem::path mLocalConfigPath; /**< User local path to the configuration files */
|
|
||||||
boost::filesystem::path mGlobalConfigPath; /**< Global path to the configuration files */
|
|
||||||
boost::filesystem::path mRuntimeConfigPath; /**< Runtime path to the configuration files.
|
|
||||||
By default it is the same directory where
|
|
||||||
application was run */
|
|
||||||
|
|
||||||
boost::filesystem::path mLocalDataPath; /**< User local application data path (user plugins / mods / etc.) */
|
|
||||||
boost::filesystem::path mGlobalDataPath; /**< Global application data path */
|
|
||||||
boost::filesystem::path mRuntimeDataPath; /**< Runtime path to the configuration files.
|
|
||||||
By default it is a 'data' directory in same
|
|
||||||
directory where application was run */
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} /* namespace Files */
|
|
||||||
|
|
||||||
#endif /* COMPONENTS_FILES_PATH_HPP */
|
|
|
@ -10,12 +10,19 @@
|
||||||
|
|
||||||
#pragma comment(lib, "Shlwapi.lib")
|
#pragma comment(lib, "Shlwapi.lib")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME: Someone with Windows system should check this and correct if necessary
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \namespace Files
|
||||||
|
*/
|
||||||
namespace Files
|
namespace Files
|
||||||
{
|
{
|
||||||
|
|
||||||
boost::filesystem::path WindowsPath::getLocalConfigPath() const
|
boost::filesystem::path WindowsPath::getUserPath() const
|
||||||
{
|
{
|
||||||
boost::filesystem::path localConfigPath(".");
|
boost::filesystem::path userPath(".");
|
||||||
boost::filesystem::path suffix("/");
|
boost::filesystem::path suffix("/");
|
||||||
|
|
||||||
TCHAR path[MAX_PATH];
|
TCHAR path[MAX_PATH];
|
||||||
|
@ -24,17 +31,17 @@ boost::filesystem::path WindowsPath::getLocalConfigPath() const
|
||||||
if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, path)))
|
if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, path)))
|
||||||
{
|
{
|
||||||
PathAppend(path, TEXT("My Games"));
|
PathAppend(path, TEXT("My Games"));
|
||||||
localConfigPath = boost::filesystem::path(path);
|
userPath = boost::filesystem::path(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
localConfigPath /= suffix;
|
userPath /= suffix;
|
||||||
|
|
||||||
return localConfigPath;
|
return userPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path WindowsPath::getGlobalConfigPath() const
|
boost::filesystem::path WindowsPath::getGlobalPath() const
|
||||||
{
|
{
|
||||||
boost::filesystem::path globalConfigPath(".");
|
boost::filesystem::path globalPath(".");
|
||||||
boost::filesystem::path suffix("/");
|
boost::filesystem::path suffix("/");
|
||||||
|
|
||||||
TCHAR path[MAX_PATH];
|
TCHAR path[MAX_PATH];
|
||||||
|
@ -42,32 +49,54 @@ boost::filesystem::path WindowsPath::getGlobalConfigPath() const
|
||||||
|
|
||||||
if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES | CSIDL_FLAG_CREATE, NULL, 0, path)))
|
if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES | CSIDL_FLAG_CREATE, NULL, 0, path)))
|
||||||
{
|
{
|
||||||
globalConfigPath = boost::filesystem::path(path);
|
globalPath = boost::filesystem::path(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
globalConfigPath /= suffix;
|
globalPath /= suffix;
|
||||||
|
|
||||||
return globalConfigPath;
|
return globalPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path WindowsPath::getRuntimeConfigPath() const
|
boost::filesystem::path WindowsPath::getLocalPath() const
|
||||||
{
|
{
|
||||||
return boost::filesystem::path("./");
|
return boost::filesystem::path("./");
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path WindowsPath::getLocalDataPath() const
|
|
||||||
{
|
|
||||||
return getLocalConfigPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::filesystem::path WindowsPath::getGlobalDataPath() const
|
boost::filesystem::path WindowsPath::getGlobalDataPath() const
|
||||||
{
|
{
|
||||||
return getGlobalConfigPath();
|
return getGlobalConfigPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path WindowsPath::getRuntimeDataPath() const
|
boost::filesystem::path WindowsPath::getInstallPath() const
|
||||||
{
|
{
|
||||||
return boost::filesystem::path("./data/");
|
boost::filesystem::path installPath("");
|
||||||
|
|
||||||
|
HKEY hKey;
|
||||||
|
|
||||||
|
BOOL f64 = FALSE;
|
||||||
|
LPCTSTR regkey;
|
||||||
|
if (IsWow64Process(GetCurrentProcess(), &f64) && f64)
|
||||||
|
{
|
||||||
|
regkey = "SOFTWARE\\Wow6432Node\\Bethesda Softworks\\Morrowind";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regkey = "SOFTWARE\\Bethesda Softworks\\Morrowind";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(regkey), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
//Key existed, let's try to read the install dir
|
||||||
|
std::vector<char> buf(512);
|
||||||
|
int len = 512;
|
||||||
|
|
||||||
|
if (RegQueryValueEx(hKey, TEXT("Installed Path"), NULL, NULL, (LPBYTE)&buf[0], (LPDWORD)&len) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
installPath = &buf[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return installPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace Files */
|
} /* namespace Files */
|
||||||
|
|
|
@ -39,33 +39,27 @@ namespace Files
|
||||||
struct WindowsPath
|
struct WindowsPath
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* \brief Returns "X:\Documents And Settings\<User name>\My Documents\My Games\"
|
* \brief Returns user path i.e.:
|
||||||
|
* "X:\Documents And Settings\<User name>\My Documents\My Games\"
|
||||||
*
|
*
|
||||||
* \return boost::filesystem::path
|
* \return boost::filesystem::path
|
||||||
*/
|
*/
|
||||||
boost::filesystem::path getLocalConfigPath() const;
|
boost::filesystem::path getUserPath() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Returns "X:\Program Files\"
|
* \brief Returns "X:\Program Files\"
|
||||||
*
|
*
|
||||||
* \return boost::filesystem::path
|
* \return boost::filesystem::path
|
||||||
*/
|
*/
|
||||||
boost::filesystem::path getGlobalConfigPath() const;
|
boost::filesystem::path getGlobalPath() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Return runtime configuration path which is a location where
|
* \brief Return local path which is a location where
|
||||||
* an application was started
|
* an application was started
|
||||||
*
|
*
|
||||||
* \return boost::filesystem::path
|
* \return boost::filesystem::path
|
||||||
*/
|
*/
|
||||||
boost::filesystem::path getRuntimeConfigPath() const;
|
boost::filesystem::path getLocalPath() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Return same path like getLocalConfigPath
|
|
||||||
*
|
|
||||||
* \return boost::filesystem::path
|
|
||||||
*/
|
|
||||||
boost::filesystem::path getLocalDataPath() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Return same path like getGlobalConfigPath
|
* \brief Return same path like getGlobalConfigPath
|
||||||
|
@ -75,12 +69,11 @@ struct WindowsPath
|
||||||
boost::filesystem::path getGlobalDataPath() const;
|
boost::filesystem::path getGlobalDataPath() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Return runtime data path which is a location where
|
* \brief Gets the path of the installed Morrowind version if there is one.
|
||||||
* an application was started with 'data' suffix.
|
|
||||||
*
|
*
|
||||||
* \return boost::filesystem::path
|
* \return boost::filesystem::path
|
||||||
*/
|
*/
|
||||||
boost::filesystem::path getRuntimeDataPath() const;
|
boost::filesystem::path getInstallPath() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace Files */
|
} /* namespace Files */
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
data=${MORROWIND_DATA_FILES}
|
data="?mw?Data Files"
|
||||||
|
data="?global?data"
|
||||||
|
data="?local?data"
|
||||||
|
data-local="?user?data"
|
||||||
resources=${MORROWIND_RESOURCE_FILES}
|
resources=${MORROWIND_RESOURCE_FILES}
|
||||||
|
|
||||||
|
|
111
readme.txt
111
readme.txt
|
@ -3,7 +3,7 @@ OpenMW: A reimplementation of The Elder Scrolls III: Morrowind
|
||||||
OpenMW is an attempt at recreating the engine for the popular role-playing game
|
OpenMW is an attempt at recreating the engine for the popular role-playing game
|
||||||
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
|
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
|
||||||
|
|
||||||
Version: 0.11.1
|
Version: 0.12.0
|
||||||
License: GPL (see GPL3.txt for more information)
|
License: GPL (see GPL3.txt for more information)
|
||||||
Website: http://www.openmw.org
|
Website: http://www.openmw.org
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ THIS IS A WORK IN PROGRESS
|
||||||
INSTALLATION
|
INSTALLATION
|
||||||
|
|
||||||
Windows:
|
Windows:
|
||||||
Just unpack to a location of your choice. Currently there is no installer.
|
Run the installer.
|
||||||
|
|
||||||
Linux:
|
Linux:
|
||||||
Ubuntu (and most others)
|
Ubuntu (and most others)
|
||||||
|
@ -35,25 +35,87 @@ TODO add description here
|
||||||
|
|
||||||
THE DATA PATH
|
THE DATA PATH
|
||||||
|
|
||||||
After the installation OpenMW needs to be told where to find the Morrowind data directory. Create a text file named openmw.cfg (location depends on platform) and enter the following line:
|
The data path tells OpenMW where to find your Morrowind files. From 0.12.0 on OpenMW should be able to
|
||||||
|
pick up the location of these files on its own, if both Morrowind and OpenMW are installed properly
|
||||||
|
(installing Morrowind under WINE is considered a proper install).
|
||||||
|
|
||||||
|
If that does not work for you, please check if you have any leftover openmw.cfg files from versions earlier than 0.12.0. These can interfere with the configuration process, so try to remove then.
|
||||||
|
|
||||||
|
If you are running OpenMW without installing it, you still need to manually adjust the data path. Create a text file named openmw.cfg in the location of the binary and enter the following line:
|
||||||
|
|
||||||
data=path to your data directory
|
data=path to your data directory
|
||||||
|
|
||||||
(where you replace "path to your data directory" with the actual location of your data directory)
|
(where you replace "path to your data directory" with the actual location of your data directory)
|
||||||
|
|
||||||
On Windows a suitable location for the cfg file is alongside the binary. Currently the binary release comes with such a file pre-generated, but you still need to adjust the data setting.
|
|
||||||
|
|
||||||
On Linux and Mac the default location will be ~/.config/openmw/openmw.cfg.
|
|
||||||
|
|
||||||
|
|
||||||
COMMAND LINE OPTIONS
|
COMMAND LINE OPTIONS
|
||||||
TODO add description of command line options
|
|
||||||
|
Syntax: openmw <options>
|
||||||
|
Allowed options:
|
||||||
|
--help print help message
|
||||||
|
--version print version information and quit
|
||||||
|
--data arg (=data) set data directories (later directories have
|
||||||
|
higher priority)
|
||||||
|
--data-local arg set local data directory (highest priority)
|
||||||
|
--resources arg (=resources) set resources directory
|
||||||
|
--start arg (=Beshara) set initial cell
|
||||||
|
--master arg master file(s)
|
||||||
|
--plugin arg plugin file(s)
|
||||||
|
--fps [=arg(=1)] (=0) fps counter detail (0 = off, 1 = fps counter
|
||||||
|
, 2 = full detail)
|
||||||
|
--anim-verbose [=arg(=1)] (=0) output animation indices files
|
||||||
|
--debug [=arg(=1)] (=0) debug mode
|
||||||
|
--nosound [=arg(=1)] (=0) disable all sounds
|
||||||
|
--script-verbose [=arg(=1)] (=0) verbose script output
|
||||||
|
--new-game [=arg(=1)] (=0) activate char gen/new game mechanics
|
||||||
|
--script-all [=arg(=1)] (=0) compile all scripts (excluding dialogue scri
|
||||||
|
pts) at startup
|
||||||
|
--fs-strict [=arg(=1)] (=0) strict file system handling (no case folding
|
||||||
|
)
|
||||||
|
--encoding arg (=win1252) Character encoding used in OpenMW game messa
|
||||||
|
ges:
|
||||||
|
|
||||||
|
win1250 - Central and Eastern European such
|
||||||
|
as Polish, Czech, Slovak, Hungarian, Slovene
|
||||||
|
, Bosnian, Croatian, Serbian (Latin script),
|
||||||
|
Romanian and Albanian languages
|
||||||
|
|
||||||
|
win1251 - Cyrillic alphabet such as Russian,
|
||||||
|
Bulgarian, Serbian Cyrillic and other langua
|
||||||
|
ges
|
||||||
|
|
||||||
|
win1252 - Western European (Latin) alphabet,
|
||||||
|
used by default
|
||||||
|
--report-focus [=arg(=1)] (=0) write name of focussed object to cout
|
||||||
|
|
||||||
|
|
||||||
CREDITS
|
CREDITS
|
||||||
|
|
||||||
Developers:
|
Current Developers:
|
||||||
TODO add list of developers
|
Alexander “Ace” Olofsson
|
||||||
|
athile
|
||||||
|
Cris “Mirceam” Mihalache
|
||||||
|
gugus / gus
|
||||||
|
Jacob “Yacoby” Essex
|
||||||
|
Jason “jhooks” Hooks
|
||||||
|
Lukasz “lgro” Gromanowski
|
||||||
|
Marc “Zini” Zinnschlag
|
||||||
|
Nikolay “corristo” Kasyanov
|
||||||
|
Pieter “pvdk” van der Kloet
|
||||||
|
Sebastian “swick” Wick
|
||||||
|
|
||||||
|
Retired Developers:
|
||||||
|
Ardekantur
|
||||||
|
Armin Preiml
|
||||||
|
Diggory Hardy
|
||||||
|
Jan Borsodi
|
||||||
|
Jan-Peter “peppe” Nilsson
|
||||||
|
Josua Grawitter
|
||||||
|
Karl-Felix “k1ll” Glatzer
|
||||||
|
Nicolay Korslund
|
||||||
|
sergoz
|
||||||
|
Star-Demon
|
||||||
|
Yuri Krupenin
|
||||||
|
|
||||||
OpenMW:
|
OpenMW:
|
||||||
Thanks to DokterDume for kindly providing us with the Moon and Star logo used as the application icon and project logo.
|
Thanks to DokterDume for kindly providing us with the Moon and Star logo used as the application icon and project logo.
|
||||||
|
@ -64,6 +126,33 @@ Thanks to Kevin Ryan for kindly providing us with the icon used for the Data Fil
|
||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
0.12.0
|
||||||
|
|
||||||
|
Bug #154: FPS Drop
|
||||||
|
Bug #169: Local scripts continue running if associated object is deleted
|
||||||
|
Bug #174: OpenMW fails to start if the config directory doesn't exist
|
||||||
|
Bug #187: Missing lighting
|
||||||
|
Bug #188: Lights without a mesh are not rendered
|
||||||
|
Bug #191: Taking screenshot causes crash when running installed
|
||||||
|
Feature #28: Sort out the cell load problem
|
||||||
|
Feature #31: Allow the player to move away from pre-defined cells
|
||||||
|
Feature #35: Use alternate storage location for modified object position
|
||||||
|
Feature #45: NPC animations
|
||||||
|
Feature #46: Creature Animation
|
||||||
|
Feature #89: Basic Journal Window
|
||||||
|
Feature #110: Automatically pick up the path of existing MW-installations
|
||||||
|
Feature #133: Handle resources across multiple data directories
|
||||||
|
Feature #134: Generate a suitable default-value for --data-local
|
||||||
|
Feature #183: More FPS display settings
|
||||||
|
Task #19: Refactor engine class
|
||||||
|
Task #109/Feature #162: Automate Packaging
|
||||||
|
Task #112: Catch exceptions thrown in input handling functions
|
||||||
|
Task #128/#168: Cleanup Configuration File Handling
|
||||||
|
Task #131: NPC Activation doesn't work properly
|
||||||
|
Task #144: MWRender cleanup
|
||||||
|
Task #155: cmake cleanup
|
||||||
|
|
||||||
|
|
||||||
0.11.1
|
0.11.1
|
||||||
|
|
||||||
Bug #2: Resources loading doesn't work outside of bsa files
|
Bug #2: Resources loading doesn't work outside of bsa files
|
||||||
|
@ -90,4 +179,4 @@ Task #14: Replace tabs with 4 spaces
|
||||||
Task #18: Move components from global namespace into their own namespace
|
Task #18: Move components from global namespace into their own namespace
|
||||||
Task #123: refactor header files in components/esm
|
Task #123: refactor header files in components/esm
|
||||||
|
|
||||||
TODO add old changelog (take pre 0.11.0 changelog from wiki)
|
TODO add old changelog (take pre 0.11.1 changelog from wiki)
|
||||||
|
|
Loading…
Reference in a new issue