From ceb3317807876e95180f1371257fe14ac2a7d54a Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Sat, 17 Aug 2013 22:56:50 +0100 Subject: [PATCH 01/12] Integrate unshield with launcher --- CMakeLists.txt | 1 + apps/launcher/CMakeLists.txt | 14 +- apps/launcher/maindialog.cpp | 124 +++++++- apps/launcher/text_slot_msg_box.cpp | 6 + apps/launcher/text_slot_msg_box.hpp | 13 + apps/launcher/unshield_thread.cpp | 441 ++++++++++++++++++++++++++++ apps/launcher/unshield_thread.hpp | 55 ++++ 7 files changed, 648 insertions(+), 6 deletions(-) create mode 100644 apps/launcher/text_slot_msg_box.cpp create mode 100644 apps/launcher/text_slot_msg_box.hpp create mode 100644 apps/launcher/unshield_thread.cpp create mode 100644 apps/launcher/unshield_thread.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 575fecd0c..99a7e85a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -499,6 +499,7 @@ endif(WIN32) add_subdirectory (extern/shiny) add_subdirectory (extern/oics) add_subdirectory (extern/sdl4ogre) +add_subdirectory (extern/unshield) # Components add_subdirectory (components) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index bff26b63c..bfe932448 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -4,6 +4,8 @@ set(LAUNCHER main.cpp maindialog.cpp playpage.cpp + unshield_thread.cpp + text_slot_msg_box.cpp settings/gamesettings.cpp settings/graphicssettings.cpp @@ -20,6 +22,8 @@ set(LAUNCHER_HEADER graphicspage.hpp maindialog.hpp playpage.hpp + unshield_thread.hpp + text_slot_msg_box.hpp settings/gamesettings.hpp settings/graphicssettings.hpp @@ -37,6 +41,8 @@ set(LAUNCHER_HEADER_MOC graphicspage.hpp maindialog.hpp playpage.hpp + unshield_thread.hpp + text_slot_msg_box.hpp utils/checkablemessagebox.hpp utils/textinputdialog.hpp @@ -64,8 +70,11 @@ QT4_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/launcher/launcher.qrc) QT4_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC}) QT4_WRAP_UI(UI_HDRS ${LAUNCHER_UI}) + +message(STATUS "hello ${LIBUNSHIELD_INCLUDE}") + include(${QT_USE_FILE}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${LIBUNSHIELD_INCLUDE}) # Main executable IF(OGRE_STATIC) @@ -93,8 +102,11 @@ target_link_libraries(omwlauncher ${SDL2_LIBRARY} ${QT_LIBRARIES} components + libunshield ) + + if(DPKG_PROGRAM) INSTALL(TARGETS omwlauncher RUNTIME DESTINATION games COMPONENT omwlauncher) endif() diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index b75d09c51..e274a2896 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -11,6 +11,9 @@ #include +#include "unshield_thread.hpp" +#include "text_slot_msg_box.hpp" + #include "utils/checkablemessagebox.hpp" #include "playpage.hpp" @@ -128,11 +131,16 @@ bool MainDialog::showFirstRunDialog() QDir dir(path); dir.setPath(dir.canonicalPath()); // Resolve symlinks - if (!dir.cdUp()) - continue; // Cannot move from Data Files - if (dir.exists(QString("Morrowind.ini"))) iniPaths.append(dir.absoluteFilePath(QString("Morrowind.ini"))); + else + { + if (!dir.cdUp()) + continue; // Cannot move from Data Files + + if (dir.exists(QString("Morrowind.ini"))) + iniPaths.append(dir.absoluteFilePath(QString("Morrowind.ini"))); + } } // Ask the user where the Morrowind.ini is @@ -344,6 +352,76 @@ bool MainDialog::setupLauncherSettings() return true; } +bool expansions(UnshieldThread& cd) +{ + if(cd.BloodmoonDone()) + { + cd.Done(); + return false; + } + + QMessageBox expansionsBox; + expansionsBox.setText(QObject::tr("
Would you like to install expansions now ? (make sure you have the disc)
\ + If you want to install both Bloodmoon and Tribunal, you have to install Tribunal first.
")); + + QAbstractButton* tribunalButton = NULL; + if(!cd.TribunalDone()) + tribunalButton = expansionsBox.addButton(QObject::tr("&Tribunal"), QMessageBox::ActionRole); + + QAbstractButton* bloodmoonButton = expansionsBox.addButton(QObject::tr("&Bloodmoon"), QMessageBox::ActionRole); + QAbstractButton* noneButton = expansionsBox.addButton(QObject::tr("&None"), QMessageBox::ActionRole); + + expansionsBox.exec(); + + if(expansionsBox.clickedButton() == noneButton) + { + cd.Done(); + return false; + } + else if(expansionsBox.clickedButton() == tribunalButton) + { + + TextSlotMsgBox cdbox; + cdbox.setStandardButtons(QMessageBox::Cancel); + + QObject::connect(&cd,SIGNAL(signalGUI(const QString&)), &cdbox, SLOT(setTextSlot(const QString&))); + QObject::connect(&cd,SIGNAL(close()), &cdbox, SLOT(reject())); + + cd.SetTribunalPath( + QFileDialog::getOpenFileName( + NULL, + QObject::tr("Select data1.hdr from Tribunal Installation CD (Tribunal/data1.hdr on GOTY CDs)"), + QDir::currentPath(), + QString(QObject::tr("Installshield hdr file (*.hdr)"))).toUtf8().constData()); + + cd.start(); + cdbox.exec(); + } + else if(expansionsBox.clickedButton() == bloodmoonButton) + { + + TextSlotMsgBox cdbox; + cdbox.setStandardButtons(QMessageBox::Cancel); + + QObject::connect(&cd,SIGNAL(signalGUI(const QString&)), &cdbox, SLOT(setTextSlot(const QString&))); + QObject::connect(&cd,SIGNAL(close()), &cdbox, SLOT(reject())); + + cd.SetBloodmoonPath( + QFileDialog::getOpenFileName( + NULL, + QObject::tr("Select data1.hdr from Bloodmoon Installation CD (Bloodmoon/data1.hdr on GOTY CDs)"), + QDir::currentPath(), + QString(QObject::tr("Installshield hdr file (*.hdr)"))).toUtf8().constData()); + + cd.start(); + cdbox.exec(); + } + + + + return true; +} + bool MainDialog::setupGameSettings() { QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string()); @@ -401,9 +479,13 @@ bool MainDialog::setupGameSettings() Press \"Browse...\" to specify the location manually.
")); QAbstractButton *dirSelectButton = - msgBox.addButton(QObject::tr("B&rowse..."), QMessageBox::ActionRole); + msgBox.addButton(QObject::tr("Browse to &Install..."), QMessageBox::ActionRole); - msgBox.exec(); + QAbstractButton *cdSelectButton = + msgBox.addButton(QObject::tr("Browse to &CD..."), QMessageBox::ActionRole); + + + msgBox.exec(); QString selectedFile; if (msgBox.clickedButton() == dirSelectButton) { @@ -413,6 +495,38 @@ bool MainDialog::setupGameSettings() QDir::currentPath(), QString(tr("Morrowind master file (*.esm)"))); } + else if(msgBox.clickedButton() == cdSelectButton) { + UnshieldThread cd; + + { + TextSlotMsgBox cdbox; + cdbox.setStandardButtons(QMessageBox::Cancel); + + QObject::connect(&cd,SIGNAL(signalGUI(const QString&)), &cdbox, SLOT(setTextSlot(const QString&))); + QObject::connect(&cd,SIGNAL(close()), &cdbox, SLOT(reject())); + + cd.SetMorrowindPath( + QFileDialog::getOpenFileName( + NULL, + QObject::tr("Select data1.hdr from Morrowind Installation CD"), + QDir::currentPath(), + QString(tr("Installshield hdr file (*.hdr)"))).toUtf8().constData()); + + cd.SetOutputPath( + QFileDialog::getExistingDirectory( + NULL, + QObject::tr("Select where to extract files to"), + QDir::currentPath(), + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks).toUtf8().constData()); + + cd.start(); + cdbox.exec(); + } + + while(expansions(cd)); + + selectedFile = QString::fromStdString(cd.GetMWEsmPath()); + } if (selectedFile.isEmpty()) return false; // Cancel was clicked; diff --git a/apps/launcher/text_slot_msg_box.cpp b/apps/launcher/text_slot_msg_box.cpp new file mode 100644 index 000000000..25bd5d970 --- /dev/null +++ b/apps/launcher/text_slot_msg_box.cpp @@ -0,0 +1,6 @@ +#include "text_slot_msg_box.hpp" + +void TextSlotMsgBox::setTextSlot(const QString& string) +{ + setText(string); +} diff --git a/apps/launcher/text_slot_msg_box.hpp b/apps/launcher/text_slot_msg_box.hpp new file mode 100644 index 000000000..a29e2c354 --- /dev/null +++ b/apps/launcher/text_slot_msg_box.hpp @@ -0,0 +1,13 @@ +#ifndef TEXT_SLOT_MSG_BOX +#define TEXT_SLOT_MSG_BOX + +#include + +class TextSlotMsgBox : public QMessageBox +{ +Q_OBJECT + public slots: + void setTextSlot(const QString& string); +}; + +#endif diff --git a/apps/launcher/unshield_thread.cpp b/apps/launcher/unshield_thread.cpp new file mode 100644 index 000000000..f8166dba8 --- /dev/null +++ b/apps/launcher/unshield_thread.cpp @@ -0,0 +1,441 @@ +#include "unshield_thread.hpp" + +#include +#include + +namespace bfs = boost::filesystem; + + +typedef enum +{ + FORMAT_NEW, + FORMAT_OLD, + FORMAT_RAW +} FORMAT; + + +static bool make_sure_directory_exists(bfs::path directory) +{ + + if(!bfs::exists(directory)) + { + bfs::create_directories(directory); + } + + return bfs::exists(directory); +} + +void fill_path(bfs::path& path, const std::string& name) +{ + size_t start = 0; + + size_t i; + for(i = 0; i < name.length(); i++) + { + switch(name[i]) + { + case '\\': + path /= name.substr(start, i-start); + start = i+1; + break; + } + } + + path /= name.substr(start, i-start); +} + +bool UnshieldThread::extract_file(Unshield* unshield, bfs::path output_dir, const char* prefix, int index) +{ + bool success; + bfs::path dirname; + bfs::path filename; + int directory = unshield_file_directory(unshield, index); + + dirname = output_dir; + + if (prefix && prefix[0]) + dirname /= prefix; + + if (directory >= 0) + { + const char* tmp = unshield_directory_name(unshield, directory); + if (tmp && tmp[0]) + fill_path(dirname, tmp); + } + + make_sure_directory_exists(dirname); + + filename = dirname; + filename /= unshield_file_name(unshield, index); + + emit signalGUI(QString("Extracting: ") + QString(filename.c_str())); + + FORMAT format = FORMAT_NEW; + switch (format) + { + case FORMAT_NEW: + success = unshield_file_save(unshield, index, filename.c_str()); + break; + case FORMAT_OLD: + success = unshield_file_save_old(unshield, index, filename.c_str()); + break; + case FORMAT_RAW: + success = unshield_file_save_raw(unshield, index, filename.c_str()); + break; + } + + if (!success) + bfs::remove(filename); + + return success; +} + +void UnshieldThread::extract_cab(const bfs::path& cab, const bfs::path& output_dir, bool extract_ini) +{ + Unshield * unshield; + unshield = unshield_open_force_version(cab.c_str(), -1); + + int i; + for (i = 0; i < unshield_file_group_count(unshield); i++) + { + UnshieldFileGroup* file_group = unshield_file_group_get(unshield, i); + + for (size_t j = file_group->first_file; j <= file_group->last_file; j++) + { + if (unshield_file_is_valid(unshield, j)) + extract_file(unshield, output_dir, file_group->name, j); + } + } + unshield_close(unshield); +} + +std::string get_setting(const std::string& category, const std::string& setting, const std::string& inx) +{ + size_t start = inx.find(category); + start = inx.find(setting, start) + setting.length() + 3; + + size_t end = inx.find("!", start); + + return inx.substr(start, end-start); +} + +std::string read_to_string(const bfs::path& path) +{ + std::ifstream strstream(path.c_str(), std::ios::in | std::ios::binary); + std::string str; + + strstream.seekg(0, std::ios::end); + str.resize(strstream.tellg()); + strstream.seekg(0, std::ios::beg); + strstream.read(&str[0], str.size()); + strstream.close(); + + return str; +} + +void add_setting(const std::string& category, const std::string& setting, const std::string& val, std::string& ini) +{ + size_t loc; + loc = ini.find("[" + category + "]"); + + // If category is not found, create it + if(loc == std::string::npos) + { + loc = ini.size() + 2; + ini += ("\r\n[" + category + "]\r\n"); + } + + loc += category.length() +2 +2; + ini.insert(loc, setting + "=" + val + "\r\n"); +} + +void bloodmoon_fix_ini(std::string& ini, const bfs::path inxPath) +{ + std::string inx = read_to_string(inxPath); + + // Remove this one setting (the only one actually changed by bloodmoon, as opposed to just adding new ones) + size_t start = ini.find("[Weather Blight]"); + start = ini.find("Ambient Loop Sound ID", start); + size_t end = ini.find("\r\n", start) +2; + ini.erase(start, end-start); + + std::string category; + std::string setting; + + category = "General"; + { + setting = "Werewolf FOV"; add_setting(category, setting, get_setting(category, setting, inx), ini); + } + category = "Moons"; + { + setting = "Script Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + } + category = "Weather"; + { + setting = "Snow Ripples"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Ripple Radius"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Ripples Per Flake"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Ripple Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Ripple Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Gravity Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow High Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Low Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini); + } + category = "Weather Blight"; + { + setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini); + } + category = "Weather Snow"; + { + setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Diameter"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Height Min"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Height Max"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Entrance Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Max Snowflakes"; add_setting(category, setting, get_setting(category, setting, inx), ini); + } + category = "Weather Blizzard"; + { + setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Storm Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini); + } +} + + +void fix_ini(const bfs::path& output_dir, bfs::path cdPath, bool tribunal, bool bloodmoon) +{ + bfs::path ini_path = output_dir; + ini_path /= "Morrowind.ini"; + + std::string ini = read_to_string(ini_path.string()); + + if(tribunal) + { + add_setting("Game Files", "GameFile1", "Tribunal.esm", ini); + add_setting("Archives", "Archive 0", "Tribunal.bsa", ini); + } + if(bloodmoon) + { + bloodmoon_fix_ini(ini, cdPath / "setup.inx"); + add_setting("Game Files", "GameFile2", "Bloodmoon.esm", ini); + add_setting("Archives", "Archive 1", "Bloodmoon.bsa", ini); + } + + std::ofstream inistream(ini_path.c_str()); + inistream << ini; + inistream.close(); +} + +bool UnshieldThread::SetMorrowindPath(const std::string& path) +{ + mMorrowindPath = path; + return true; +} + +bool UnshieldThread::SetTribunalPath(const std::string& path) +{ + mTribunalPath = path; + return true; +} + +bool UnshieldThread::SetBloodmoonPath(const std::string& path) +{ + mBloodmoonPath = path; + return true; +} + +void UnshieldThread::SetOutputPath(const std::string& path) +{ + mOutputPath = path; +} + +void installToPath(const bfs::path& from, const bfs::path& to) +{ + make_sure_directory_exists(to); + + for ( bfs::directory_iterator end, dir(from); dir != end; ++dir ) + { + if(bfs::is_directory(dir->path())) + installToPath(dir->path(), to / dir->path().filename()); + else + bfs::rename(dir->path(), to / dir->path().filename()); + } +} + +bfs::path findFile(const bfs::path& in, std::string filename) +{ + for ( bfs::recursive_directory_iterator end, dir(in); dir != end; ++dir ) + { + if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename) + return dir->path(); + } + + return ""; +} + +bool contains(const bfs::path& in, std::string filename) +{ + for(bfs::directory_iterator end, dir(in); dir != end; ++dir) + { + if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename) + return true; + } + + return false; +} + +bool UnshieldThread::extract() +{ + bfs::path outputDataFilesDir = mOutputPath; + outputDataFilesDir /= "Data Files"; + bfs::path extractPath = mOutputPath; + extractPath /= "extract-temp"; + + if(!mMorrowindDone && mMorrowindPath.string().length() > 0) + { + mMorrowindDone = true; + + bfs::path mwExtractPath = extractPath / "morrowind"; + extract_cab(mMorrowindPath, mwExtractPath, true); + + bfs::path dFilesDir = findFile(mwExtractPath, "morrowind.esm").parent_path(); + + + installToPath(dFilesDir, outputDataFilesDir); + + bfs::rename(findFile(mwExtractPath, "morrowind.ini"), outputDataFilesDir / "Morrowind.ini"); + + mTribunalDone = contains(outputDataFilesDir, "tribunal.esm"); + mBloodmoonDone = contains(outputDataFilesDir, "bloodmoon.esm"); + + } + + else if(!mTribunalDone && mTribunalPath.string().length() > 0) + { + mTribunalDone = true; + + bfs::path tbExtractPath = extractPath / "tribunal"; + extract_cab(mTribunalPath, tbExtractPath, true); + + bfs::path dFilesDir = findFile(tbExtractPath, "tribunal.esm").parent_path(); + + installToPath(dFilesDir, outputDataFilesDir); + + mBloodmoonDone = contains(outputDataFilesDir, "bloodmoon.esm"); + + fix_ini(outputDataFilesDir, bfs::path(mTribunalPath).parent_path(), mTribunalDone, mBloodmoonDone); + } + + else if(!mBloodmoonDone && mBloodmoonPath.string().length() > 0) + { + mBloodmoonDone = true; + + bfs::path bmExtractPath = extractPath / "bloodmoon"; + extract_cab(mBloodmoonPath, bmExtractPath, true); + + bfs::path dFilesDir = findFile(bmExtractPath, "bloodmoon.esm").parent_path(); + + installToPath(dFilesDir, outputDataFilesDir); + + fix_ini(outputDataFilesDir, bfs::path(mBloodmoonPath).parent_path(), false, mBloodmoonDone); + } + + + return true; +} + +time_t getTime(const char* time) +{ + struct tm tms; + memset(&tms, 0, sizeof(struct tm)); + strptime(time, "%d %B %Y", &tms); + return mktime(&tms); +} + +void UnshieldThread::Done() +{ + // Get rid of unnecessary files + bfs::remove_all(mOutputPath / "extract-temp"); + + // Set modified time to release dates, to preserve load order + if(mMorrowindDone) + bfs::last_write_time(findFile(mOutputPath, "morrowind.esm"), getTime("1 May 2002")); + + if(mTribunalDone) + bfs::last_write_time(findFile(mOutputPath, "tribunal.esm"), getTime("6 November 2002")); + + if(mBloodmoonDone) + bfs::last_write_time(findFile(mOutputPath, "bloodmoon.esm"), getTime("3 June 2003")); +} + +std::string UnshieldThread::GetMWEsmPath() +{ + return findFile(mOutputPath / "Data Files", "morrowind.esm").string(); +} + +bool UnshieldThread::TribunalDone() +{ + return mTribunalDone; +} + +bool UnshieldThread::BloodmoonDone() +{ + return mBloodmoonDone; +} + +void UnshieldThread::run() +{ + extract(); + emit close(); +} diff --git a/apps/launcher/unshield_thread.hpp b/apps/launcher/unshield_thread.hpp new file mode 100644 index 000000000..0def3ab1d --- /dev/null +++ b/apps/launcher/unshield_thread.hpp @@ -0,0 +1,55 @@ +#ifndef UNSHIELD_THREAD_H +#define UNSHIELD_THREAD_H + +#include + +#include + +#include + + +class UnshieldThread : public QThread +{ + Q_OBJECT + + public: + bool SetMorrowindPath(const std::string& path); + bool SetTribunalPath(const std::string& path); + bool SetBloodmoonPath(const std::string& path); + + void SetOutputPath(const std::string& path); + + bool extract(); + + bool TribunalDone(); + bool BloodmoonDone(); + + void Done(); + + std::string GetMWEsmPath(); + + private: + + void extract_cab(const boost::filesystem::path& cab, const boost::filesystem::path& output_dir, bool extract_ini = false); + bool extract_file(Unshield* unshield, boost::filesystem::path output_dir, const char* prefix, int index); + + boost::filesystem::path mMorrowindPath; + boost::filesystem::path mTribunalPath; + boost::filesystem::path mBloodmoonPath; + + bool mMorrowindDone = false; + bool mTribunalDone = false; + bool mBloodmoonDone = false; + + boost::filesystem::path mOutputPath; + + + protected: + virtual void run(); + + signals: + void signalGUI(QString); + void close(); +}; + +#endif From 90a892d3041eb0727794395776101ceaff42a0e5 Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Sun, 18 Aug 2013 00:16:20 +0100 Subject: [PATCH 02/12] unshield fixes --- apps/launcher/unshield_thread.cpp | 48 ++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/apps/launcher/unshield_thread.cpp b/apps/launcher/unshield_thread.cpp index f8166dba8..57ba849dc 100644 --- a/apps/launcher/unshield_thread.cpp +++ b/apps/launcher/unshield_thread.cpp @@ -300,7 +300,7 @@ void UnshieldThread::SetOutputPath(const std::string& path) mOutputPath = path; } -void installToPath(const bfs::path& from, const bfs::path& to) +void installToPath(const bfs::path& from, const bfs::path& to, bool copy = false) { make_sure_directory_exists(to); @@ -309,16 +309,32 @@ void installToPath(const bfs::path& from, const bfs::path& to) if(bfs::is_directory(dir->path())) installToPath(dir->path(), to / dir->path().filename()); else - bfs::rename(dir->path(), to / dir->path().filename()); + { + if(!copy) + bfs::rename(dir->path(), to / dir->path().filename()); + else + bfs::copy_file(dir->path(), to / dir->path().filename()); + } } } -bfs::path findFile(const bfs::path& in, std::string filename) +bfs::path findFile(const bfs::path& in, std::string filename, bool recursive = true) { - for ( bfs::recursive_directory_iterator end, dir(in); dir != end; ++dir ) + if(recursive) { - if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename) - return dir->path(); + for ( bfs::recursive_directory_iterator end, dir(in); dir != end; ++dir ) + { + if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename) + return dir->path(); + } + } + else + { + for ( bfs::recursive_directory_iterator end, dir(in); dir != end; ++dir ) + { + if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename) + return dir->path(); + } } return ""; @@ -350,10 +366,17 @@ bool UnshieldThread::extract() extract_cab(mMorrowindPath, mwExtractPath, true); bfs::path dFilesDir = findFile(mwExtractPath, "morrowind.esm").parent_path(); - installToPath(dFilesDir, outputDataFilesDir); + // Videos are often kept uncompressed on the cd + bfs::path videosPath = findFile(mMorrowindPath.parent_path(), "video", false); + if(videosPath.string() != "") + { + emit signalGUI(QString("Installing Videos...")); + installToPath(videosPath, outputDataFilesDir / "Video", true); + } + bfs::rename(findFile(mwExtractPath, "morrowind.ini"), outputDataFilesDir / "Morrowind.ini"); mTribunalDone = contains(outputDataFilesDir, "tribunal.esm"); @@ -371,6 +394,11 @@ bool UnshieldThread::extract() bfs::path dFilesDir = findFile(tbExtractPath, "tribunal.esm").parent_path(); installToPath(dFilesDir, outputDataFilesDir); + + // Mt GOTY CD has Sounds in a seperate folder from the rest of the data files + bfs::path soundsPath = findFile(tbExtractPath, "sounds", false); + if(soundsPath.string() != "") + installToPath(soundsPath, outputDataFilesDir / "Sounds"); mBloodmoonDone = contains(outputDataFilesDir, "bloodmoon.esm"); @@ -387,6 +415,12 @@ bool UnshieldThread::extract() bfs::path dFilesDir = findFile(bmExtractPath, "bloodmoon.esm").parent_path(); installToPath(dFilesDir, outputDataFilesDir); + + // My GOTY CD contains a folder within cab files called Tribunal patch, + // which contains Tribunal.esm + bfs::path tbPatchPath = findFile(bmExtractPath, "tribunal.esm"); + if(tbPatchPath.string() != "") + bfs::rename(tbPatchPath, outputDataFilesDir / "Tribunal.esm"); fix_ini(outputDataFilesDir, bfs::path(mBloodmoonPath).parent_path(), false, mBloodmoonDone); } From 3264b5974e6a6060fb95b67aac00984ca879bc21 Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Sun, 18 Aug 2013 00:29:46 +0100 Subject: [PATCH 03/12] fix invalid syntax --- apps/launcher/unshield_thread.cpp | 7 +++++++ apps/launcher/unshield_thread.hpp | 8 +++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/apps/launcher/unshield_thread.cpp b/apps/launcher/unshield_thread.cpp index 57ba849dc..34b6a6d46 100644 --- a/apps/launcher/unshield_thread.cpp +++ b/apps/launcher/unshield_thread.cpp @@ -473,3 +473,10 @@ void UnshieldThread::run() extract(); emit close(); } + +UnshieldThread::UnshieldThread() +{ + mMorrowindDone = false; + mTribunalDone = false; + mBloodmoonDone = false; +} diff --git a/apps/launcher/unshield_thread.hpp b/apps/launcher/unshield_thread.hpp index 0def3ab1d..b48d3d987 100644 --- a/apps/launcher/unshield_thread.hpp +++ b/apps/launcher/unshield_thread.hpp @@ -28,6 +28,8 @@ class UnshieldThread : public QThread std::string GetMWEsmPath(); + UnshieldThread(); + private: void extract_cab(const boost::filesystem::path& cab, const boost::filesystem::path& output_dir, bool extract_ini = false); @@ -37,9 +39,9 @@ class UnshieldThread : public QThread boost::filesystem::path mTribunalPath; boost::filesystem::path mBloodmoonPath; - bool mMorrowindDone = false; - bool mTribunalDone = false; - bool mBloodmoonDone = false; + bool mMorrowindDone; + bool mTribunalDone; + bool mBloodmoonDone; boost::filesystem::path mOutputPath; From 454b64974d56cb5aaa7b70cbc73de00219521287 Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Sun, 18 Aug 2013 12:11:39 +0100 Subject: [PATCH 04/12] filenames --- apps/launcher/CMakeLists.txt | 12 ++++++------ apps/launcher/maindialog.cpp | 4 ++-- .../{text_slot_msg_box.cpp => textslotmsgbox.cpp} | 2 +- .../{text_slot_msg_box.hpp => textslotmsgbox.hpp} | 0 .../{unshield_thread.cpp => unshieldthread.cpp} | 2 +- .../{unshield_thread.hpp => unshieldthread.hpp} | 0 6 files changed, 10 insertions(+), 10 deletions(-) rename apps/launcher/{text_slot_msg_box.cpp => textslotmsgbox.cpp} (71%) rename apps/launcher/{text_slot_msg_box.hpp => textslotmsgbox.hpp} (100%) rename apps/launcher/{unshield_thread.cpp => unshieldthread.cpp} (99%) rename apps/launcher/{unshield_thread.hpp => unshieldthread.hpp} (100%) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index bfe932448..e11b713bc 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -4,8 +4,8 @@ set(LAUNCHER main.cpp maindialog.cpp playpage.cpp - unshield_thread.cpp - text_slot_msg_box.cpp + unshieldthread.cpp + textslotmsgbox.cpp settings/gamesettings.cpp settings/graphicssettings.cpp @@ -22,8 +22,8 @@ set(LAUNCHER_HEADER graphicspage.hpp maindialog.hpp playpage.hpp - unshield_thread.hpp - text_slot_msg_box.hpp + unshieldthread.hpp + textslotmsgbox.hpp settings/gamesettings.hpp settings/graphicssettings.hpp @@ -41,8 +41,8 @@ set(LAUNCHER_HEADER_MOC graphicspage.hpp maindialog.hpp playpage.hpp - unshield_thread.hpp - text_slot_msg_box.hpp + unshieldthread.hpp + textslotmsgbox.hpp utils/checkablemessagebox.hpp utils/textinputdialog.hpp diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index e274a2896..857a15196 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -11,8 +11,8 @@ #include -#include "unshield_thread.hpp" -#include "text_slot_msg_box.hpp" +#include "unshieldthread.hpp" +#include "textslotmsgbox.hpp" #include "utils/checkablemessagebox.hpp" diff --git a/apps/launcher/text_slot_msg_box.cpp b/apps/launcher/textslotmsgbox.cpp similarity index 71% rename from apps/launcher/text_slot_msg_box.cpp rename to apps/launcher/textslotmsgbox.cpp index 25bd5d970..0607d1cc6 100644 --- a/apps/launcher/text_slot_msg_box.cpp +++ b/apps/launcher/textslotmsgbox.cpp @@ -1,4 +1,4 @@ -#include "text_slot_msg_box.hpp" +#include "textslotmsgbox.hpp" void TextSlotMsgBox::setTextSlot(const QString& string) { diff --git a/apps/launcher/text_slot_msg_box.hpp b/apps/launcher/textslotmsgbox.hpp similarity index 100% rename from apps/launcher/text_slot_msg_box.hpp rename to apps/launcher/textslotmsgbox.hpp diff --git a/apps/launcher/unshield_thread.cpp b/apps/launcher/unshieldthread.cpp similarity index 99% rename from apps/launcher/unshield_thread.cpp rename to apps/launcher/unshieldthread.cpp index 34b6a6d46..203302388 100644 --- a/apps/launcher/unshield_thread.cpp +++ b/apps/launcher/unshieldthread.cpp @@ -1,4 +1,4 @@ -#include "unshield_thread.hpp" +#include "unshieldthread.hpp" #include #include diff --git a/apps/launcher/unshield_thread.hpp b/apps/launcher/unshieldthread.hpp similarity index 100% rename from apps/launcher/unshield_thread.hpp rename to apps/launcher/unshieldthread.hpp From 641b7b0336ff95f56493883d424f132bbdb56072 Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Sun, 18 Aug 2013 12:23:09 +0100 Subject: [PATCH 05/12] anonymous namespace --- apps/launcher/unshieldthread.cpp | 547 ++++++++++++++++--------------- 1 file changed, 275 insertions(+), 272 deletions(-) diff --git a/apps/launcher/unshieldthread.cpp b/apps/launcher/unshieldthread.cpp index 203302388..10470dab9 100644 --- a/apps/launcher/unshieldthread.cpp +++ b/apps/launcher/unshieldthread.cpp @@ -5,276 +5,272 @@ namespace bfs = boost::filesystem; +namespace +{ + typedef enum + { + FORMAT_NEW, + FORMAT_OLD, + FORMAT_RAW + } FORMAT; -typedef enum -{ - FORMAT_NEW, - FORMAT_OLD, - FORMAT_RAW -} FORMAT; + static bool make_sure_directory_exists(bfs::path directory) + { -static bool make_sure_directory_exists(bfs::path directory) -{ + if(!bfs::exists(directory)) + { + bfs::create_directories(directory); + } - if(!bfs::exists(directory)) - { - bfs::create_directories(directory); + return bfs::exists(directory); } - return bfs::exists(directory); -} - -void fill_path(bfs::path& path, const std::string& name) -{ - size_t start = 0; - - size_t i; - for(i = 0; i < name.length(); i++) + void fill_path(bfs::path& path, const std::string& name) { - switch(name[i]) + size_t start = 0; + + size_t i; + for(i = 0; i < name.length(); i++) { - case '\\': - path /= name.substr(start, i-start); - start = i+1; - break; + switch(name[i]) + { + case '\\': + path /= name.substr(start, i-start); + start = i+1; + break; + } } - } - path /= name.substr(start, i-start); -} - -bool UnshieldThread::extract_file(Unshield* unshield, bfs::path output_dir, const char* prefix, int index) -{ - bool success; - bfs::path dirname; - bfs::path filename; - int directory = unshield_file_directory(unshield, index); - - dirname = output_dir; - - if (prefix && prefix[0]) - dirname /= prefix; + path /= name.substr(start, i-start); + } - if (directory >= 0) + std::string get_setting(const std::string& category, const std::string& setting, const std::string& inx) { - const char* tmp = unshield_directory_name(unshield, directory); - if (tmp && tmp[0]) - fill_path(dirname, tmp); - } + size_t start = inx.find(category); + start = inx.find(setting, start) + setting.length() + 3; - make_sure_directory_exists(dirname); + size_t end = inx.find("!", start); - filename = dirname; - filename /= unshield_file_name(unshield, index); - - emit signalGUI(QString("Extracting: ") + QString(filename.c_str())); - - FORMAT format = FORMAT_NEW; - switch (format) - { - case FORMAT_NEW: - success = unshield_file_save(unshield, index, filename.c_str()); - break; - case FORMAT_OLD: - success = unshield_file_save_old(unshield, index, filename.c_str()); - break; - case FORMAT_RAW: - success = unshield_file_save_raw(unshield, index, filename.c_str()); - break; + return inx.substr(start, end-start); } - if (!success) - bfs::remove(filename); + std::string read_to_string(const bfs::path& path) + { + std::ifstream strstream(path.c_str(), std::ios::in | std::ios::binary); + std::string str; - return success; -} + strstream.seekg(0, std::ios::end); + str.resize(strstream.tellg()); + strstream.seekg(0, std::ios::beg); + strstream.read(&str[0], str.size()); + strstream.close(); -void UnshieldThread::extract_cab(const bfs::path& cab, const bfs::path& output_dir, bool extract_ini) -{ - Unshield * unshield; - unshield = unshield_open_force_version(cab.c_str(), -1); - - int i; - for (i = 0; i < unshield_file_group_count(unshield); i++) - { - UnshieldFileGroup* file_group = unshield_file_group_get(unshield, i); + return str; + } - for (size_t j = file_group->first_file; j <= file_group->last_file; j++) + void add_setting(const std::string& category, const std::string& setting, const std::string& val, std::string& ini) + { + size_t loc; + loc = ini.find("[" + category + "]"); + + // If category is not found, create it + if(loc == std::string::npos) { - if (unshield_file_is_valid(unshield, j)) - extract_file(unshield, output_dir, file_group->name, j); + loc = ini.size() + 2; + ini += ("\r\n[" + category + "]\r\n"); } + + loc += category.length() +2 +2; + ini.insert(loc, setting + "=" + val + "\r\n"); } - unshield_close(unshield); -} -std::string get_setting(const std::string& category, const std::string& setting, const std::string& inx) -{ - size_t start = inx.find(category); - start = inx.find(setting, start) + setting.length() + 3; + void bloodmoon_fix_ini(std::string& ini, const bfs::path inxPath) + { + std::string inx = read_to_string(inxPath); - size_t end = inx.find("!", start); + // Remove this one setting (the only one actually changed by bloodmoon, as opposed to just adding new ones) + size_t start = ini.find("[Weather Blight]"); + start = ini.find("Ambient Loop Sound ID", start); + size_t end = ini.find("\r\n", start) +2; + ini.erase(start, end-start); - return inx.substr(start, end-start); -} + std::string category; + std::string setting; -std::string read_to_string(const bfs::path& path) -{ - std::ifstream strstream(path.c_str(), std::ios::in | std::ios::binary); - std::string str; - - strstream.seekg(0, std::ios::end); - str.resize(strstream.tellg()); - strstream.seekg(0, std::ios::beg); - strstream.read(&str[0], str.size()); - strstream.close(); + category = "General"; + { + setting = "Werewolf FOV"; add_setting(category, setting, get_setting(category, setting, inx), ini); + } + category = "Moons"; + { + setting = "Script Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + } + category = "Weather"; + { + setting = "Snow Ripples"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Ripple Radius"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Ripples Per Flake"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Ripple Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Ripple Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Gravity Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow High Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Low Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini); + } + category = "Weather Blight"; + { + setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini); + } + category = "Weather Snow"; + { + setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Diameter"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Height Min"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Height Max"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Snow Entrance Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Max Snowflakes"; add_setting(category, setting, get_setting(category, setting, inx), ini); + } + category = "Weather Blizzard"; + { + setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini); + setting = "Storm Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini); + } + } - return str; -} -void add_setting(const std::string& category, const std::string& setting, const std::string& val, std::string& ini) -{ - size_t loc; - loc = ini.find("[" + category + "]"); - - // If category is not found, create it - if(loc == std::string::npos) + void fix_ini(const bfs::path& output_dir, bfs::path cdPath, bool tribunal, bool bloodmoon) { - loc = ini.size() + 2; - ini += ("\r\n[" + category + "]\r\n"); - } - - loc += category.length() +2 +2; - ini.insert(loc, setting + "=" + val + "\r\n"); -} - -void bloodmoon_fix_ini(std::string& ini, const bfs::path inxPath) -{ - std::string inx = read_to_string(inxPath); + bfs::path ini_path = output_dir; + ini_path /= "Morrowind.ini"; - // Remove this one setting (the only one actually changed by bloodmoon, as opposed to just adding new ones) - size_t start = ini.find("[Weather Blight]"); - start = ini.find("Ambient Loop Sound ID", start); - size_t end = ini.find("\r\n", start) +2; - ini.erase(start, end-start); + std::string ini = read_to_string(ini_path.string()); - std::string category; - std::string setting; + if(tribunal) + { + add_setting("Game Files", "GameFile1", "Tribunal.esm", ini); + add_setting("Archives", "Archive 0", "Tribunal.bsa", ini); + } + if(bloodmoon) + { + bloodmoon_fix_ini(ini, cdPath / "setup.inx"); + add_setting("Game Files", "GameFile2", "Bloodmoon.esm", ini); + add_setting("Archives", "Archive 1", "Bloodmoon.bsa", ini); + } - category = "General"; - { - setting = "Werewolf FOV"; add_setting(category, setting, get_setting(category, setting, inx), ini); + std::ofstream inistream(ini_path.c_str()); + inistream << ini; + inistream.close(); } - category = "Moons"; - { - setting = "Script Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - } - category = "Weather"; - { - setting = "Snow Ripples"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Ripple Radius"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Ripples Per Flake"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Ripple Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Ripple Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Gravity Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow High Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Low Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini); - } - category = "Weather Blight"; - { - setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini); - } - category = "Weather Snow"; - { - setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Diameter"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Height Min"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Height Max"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Snow Entrance Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Max Snowflakes"; add_setting(category, setting, get_setting(category, setting, inx), ini); - } - category = "Weather Blizzard"; + + void installToPath(const bfs::path& from, const bfs::path& to, bool copy = false) { - setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini); - setting = "Storm Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini); - } -} + make_sure_directory_exists(to); + for ( bfs::directory_iterator end, dir(from); dir != end; ++dir ) + { + if(bfs::is_directory(dir->path())) + installToPath(dir->path(), to / dir->path().filename()); + else + { + if(!copy) + bfs::rename(dir->path(), to / dir->path().filename()); + else + bfs::copy_file(dir->path(), to / dir->path().filename()); + } + } + } -void fix_ini(const bfs::path& output_dir, bfs::path cdPath, bool tribunal, bool bloodmoon) -{ - bfs::path ini_path = output_dir; - ini_path /= "Morrowind.ini"; + bfs::path findFile(const bfs::path& in, std::string filename, bool recursive = true) + { + if(recursive) + { + for ( bfs::recursive_directory_iterator end, dir(in); dir != end; ++dir ) + { + if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename) + return dir->path(); + } + } + else + { + for ( bfs::recursive_directory_iterator end, dir(in); dir != end; ++dir ) + { + if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename) + return dir->path(); + } + } - std::string ini = read_to_string(ini_path.string()); + return ""; + } - if(tribunal) + bool contains(const bfs::path& in, std::string filename) { - add_setting("Game Files", "GameFile1", "Tribunal.esm", ini); - add_setting("Archives", "Archive 0", "Tribunal.bsa", ini); + for(bfs::directory_iterator end, dir(in); dir != end; ++dir) + { + if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename) + return true; + } + + return false; } - if(bloodmoon) + + time_t getTime(const char* time) { - bloodmoon_fix_ini(ini, cdPath / "setup.inx"); - add_setting("Game Files", "GameFile2", "Bloodmoon.esm", ini); - add_setting("Archives", "Archive 1", "Bloodmoon.bsa", ini); + struct tm tms; + memset(&tms, 0, sizeof(struct tm)); + strptime(time, "%d %B %Y", &tms); + return mktime(&tms); } - - std::ofstream inistream(ini_path.c_str()); - inistream << ini; - inistream.close(); } bool UnshieldThread::SetMorrowindPath(const std::string& path) @@ -300,57 +296,72 @@ void UnshieldThread::SetOutputPath(const std::string& path) mOutputPath = path; } -void installToPath(const bfs::path& from, const bfs::path& to, bool copy = false) +bool UnshieldThread::extract_file(Unshield* unshield, bfs::path output_dir, const char* prefix, int index) { - make_sure_directory_exists(to); + bool success; + bfs::path dirname; + bfs::path filename; + int directory = unshield_file_directory(unshield, index); - for ( bfs::directory_iterator end, dir(from); dir != end; ++dir ) - { - if(bfs::is_directory(dir->path())) - installToPath(dir->path(), to / dir->path().filename()); - else - { - if(!copy) - bfs::rename(dir->path(), to / dir->path().filename()); - else - bfs::copy_file(dir->path(), to / dir->path().filename()); - } - } -} + dirname = output_dir; -bfs::path findFile(const bfs::path& in, std::string filename, bool recursive = true) -{ - if(recursive) + if (prefix && prefix[0]) + dirname /= prefix; + + if (directory >= 0) { - for ( bfs::recursive_directory_iterator end, dir(in); dir != end; ++dir ) - { - if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename) - return dir->path(); - } + const char* tmp = unshield_directory_name(unshield, directory); + if (tmp && tmp[0]) + fill_path(dirname, tmp); } - else + + make_sure_directory_exists(dirname); + + filename = dirname; + filename /= unshield_file_name(unshield, index); + + emit signalGUI(QString("Extracting: ") + QString(filename.c_str())); + + FORMAT format = FORMAT_NEW; + switch (format) { - for ( bfs::recursive_directory_iterator end, dir(in); dir != end; ++dir ) - { - if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename) - return dir->path(); - } + case FORMAT_NEW: + success = unshield_file_save(unshield, index, filename.c_str()); + break; + case FORMAT_OLD: + success = unshield_file_save_old(unshield, index, filename.c_str()); + break; + case FORMAT_RAW: + success = unshield_file_save_raw(unshield, index, filename.c_str()); + break; } - return ""; + if (!success) + bfs::remove(filename); + + return success; } -bool contains(const bfs::path& in, std::string filename) +void UnshieldThread::extract_cab(const bfs::path& cab, const bfs::path& output_dir, bool extract_ini) { - for(bfs::directory_iterator end, dir(in); dir != end; ++dir) + Unshield * unshield; + unshield = unshield_open_force_version(cab.c_str(), -1); + + int i; + for (i = 0; i < unshield_file_group_count(unshield); i++) { - if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename) - return true; - } + UnshieldFileGroup* file_group = unshield_file_group_get(unshield, i); - return false; + for (size_t j = file_group->first_file; j <= file_group->last_file; j++) + { + if (unshield_file_is_valid(unshield, j)) + extract_file(unshield, output_dir, file_group->name, j); + } + } + unshield_close(unshield); } + bool UnshieldThread::extract() { bfs::path outputDataFilesDir = mOutputPath; @@ -429,14 +440,6 @@ bool UnshieldThread::extract() return true; } -time_t getTime(const char* time) -{ - struct tm tms; - memset(&tms, 0, sizeof(struct tm)); - strptime(time, "%d %B %Y", &tms); - return mktime(&tms); -} - void UnshieldThread::Done() { // Get rid of unnecessary files From 9d1daf7dc2e9be1d6375abf931aafe63d01de9f2 Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Sun, 18 Aug 2013 12:29:12 +0100 Subject: [PATCH 06/12] enum was unnecessary --- apps/launcher/unshieldthread.cpp | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/apps/launcher/unshieldthread.cpp b/apps/launcher/unshieldthread.cpp index 10470dab9..4ccb6b04e 100644 --- a/apps/launcher/unshieldthread.cpp +++ b/apps/launcher/unshieldthread.cpp @@ -7,14 +7,6 @@ namespace bfs = boost::filesystem; namespace { - typedef enum - { - FORMAT_NEW, - FORMAT_OLD, - FORMAT_RAW - } FORMAT; - - static bool make_sure_directory_exists(bfs::path directory) { @@ -322,19 +314,7 @@ bool UnshieldThread::extract_file(Unshield* unshield, bfs::path output_dir, cons emit signalGUI(QString("Extracting: ") + QString(filename.c_str())); - FORMAT format = FORMAT_NEW; - switch (format) - { - case FORMAT_NEW: - success = unshield_file_save(unshield, index, filename.c_str()); - break; - case FORMAT_OLD: - success = unshield_file_save_old(unshield, index, filename.c_str()); - break; - case FORMAT_RAW: - success = unshield_file_save_raw(unshield, index, filename.c_str()); - break; - } + success = unshield_file_save(unshield, index, filename.c_str()); if (!success) bfs::remove(filename); From d3748cd5bb8b8c7be40ca2d843346fff5ee587c1 Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Sun, 18 Aug 2013 12:46:10 +0100 Subject: [PATCH 07/12] Install uncompressed data files from cd --- apps/launcher/unshieldthread.cpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/apps/launcher/unshieldthread.cpp b/apps/launcher/unshieldthread.cpp index 4ccb6b04e..5a9475d96 100644 --- a/apps/launcher/unshieldthread.cpp +++ b/apps/launcher/unshieldthread.cpp @@ -212,13 +212,13 @@ namespace for ( bfs::directory_iterator end, dir(from); dir != end; ++dir ) { if(bfs::is_directory(dir->path())) - installToPath(dir->path(), to / dir->path().filename()); + installToPath(dir->path(), to / dir->path().filename(), copy); else { - if(!copy) - bfs::rename(dir->path(), to / dir->path().filename()); - else + if(copy) bfs::copy_file(dir->path(), to / dir->path().filename()); + else + bfs::rename(dir->path(), to / dir->path().filename()); } } } @@ -235,7 +235,7 @@ namespace } else { - for ( bfs::recursive_directory_iterator end, dir(in); dir != end; ++dir ) + for ( bfs::directory_iterator end, dir(in); dir != end; ++dir ) { if(Misc::StringUtils::lowerCase(dir->path().filename().string()) == filename) return dir->path(); @@ -368,6 +368,14 @@ bool UnshieldThread::extract() installToPath(videosPath, outputDataFilesDir / "Video", true); } + bfs::path cdDFiles = findFile(mMorrowindPath.parent_path(), "data files", false); + if(cdDFiles.string() != "") + { + emit signalGUI(QString("Installing Uncompressed Data files from CD...")); + installToPath(cdDFiles, outputDataFilesDir, true); + } + + bfs::rename(findFile(mwExtractPath, "morrowind.ini"), outputDataFilesDir / "Morrowind.ini"); mTribunalDone = contains(outputDataFilesDir, "tribunal.esm"); @@ -391,6 +399,13 @@ bool UnshieldThread::extract() if(soundsPath.string() != "") installToPath(soundsPath, outputDataFilesDir / "Sounds"); + bfs::path cdDFiles = findFile(mTribunalPath.parent_path(), "data files", false); + if(cdDFiles.string() != "") + { + emit signalGUI(QString("Installing Uncompressed Data files from CD...")); + installToPath(cdDFiles, outputDataFilesDir, true); + } + mBloodmoonDone = contains(outputDataFilesDir, "bloodmoon.esm"); fix_ini(outputDataFilesDir, bfs::path(mTribunalPath).parent_path(), mTribunalDone, mBloodmoonDone); @@ -412,6 +427,13 @@ bool UnshieldThread::extract() bfs::path tbPatchPath = findFile(bmExtractPath, "tribunal.esm"); if(tbPatchPath.string() != "") bfs::rename(tbPatchPath, outputDataFilesDir / "Tribunal.esm"); + + bfs::path cdDFiles = findFile(mBloodmoonPath.parent_path(), "data files", false); + if(cdDFiles.string() != "") + { + emit signalGUI(QString("Installing Uncompressed Data files from CD...")); + installToPath(cdDFiles, outputDataFilesDir, true); + } fix_ini(outputDataFilesDir, bfs::path(mBloodmoonPath).parent_path(), false, mBloodmoonDone); } From 865a7c63df278214f2585804374089ad126da271 Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Mon, 19 Aug 2013 19:59:58 +0100 Subject: [PATCH 08/12] cmake for system libunshield --- CMakeLists.txt | 8 +++++- apps/launcher/CMakeLists.txt | 4 +-- cmake/FindLibUnshield.cmake | 48 ++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 cmake/FindLibUnshield.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 99a7e85a4..148a56d3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -499,7 +499,6 @@ endif(WIN32) add_subdirectory (extern/shiny) add_subdirectory (extern/oics) add_subdirectory (extern/sdl4ogre) -add_subdirectory (extern/unshield) # Components add_subdirectory (components) @@ -516,6 +515,13 @@ if (BUILD_ESMTOOL) endif() if (BUILD_LAUNCHER) + if(NOT WIN32) + find_package(LIBUNSHIELD REQUIRED) + if(NOT LIBUNSHIELD_FOUND) + message(SEND_ERROR "Failed to find libunshield") + endif(NOT LIBUNSHIELD_FOUND) + endif(NOT WIN32) + add_subdirectory( apps/launcher ) endif() diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index e11b713bc..9b812e4ba 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -71,8 +71,6 @@ QT4_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC}) QT4_WRAP_UI(UI_HDRS ${LAUNCHER_UI}) -message(STATUS "hello ${LIBUNSHIELD_INCLUDE}") - include(${QT_USE_FILE}) include_directories(${CMAKE_CURRENT_BINARY_DIR} ${LIBUNSHIELD_INCLUDE}) @@ -102,7 +100,7 @@ target_link_libraries(omwlauncher ${SDL2_LIBRARY} ${QT_LIBRARIES} components - libunshield + ${LIBUNSHIELD_LIBRARY} ) diff --git a/cmake/FindLibUnshield.cmake b/cmake/FindLibUnshield.cmake new file mode 100644 index 000000000..4f4e98a1c --- /dev/null +++ b/cmake/FindLibUnshield.cmake @@ -0,0 +1,48 @@ +# Locate LIBUNSHIELD +# This module defines +# LIBUNSHIELD_LIBRARY +# LIBUNSHIELD_FOUND, if false, do not try to link to LibUnshield +# LIBUNSHIELD_INCLUDE_DIR, where to find the headers +# +# Created by Tom Mason (wheybags) for OpenMW (http://openmw.com), based on FindMPG123.cmake +# +# Ripped off from other sources. In fact, this file is so generic (I +# just did a search and replace on another file) that I wonder why the +# CMake guys haven't wrapped this entire thing in a single +# function. Do we really need to repeat this stuff for every single +# library when they all work the same? + +FIND_PATH(LIBUNSHIELD_INCLUDE_DIR libunshield.h + HINTS + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt + /usr/include +) + +FIND_LIBRARY(LIBUNSHIELD_LIBRARY + unshield + HINTS +# PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64 + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw + /opt/local + /opt/csw + /opt + /usr/lib +) + +IF(LIBUNSHIELD_LIBRARY AND LIBUNSHIELD_INCLUDE_DIR) + SET(LIBUNSHIELD_FOUND "YES") +ENDIF(LIBUNSHIELD_LIBRARY AND LIBUNSHIELD_INCLUDE_DIR) + From 06ff40eda731a657658c5ba930fd514f36aaf94f Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Mon, 19 Aug 2013 20:11:52 +0100 Subject: [PATCH 09/12] only use unshield on not windows --- apps/launcher/CMakeLists.txt | 24 +++++++++++++++++++++--- apps/launcher/maindialog.cpp | 17 +++++++++++++---- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 9b812e4ba..5908deb90 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -4,7 +4,6 @@ set(LAUNCHER main.cpp maindialog.cpp playpage.cpp - unshieldthread.cpp textslotmsgbox.cpp settings/gamesettings.cpp @@ -16,6 +15,9 @@ set(LAUNCHER ${CMAKE_SOURCE_DIR}/files/launcher/launcher.rc ) +if(NOT WIN32) + LIST(APPEND LAUNCHER unshieldthread.cpp) +endif(NOT WIN32) set(LAUNCHER_HEADER datafilespage.hpp @@ -34,6 +36,10 @@ set(LAUNCHER_HEADER utils/textinputdialog.hpp ) +if(NOT WIN32) + LIST(APPEND LAUNCHER_HEADER unshieldthread.hpp) +endif(NOT WIN32) + # Headers that must be pre-processed set(LAUNCHER_HEADER_MOC @@ -48,6 +54,11 @@ set(LAUNCHER_HEADER_MOC utils/textinputdialog.hpp ) +if(NOT WIN32) + LIST(APPEND LAUNCHER_HEADER_MOC unshieldthread.hpp) +endif(NOT WIN32) + + set(LAUNCHER_UI ${CMAKE_SOURCE_DIR}/files/ui/datafilespage.ui ${CMAKE_SOURCE_DIR}/files/ui/graphicspage.ui @@ -72,7 +83,10 @@ QT4_WRAP_UI(UI_HDRS ${LAUNCHER_UI}) include(${QT_USE_FILE}) -include_directories(${CMAKE_CURRENT_BINARY_DIR} ${LIBUNSHIELD_INCLUDE}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +if(NOT WIN32) + include_directories(${LIBUNSHIELD_INCLUDE}) +endif(NOT WIN32) # Main executable IF(OGRE_STATIC) @@ -100,8 +114,12 @@ target_link_libraries(omwlauncher ${SDL2_LIBRARY} ${QT_LIBRARIES} components - ${LIBUNSHIELD_LIBRARY} ) +if(NOT WIN32) + target_link_libraries(omwlauncher + ${LIBUNSHIELD_LIBRARY} + ) +endif(NOT WIN32) diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 857a15196..032f70916 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -11,7 +11,10 @@ #include -#include "unshieldthread.hpp" +#ifndef WIN32 + #include "unshieldthread.hpp" +#endif + #include "textslotmsgbox.hpp" #include "utils/checkablemessagebox.hpp" @@ -352,6 +355,7 @@ bool MainDialog::setupLauncherSettings() return true; } +#ifndef WIN32 bool expansions(UnshieldThread& cd) { if(cd.BloodmoonDone()) @@ -421,6 +425,7 @@ bool expansions(UnshieldThread& cd) return true; } +#endif // WIN32 bool MainDialog::setupGameSettings() { @@ -480,9 +485,11 @@ bool MainDialog::setupGameSettings() QAbstractButton *dirSelectButton = msgBox.addButton(QObject::tr("Browse to &Install..."), QMessageBox::ActionRole); - - QAbstractButton *cdSelectButton = - msgBox.addButton(QObject::tr("Browse to &CD..."), QMessageBox::ActionRole); + + #ifndef WIN32 + QAbstractButton *cdSelectButton = + msgBox.addButton(QObject::tr("Browse to &CD..."), QMessageBox::ActionRole); + #endif msgBox.exec(); @@ -495,6 +502,7 @@ bool MainDialog::setupGameSettings() QDir::currentPath(), QString(tr("Morrowind master file (*.esm)"))); } + #ifndef WIN32 else if(msgBox.clickedButton() == cdSelectButton) { UnshieldThread cd; @@ -527,6 +535,7 @@ bool MainDialog::setupGameSettings() selectedFile = QString::fromStdString(cd.GetMWEsmPath()); } + #endif // WIN32 if (selectedFile.isEmpty()) return false; // Cancel was clicked; From 603ce4105474f0ae4864bed8d6e25538d53a67a9 Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Mon, 19 Aug 2013 20:32:19 +0100 Subject: [PATCH 10/12] added libunshield to travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5c69f49f0..caf2e3389 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ before_install: - sudo apt-get install -qq libqt4-dev libxaw7-dev libxrandr-dev libfreeimage-dev libpng-dev - sudo apt-get install -qq libopenal-dev libmpg123-dev libsndfile1-dev - sudo apt-get install -qq libavcodec-dev libavformat-dev libavdevice-dev libavutil-dev libswscale-dev libpostproc-dev - - sudo apt-get install -qq libbullet-dev libogre-static-dev libmygui-static-dev libsdl2-static-dev + - sudo apt-get install -qq libbullet-dev libogre-static-dev libmygui-static-dev libsdl2-static-dev libunshield-dev - sudo mkdir /usr/src/gtest/build - cd /usr/src/gtest/build - sudo cmake .. -DBUILD_SHARED_LIBS=1 From 8d232aca35c679ae48b4402b77462aed51a131c7 Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Mon, 19 Aug 2013 20:48:20 +0100 Subject: [PATCH 11/12] changed libunshield filename to satisfy travis --- cmake/{FindLibUnshield.cmake => FindLIBUNSHIELD.cmake} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cmake/{FindLibUnshield.cmake => FindLIBUNSHIELD.cmake} (100%) diff --git a/cmake/FindLibUnshield.cmake b/cmake/FindLIBUNSHIELD.cmake similarity index 100% rename from cmake/FindLibUnshield.cmake rename to cmake/FindLIBUNSHIELD.cmake From 7f0f9037be06db17016813dc4ff52962d73937c4 Mon Sep 17 00:00:00 2001 From: Tom Mason Date: Mon, 19 Aug 2013 22:57:21 +0100 Subject: [PATCH 12/12] fix for older versions of unshield --- apps/launcher/unshieldthread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/launcher/unshieldthread.cpp b/apps/launcher/unshieldthread.cpp index 5a9475d96..ab9d984e1 100644 --- a/apps/launcher/unshieldthread.cpp +++ b/apps/launcher/unshieldthread.cpp @@ -325,7 +325,7 @@ bool UnshieldThread::extract_file(Unshield* unshield, bfs::path output_dir, cons void UnshieldThread::extract_cab(const bfs::path& cab, const bfs::path& output_dir, bool extract_ini) { Unshield * unshield; - unshield = unshield_open_force_version(cab.c_str(), -1); + unshield = unshield_open(cab.c_str()); int i; for (i = 0; i < unshield_file_group_count(unshield); i++)