From 2ee84a20fe898bfc4639adf5d67d883e88b2a20c Mon Sep 17 00:00:00 2001 From: Anthony Serna Date: Tue, 5 Jan 2016 19:36:16 -0600 Subject: [PATCH] [UI] Remove DolphinQt --- Source/Core/CMakeLists.txt | 3 - Source/Core/DolphinQt/AboutDialog.cpp | 38 -- Source/Core/DolphinQt/AboutDialog.h | 26 -- Source/Core/DolphinQt/AboutDialog.ui | 151 ------- Source/Core/DolphinQt/CMakeLists.txt | 88 ---- Source/Core/DolphinQt/DolphinQt.vcxproj | 189 --------- .../Core/DolphinQt/DolphinQt.vcxproj.filters | 109 ----- Source/Core/DolphinQt/DolphinQt.vcxproj.user | 10 - Source/Core/DolphinQt/GameList/GameFile.cpp | 393 ------------------ Source/Core/DolphinQt/GameList/GameFile.h | 95 ----- Source/Core/DolphinQt/GameList/GameGrid.cpp | 95 ----- Source/Core/DolphinQt/GameList/GameGrid.h | 44 -- Source/Core/DolphinQt/GameList/GameGrid.ui | 25 -- .../Core/DolphinQt/GameList/GameTracker.cpp | 240 ----------- Source/Core/DolphinQt/GameList/GameTracker.h | 68 --- Source/Core/DolphinQt/GameList/GameTree.cpp | 167 -------- Source/Core/DolphinQt/GameList/GameTree.h | 62 --- Source/Core/DolphinQt/GameList/GameTree.ui | 54 --- Source/Core/DolphinQt/Host.cpp | 102 ----- Source/Core/DolphinQt/Host.h | 19 - Source/Core/DolphinQt/Info.plist.in | 80 ---- Source/Core/DolphinQt/Main.cpp | 65 --- Source/Core/DolphinQt/MainWindow.cpp | 379 ----------------- Source/Core/DolphinQt/MainWindow.h | 77 ---- Source/Core/DolphinQt/MainWindow.ui | 253 ----------- Source/Core/DolphinQt/Resources/Dolphin.icns | Bin 103023 -> 0 bytes Source/Core/DolphinQt/SystemInfo.cpp | 109 ----- Source/Core/DolphinQt/SystemInfo.h | 31 -- Source/Core/DolphinQt/SystemInfo.ui | 71 ---- Source/Core/DolphinQt/Utils/Resources.cpp | 121 ------ Source/Core/DolphinQt/Utils/Resources.h | 54 --- Source/Core/DolphinQt/Utils/Utils.cpp | 28 -- Source/Core/DolphinQt/Utils/Utils.h | 11 - .../DolphinQt/VideoInterface/RenderWidget.cpp | 27 -- .../DolphinQt/VideoInterface/RenderWidget.h | 25 -- Source/dolphin-emu.sln | 2 - 36 files changed, 3311 deletions(-) delete mode 100644 Source/Core/DolphinQt/AboutDialog.cpp delete mode 100644 Source/Core/DolphinQt/AboutDialog.h delete mode 100644 Source/Core/DolphinQt/AboutDialog.ui delete mode 100644 Source/Core/DolphinQt/CMakeLists.txt delete mode 100644 Source/Core/DolphinQt/DolphinQt.vcxproj delete mode 100644 Source/Core/DolphinQt/DolphinQt.vcxproj.filters delete mode 100644 Source/Core/DolphinQt/DolphinQt.vcxproj.user delete mode 100644 Source/Core/DolphinQt/GameList/GameFile.cpp delete mode 100644 Source/Core/DolphinQt/GameList/GameFile.h delete mode 100644 Source/Core/DolphinQt/GameList/GameGrid.cpp delete mode 100644 Source/Core/DolphinQt/GameList/GameGrid.h delete mode 100644 Source/Core/DolphinQt/GameList/GameGrid.ui delete mode 100644 Source/Core/DolphinQt/GameList/GameTracker.cpp delete mode 100644 Source/Core/DolphinQt/GameList/GameTracker.h delete mode 100644 Source/Core/DolphinQt/GameList/GameTree.cpp delete mode 100644 Source/Core/DolphinQt/GameList/GameTree.h delete mode 100644 Source/Core/DolphinQt/GameList/GameTree.ui delete mode 100644 Source/Core/DolphinQt/Host.cpp delete mode 100644 Source/Core/DolphinQt/Host.h delete mode 100644 Source/Core/DolphinQt/Info.plist.in delete mode 100644 Source/Core/DolphinQt/Main.cpp delete mode 100644 Source/Core/DolphinQt/MainWindow.cpp delete mode 100644 Source/Core/DolphinQt/MainWindow.h delete mode 100644 Source/Core/DolphinQt/MainWindow.ui delete mode 100644 Source/Core/DolphinQt/Resources/Dolphin.icns delete mode 100644 Source/Core/DolphinQt/SystemInfo.cpp delete mode 100644 Source/Core/DolphinQt/SystemInfo.h delete mode 100644 Source/Core/DolphinQt/SystemInfo.ui delete mode 100644 Source/Core/DolphinQt/Utils/Resources.cpp delete mode 100644 Source/Core/DolphinQt/Utils/Resources.h delete mode 100644 Source/Core/DolphinQt/Utils/Utils.cpp delete mode 100644 Source/Core/DolphinQt/Utils/Utils.h delete mode 100644 Source/Core/DolphinQt/VideoInterface/RenderWidget.cpp delete mode 100644 Source/Core/DolphinQt/VideoInterface/RenderWidget.h diff --git a/Source/Core/CMakeLists.txt b/Source/Core/CMakeLists.txt index 8da95c59a9..efc04e1f43 100644 --- a/Source/Core/CMakeLists.txt +++ b/Source/Core/CMakeLists.txt @@ -8,9 +8,6 @@ add_subdirectory(UICommon) add_subdirectory(VideoCommon) add_subdirectory(VideoBackends) -if(ENABLE_QT) - add_subdirectory(DolphinQt) -endif() if(ENABLE_QT2) add_subdirectory(DolphinQt2) endif() diff --git a/Source/Core/DolphinQt/AboutDialog.cpp b/Source/Core/DolphinQt/AboutDialog.cpp deleted file mode 100644 index 3ef7f91b48..0000000000 --- a/Source/Core/DolphinQt/AboutDialog.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include -#include -#include - -#include "ui_AboutDialog.h" - -#include "Common/Common.h" - -#include "DolphinQt/AboutDialog.h" -#include "DolphinQt/Utils/Resources.h" - -DAboutDialog::DAboutDialog(QWidget* parent_widget) - : QDialog(parent_widget) -{ - setWindowModality(Qt::WindowModal); - setAttribute(Qt::WA_DeleteOnClose); - setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); - - m_ui = std::make_unique(); - m_ui->setupUi(this); - m_ui->lblGitRev->setText(QString::fromUtf8(scm_desc_str)); - m_ui->lblGitInfo->setText(m_ui->lblGitInfo->text().arg(QString::fromUtf8(scm_branch_str), - QString::fromUtf8(scm_rev_git_str))); - m_ui->lblFinePrint->setText(m_ui->lblFinePrint->text().arg(QStringLiteral("2015"))); - m_ui->lblLicenseAuthorsSupport->setText(m_ui->lblLicenseAuthorsSupport->text() - .arg(QStringLiteral("https://github.com/dolphin-emu/dolphin/blob/master/license.txt")) - .arg(QStringLiteral("https://github.com/dolphin-emu/dolphin/graphs/contributors")) - .arg(QStringLiteral("https://forums.dolphin-emu.org/"))); - m_ui->lblLogo->setPixmap(Resources::GetPixmap(Resources::DOLPHIN_LOGO_LARGE)); -} - -DAboutDialog::~DAboutDialog() -{ -} diff --git a/Source/Core/DolphinQt/AboutDialog.h b/Source/Core/DolphinQt/AboutDialog.h deleted file mode 100644 index fa476a1024..0000000000 --- a/Source/Core/DolphinQt/AboutDialog.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include -#include - -// Predefinitions -namespace Ui -{ -class DAboutDialog; -} - -class DAboutDialog final : public QDialog -{ - Q_OBJECT - -public: - explicit DAboutDialog(QWidget* parent_widget = nullptr); - ~DAboutDialog(); - -private: - std::unique_ptr m_ui; -}; diff --git a/Source/Core/DolphinQt/AboutDialog.ui b/Source/Core/DolphinQt/AboutDialog.ui deleted file mode 100644 index 5cce02c2b0..0000000000 --- a/Source/Core/DolphinQt/AboutDialog.ui +++ /dev/null @@ -1,151 +0,0 @@ - - - DAboutDialog - - - - 0 - 0 - - - - About Dolphin - - - - 22 - - - 18 - - - 13 - - - - - <a href="%1">License</a> | <a href="%2">Authors</a> | <a href="%3">Support</a> - - - Qt::RichText - - - true - - - - - - - - 7 - - - - Branch: %1 -Revision: %2 - - - Qt::PlainText - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - - 0 - 0 - - - - 16 - - - - - - - Check for updates: <a href="https://dolphin-emu.org/download">dolphin-emu.org/download</a> - - - Qt::RichText - - - true - - - - - - - - 31 - - - - Dolphin - - - Qt::PlainText - - - - - - - - 7 - - - - © 2003-%1 Dolphin Team. “GameCube” and “Wii” are trademarks of Nintendo. Dolphin is not affiliated with Nintendo in any way. - - - Qt::PlainText - - - Qt::AlignCenter - - - - - - - - 9 - 75 - false - true - - - - <git shortrev> - - - Qt::PlainText - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - Dolphin is a free and open-source GameCube and Wii emulator. -This software should not be used to play games you do not legally own. - - - Qt::PlainText - - - - - - - - diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt deleted file mode 100644 index 186db06c5c..0000000000 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ /dev/null @@ -1,88 +0,0 @@ -# because of generated UI files -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -add_definitions(-DQT_USE_QSTRINGBUILDER -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII) -set(CMAKE_AUTOMOC ON) - -set(SRCS - AboutDialog.cpp - AboutDialog.h - Host.cpp - Main.cpp - MainWindow.cpp - MainWindow.h - SystemInfo.cpp - GameList/GameFile.cpp - GameList/GameGrid.cpp - GameList/GameTracker.cpp - GameList/GameTree.cpp - Utils/Resources.cpp - Utils/Utils.cpp - VideoInterface/RenderWidget.cpp - ) - -set(UIS - AboutDialog.ui - MainWindow.ui - SystemInfo.ui - GameList/GameGrid.ui - GameList/GameTree.ui - ) - -list(APPEND LIBS core uicommon) - -if(APPLE) - set(DOLPHINQT_BINARY DolphinQt) -else() - set(DOLPHINQT_BINARY dolphin-emu-qt) -endif() - -qt5_wrap_ui(UI_HEADERS ${UIS}) -add_executable(${DOLPHINQT_BINARY} ${SRCS} ${UI_HEADERS}) -target_link_libraries(${DOLPHINQT_BINARY} ${LIBS}) -qt5_use_modules(${DOLPHINQT_BINARY} Widgets) - -if(APPLE) - # Note: This is based on the DolphinWX version. - - include(BundleUtilities) - set(BUNDLE_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${DOLPHINQT_BINARY}.app) - - # Ask for an application bundle. - set_target_properties(${DOLPHINQT_BINARY} PROPERTIES - MACOSX_BUNDLE true - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in - ) - - # get rid of any old copies - file (REMOVE_RECURSE ${BUNDLE_PATH}/Contents/Resources/Sys) - if(NOT SKIP_POSTPROCESS_BUNDLE) - # Fix up the bundle after it is finished. - # There does not seem to be an easy way to run CMake commands post-build, - # so we invoke CMake again on a generated script. - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/postprocess_bundle.cmake " - include(BundleUtilities) - message(\"Fixing up application bundle: ${BUNDLE_PATH}\") - message(\"(Note: This is only necessary to produce a redistributable binary.\") - message(\"To skip, pass -DSKIP_POSTPROCESS_BUNDLE=1 to cmake.)\") - set(BU_CHMOD_BUNDLE_ITEMS ON) - execute_process(COMMAND ${CMAKE_SOURCE_DIR}/Tools/deploy-mac.py -p platforms/libqcocoa.dylib \"${BUNDLE_PATH}\") - file(INSTALL ${CMAKE_SOURCE_DIR}/Data/Sys - DESTINATION ${BUNDLE_PATH}/Contents/Resources - ) - ") - add_custom_command(TARGET ${DOLPHINQT_BINARY} POST_BUILD - COMMAND ${CMAKE_COMMAND} -P postprocess_bundle.cmake - ) - else() - add_custom_command(OUTPUT ${BUNDLE_PATH}/Contents/Resources/Sys - COMMAND ln -nfs ${CMAKE_SOURCE_DIR}/Data/Sys ${BUNDLE_PATH}/Contents/Resources/Sys - VERBATIM - ) - add_custom_target(CopyDataIntoBundleQt ALL - DEPENDS ${BUNDLE_PATH}/Contents/Resources/Sys - ) - endif() -else() - install(TARGETS ${DOLPHINQT_BINARY} RUNTIME DESTINATION ${bindir}) -endif() diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj deleted file mode 100644 index abb186303c..0000000000 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ /dev/null @@ -1,189 +0,0 @@ - - - - - Debug - x64 - - - Release - x64 - - - - {69D2B16E-122A-4E5D-8C37-8EC7B0F7CEB0} - - - - - Application - v140 - Unicode - - - true - - - false - - - - - - - - - - - - - - - 0x00400000 - false - true - $(ExternalsDir)OpenAL\$(PlatformName);%(AdditionalLibraryDirectories) - iphlpapi.lib;winmm.lib;setupapi.lib;vfw32.lib;opengl32.lib;glu32.lib;rpcrt4.lib;comctl32.lib;%(AdditionalDependencies) - Windows - - - $(ProjectDir)\VideoInterface;$(ProjectDir)\GameList;%(AdditionalIncludeDirectories) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {8ada04d7-6db1-4da4-ab55-64fb12a0997b} - - - {4c9f135b-a85e-430c-bad4-4c67ef5fc12c} - - - {ab993f38-c31d-4897-b139-a620c42bc565} - - - {93d73454-2512-424e-9cda-4bb357fe13dd} - - - {ff213b23-2c26-4214-9f88-85271e557e87} - - - {54aa7840-5beb-4a0c-9452-74ba4cc7fd44} - - - {2e6c348c-c75c-4d94-8d1e-9c1fcbf3efe4} - - - {41279555-f94f-4ebc-99de-af863c10c5c4} - - - {e54cf649-140e-4255-81a5-30a673c1fb36} - - - {160bdc25-5626-4b0d-bdd8-2953d9777fb5} - - - {6bbd47cf-91fd-4077-b676-8b76980178a9} - - - {96020103-4ba5-4fd2-b4aa-5b6d24492d4e} - - - {ec1a314c-5588-4506-9c1e-2e58e5817f75} - - - {a4c423aa-f57c-46c7-a172-d1a777017d29} - - - {3de9ee35-3e91-4f27-a014-2866ad8c3fe3} - - - {604C8368-F34A-4D55-82C8-CC92A0C13254} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj.filters b/Source/Core/DolphinQt/DolphinQt.vcxproj.filters deleted file mode 100644 index 2c58321344..0000000000 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj.filters +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - Utils - - - Utils - - - GameList - - - GameList - - - GameList - - - GameList - - - VideoInterface - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - - - - - - - - - - - - - - GameList - - - - - - - - {2497846c-00eb-4f1c-b437-2d32eac9027c} - - - {730f2ae7-a686-4bc8-bb49-b4f8bd240329} - - - {c18a1fb3-64ff-4249-b808-d73a56ea3a2d} - - - {be9925db-448c-46d8-a5a3-fb957490d3ef} - - - - - - Utils - - - Utils - - - VideoInterface - - - GameList - - - GameList - - - GameList - - - GameList - - - \ No newline at end of file diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj.user b/Source/Core/DolphinQt/DolphinQt.vcxproj.user deleted file mode 100644 index 5804e0cf2d..0000000000 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj.user +++ /dev/null @@ -1,10 +0,0 @@ - - - - - $(BinaryOutputDir)$(TargetFileName) - $(BinaryOutputDir) - WindowsLocalDebugger - false - - \ No newline at end of file diff --git a/Source/Core/DolphinQt/GameList/GameFile.cpp b/Source/Core/DolphinQt/GameList/GameFile.cpp deleted file mode 100644 index 0d773d1fe0..0000000000 --- a/Source/Core/DolphinQt/GameList/GameFile.cpp +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include -#include - -#include -#include -#include -#include -#include - -#include "Common/Common.h" -#include "Common/CommonPaths.h" -#include "Common/FileUtil.h" -#include "Common/Hash.h" -#include "Common/IniFile.h" -#include "Common/StringUtil.h" - -#include "Core/ConfigManager.h" - -#include "DiscIO/VolumeCreator.h" - -#include "DolphinQt/GameList/GameFile.h" - -static const u32 CACHE_REVISION = 0x00E; // Last changed in PR 3309 -static const u32 DATASTREAM_REVISION = 15; // Introduced in Qt 5.2 - -static QMap ConvertLocalizedStrings(std::map strings) -{ - QMap result; - - for (auto entry : strings) - result.insert(entry.first, QString::fromStdString(entry.second).trimmed()); - - return result; -} - -template -static QMap CastLocalizedStrings(QMap strings) -{ - QMap result; - - auto end = strings.cend(); - for (auto it = strings.cbegin(); it != end; ++it) - result.insert((to)it.key(), it.value()); - - return result; -} - -static QString GetLanguageString(DiscIO::IVolume::ELanguage language, QMap strings) -{ - if (strings.contains(language)) - return strings.value(language); - - // English tends to be a good fallback when the requested language isn't available - if (language != DiscIO::IVolume::ELanguage::LANGUAGE_ENGLISH) - { - if (strings.contains(DiscIO::IVolume::ELanguage::LANGUAGE_ENGLISH)) - return strings.value(DiscIO::IVolume::ELanguage::LANGUAGE_ENGLISH); - } - - // If English isn't available either, just pick something - if (!strings.empty()) - return strings.cbegin().value(); - - return QStringLiteral(""); -} - -GameFile::GameFile(const QString& fileName) - : m_file_name(fileName) -{ - QFileInfo info(m_file_name); - QDir directory = info.absoluteDir(); - m_folder_name = directory.dirName(); - - if (LoadFromCache()) - { - m_valid = true; - - // Wii banners can only be read if there is a savefile, - // so sometimes caches don't contain banners. Let's check - // if a banner has become available after the cache was made. - if (m_banner.isNull()) - { - int width, height; - std::vector buffer = DiscIO::IVolume::GetWiiBanner(&width, &height, m_title_id); - ReadBanner(buffer, width, height); - if (!m_banner.isNull()) - SaveToCache(); - } - } - else - { - std::unique_ptr volume(DiscIO::CreateVolumeFromFilename(fileName.toStdString())); - - if (volume != nullptr) - { - m_platform = volume->GetVolumeType(); - - m_short_names = ConvertLocalizedStrings(volume->GetNames(false)); - m_long_names = ConvertLocalizedStrings(volume->GetNames(true)); - m_descriptions = ConvertLocalizedStrings(volume->GetDescriptions()); - m_company = QString::fromStdString(volume->GetCompany()); - - m_country = volume->GetCountry(); - m_blob_type = volume->GetBlobType(); - m_file_size = volume->GetRawSize(); - m_volume_size = volume->GetSize(); - - // A temporary variable is necessary here to convert between - // quint64 (needed by GameFile's cache code) and u64 (needed by GetTitleID) - u64 title_id; - volume->GetTitleID(&title_id); - m_title_id = title_id; - - m_unique_id = QString::fromStdString(volume->GetUniqueID()); - m_disc_number = volume->GetDiscNumber(); - m_revision = volume->GetRevision(); - - int width, height; - std::vector buffer = volume->GetBanner(&width, &height); - ReadBanner(buffer, width, height); - - m_valid = true; - SaveToCache(); - } - } - - if (m_company.isEmpty() && m_unique_id.size() >= 6) - m_company = QString::fromStdString(DiscIO::GetCompanyFromID(m_unique_id.mid(4, 2).toStdString())); - - if (m_valid) - { - IniFile ini = SConfig::LoadGameIni(m_unique_id.toStdString(), m_revision); - std::string issues_temp; - ini.GetIfExists("EmuState", "EmulationStateId", &m_emu_state); - ini.GetIfExists("EmuState", "EmulationIssues", &issues_temp); - m_issues = QString::fromStdString(issues_temp); - } - - if (!IsValid() && IsElfOrDol()) - { - m_valid = true; - m_file_size = info.size(); - m_platform = DiscIO::IVolume::ELF_DOL; - } - - // Metadata can optionally be stored in XML and PNG files. Typical for DOLs and ELFs, but also works - // with volumes. icon.png and meta.xml are the file names used by Homebrew Channel. The ability to use - // files with the same name as the main file is provided as an alternative for those who want to have - // multiple files in one folder instead of having a Homebrew Channel-style folder structure. - - if (!ReadXML(directory.filePath(info.baseName() + QStringLiteral(".xml")))) - ReadXML(directory.filePath(QStringLiteral("meta.xml"))); - - QImage banner(directory.filePath(info.baseName() + QStringLiteral(".png"))); - if (banner.isNull()) - banner.load(directory.filePath(QStringLiteral("icon.png"))); - if (!banner.isNull()) - m_banner = QPixmap::fromImage(banner); -} - -bool GameFile::LoadFromCache() -{ - QString filename = CreateCacheFilename(); - if (filename.isEmpty()) - return false; - - QFile file(filename); - if (!file.exists()) - return false; - if (!file.open(QFile::ReadOnly)) - return false; - - // Increment CACHE_REVISION if the code below is modified (GameFile.cpp) - QDataStream stream(&file); - stream.setVersion(DATASTREAM_REVISION); - - u32 cache_rev; - stream >> cache_rev; - if (cache_rev != CACHE_REVISION) - return false; - - u32 country; - u32 platform; - u32 blob_type; - QMap short_names; - QMap long_names; - QMap descriptions; - stream >> short_names - >> long_names - >> descriptions - >> m_company - >> m_unique_id - >> m_title_id - >> blob_type - >> m_file_size - >> m_volume_size - >> country - >> m_banner - >> platform - >> m_disc_number - >> m_revision; - m_country = (DiscIO::IVolume::ECountry)country; - m_platform = (DiscIO::IVolume::EPlatform)platform; - m_blob_type = (DiscIO::BlobType)blob_type; - m_short_names = CastLocalizedStrings(short_names); - m_long_names = CastLocalizedStrings(long_names); - m_descriptions = CastLocalizedStrings(descriptions); - file.close(); - return true; -} - -void GameFile::SaveToCache() -{ - if (!File::IsDirectory(File::GetUserPath(D_CACHE_IDX))) - File::CreateDir(File::GetUserPath(D_CACHE_IDX)); - - QString filename = CreateCacheFilename(); - if (filename.isEmpty()) - return; - if (QFile::exists(filename)) - QFile::remove(filename); - - QFile file(filename); - if (!file.open(QFile::WriteOnly)) - return; - - // Increment CACHE_REVISION if the code below is modified (GameFile.cpp) - QDataStream stream(&file); - stream.setVersion(DATASTREAM_REVISION); - stream << CACHE_REVISION; - - stream << CastLocalizedStrings(m_short_names) - << CastLocalizedStrings(m_long_names) - << CastLocalizedStrings(m_descriptions) - << m_company - << m_unique_id - << m_title_id - << (u32)m_blob_type - << m_file_size - << m_volume_size - << (u32)m_country - << m_banner - << (u32)m_platform - << m_disc_number - << m_revision; -} - -bool GameFile::IsElfOrDol() const -{ - return m_file_name.endsWith(QStringLiteral(".elf"), Qt::CaseInsensitive) || - m_file_name.endsWith(QStringLiteral(".dol"), Qt::CaseInsensitive); -} - -QString GameFile::CreateCacheFilename() const -{ - std::string filename, pathname, extension; - SplitPath(m_file_name.toStdString(), &pathname, &filename, &extension); - - if (filename.empty()) - return QStringLiteral(""); // must be a disc drive - - // Filename.extension_HashOfFolderPath_Size.cache - // Append hash to prevent ISO name-clashing in different folders. - filename.append(StringFromFormat("%s_%x_%llx.qcache", - extension.c_str(), HashFletcher((const u8*)pathname.c_str(), pathname.size()), - (unsigned long long)File::GetSize(m_file_name.toStdString()))); - - QString fullname = QString::fromStdString(File::GetUserPath(D_CACHE_IDX)); - fullname += QString::fromStdString(filename); - return fullname; -} - -// Outputs to m_banner -void GameFile::ReadBanner(const std::vector& buffer, int width, int height) -{ - QImage banner(width, height, QImage::Format_RGB888); - for (int i = 0; i < width * height; i++) - { - int x = i % width, y = i / width; - banner.setPixel(x, y, qRgb((buffer[i] & 0xFF0000) >> 16, - (buffer[i] & 0x00FF00) >> 8, - (buffer[i] & 0x0000FF) >> 0)); - } - - if (!banner.isNull()) - m_banner = QPixmap::fromImage(banner); -} - -// Outputs to m_short_names, m_long_names, m_descriptions, m_company. -// Returns whether a file was found, not whether it contained useful data. -bool GameFile::ReadXML(const QString& file_path) -{ - // The format of Homebrew Channel XML metadata is described at: - // http://wiibrew.org/wiki/Homebrew_Channel#Adding_Text - - QFile file(file_path); - if (!file.open(QIODevice::ReadOnly)) - return false; - - QXmlStreamReader reader(&file); - if (reader.readNextStartElement() && reader.name() == QStringLiteral("app")) - { - while (reader.readNextStartElement()) - { - QStringRef name = reader.name(); - if (name == QStringLiteral("name")) - { - m_short_names = { { DiscIO::IVolume::LANGUAGE_UNKNOWN, reader.readElementText() } }; - m_long_names = m_short_names; - } - else if (name == QStringLiteral("short_description")) - { - m_descriptions = { { DiscIO::IVolume::LANGUAGE_UNKNOWN, reader.readElementText() } }; - } - else if (name == QStringLiteral("coder")) - { - m_company = reader.readElementText(); - } - else - { - reader.skipCurrentElement(); - } - // Elements that we aren't using: - // version (can be written in any format) - // release_date (YYYYmmddHHMMSS format) - // long_description (can be several screens long!) - } - } - - return true; -} - -QString GameFile::GetDescription(DiscIO::IVolume::ELanguage language) const -{ - return GetLanguageString(language, m_descriptions); -} - -QString GameFile::GetDescription() const -{ - bool wii = m_platform != DiscIO::IVolume::GAMECUBE_DISC; - return GetDescription(SConfig::GetInstance().GetCurrentLanguage(wii)); -} - -QString GameFile::GetName(bool prefer_long, DiscIO::IVolume::ELanguage language) const -{ - return GetLanguageString(language, prefer_long ? m_long_names : m_short_names); -} - -QString GameFile::GetName(bool prefer_long) const -{ - bool wii = m_platform != DiscIO::IVolume::GAMECUBE_DISC; - QString name = GetName(prefer_long, SConfig::GetInstance().GetCurrentLanguage(wii)); - if (name.isEmpty()) - { - // No usable name, return filename (better than nothing) - std::string name_temp, extension; - SplitPath(m_file_name.toStdString(), nullptr, &name_temp, &extension); - name = QString::fromStdString(name_temp + extension); - } - return name; -} - -const QString GameFile::GetWiiFSPath() const -{ - std::unique_ptr volume(DiscIO::CreateVolumeFromFilename(m_file_name.toStdString())); - QString ret; - - if (volume == nullptr) - return ret; - - if (volume->GetVolumeType() != DiscIO::IVolume::GAMECUBE_DISC) - { - u64 title_id; - volume->GetTitleID(&title_id); - - std::string path = StringFromFormat("%s/title/%08x/%08x/data/", - File::GetUserPath(D_WIIROOT_IDX).c_str(), (u32)(title_id >> 32), (u32)title_id); - - if (!File::Exists(path)) - File::CreateFullPath(path); - - if (path[0] == '.') - ret = QDir::currentPath() + QString::fromStdString(path).mid((int)strlen(ROOT_DIR)); - else - ret = QString::fromStdString(path); - } - - return ret; -} diff --git a/Source/Core/DolphinQt/GameList/GameFile.h b/Source/Core/DolphinQt/GameList/GameFile.h deleted file mode 100644 index 8c16ac85bf..0000000000 --- a/Source/Core/DolphinQt/GameList/GameFile.h +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include -#include -#include - -#include - -#include "DiscIO/Blob.h" -#include "DiscIO/Volume.h" - -#include "DolphinQt/Utils/Resources.h" - -class GameFile final -{ -public: - GameFile(const QString& fileName); - GameFile(const std::string& fileName) : GameFile(QString::fromStdString(fileName)) {} - - bool IsValid() const { return m_valid; } - QString GetFileName() { return m_file_name; } - QString GetFolderName() { return m_folder_name; } - QString GetName(bool prefer_long, DiscIO::IVolume::ELanguage language) const; - QString GetName(bool prefer_long) const; - QString GetDescription(DiscIO::IVolume::ELanguage language) const; - QString GetDescription() const; - QString GetCompany() const { return m_company; } - u16 GetRevision() const { return m_revision; } - const QString GetUniqueID() const { return m_unique_id; } - const QString GetWiiFSPath() const; - DiscIO::IVolume::ECountry GetCountry() const { return m_country; } - DiscIO::IVolume::EPlatform GetPlatform() const { return m_platform; } - DiscIO::BlobType GetBlobType() const { return m_blob_type; } - const QString GetIssues() const { return m_issues; } - int GetEmuState() const { return m_emu_state; } - bool IsCompressed() const - { - return m_blob_type == DiscIO::BlobType::GCZ || m_blob_type == DiscIO::BlobType::CISO || - m_blob_type == DiscIO::BlobType::WBFS; - } - u64 GetFileSize() const { return m_file_size; } - u64 GetVolumeSize() const { return m_volume_size; } - // 0 is the first disc, 1 is the second disc - u8 GetDiscNumber() const { return m_disc_number; } - const QPixmap GetBitmap() const - { - if (m_banner.isNull()) - return Resources::GetPixmap(Resources::BANNER_MISSING); - - return m_banner; - } - -private: - QString m_file_name; - QString m_folder_name; - - QMap m_short_names; - QMap m_long_names; - QMap m_descriptions; - QString m_company; - - QString m_unique_id; - quint64 m_title_id; - - QString m_issues; - int m_emu_state = 0; - - quint64 m_file_size = 0; - quint64 m_volume_size = 0; - - DiscIO::IVolume::ECountry m_country = DiscIO::IVolume::COUNTRY_UNKNOWN; - DiscIO::IVolume::EPlatform m_platform; - DiscIO::BlobType m_blob_type; - u16 m_revision = 0; - - QPixmap m_banner; - bool m_valid = false; - u8 m_disc_number = 0; - - bool LoadFromCache(); - void SaveToCache(); - - bool IsElfOrDol() const; - QString CreateCacheFilename() const; - - // Outputs to m_banner - void ReadBanner(const std::vector& buffer, int width, int height); - // Outputs to m_short_names, m_long_names, m_descriptions, m_company. - // Returns whether a file was found, not whether it contained useful data. - bool ReadXML(const QString& file_path); -}; diff --git a/Source/Core/DolphinQt/GameList/GameGrid.cpp b/Source/Core/DolphinQt/GameList/GameGrid.cpp deleted file mode 100644 index 4b1887151d..0000000000 --- a/Source/Core/DolphinQt/GameList/GameGrid.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include - -#include "ui_GameGrid.h" - -#include "DolphinQt/GameList/GameGrid.h" - -// Game banner image size -static const u32 GRID_BANNER_WIDTH = 144; -static const u32 GRID_BANNER_HEIGHT = 48; - -static const u32 ICON_BANNER_WIDTH = 64; -static const u32 ICON_BANNER_HEIGHT = 64; - -DGameGrid::DGameGrid(QWidget* parent_widget) : - QListWidget(parent_widget) -{ - m_ui = std::make_unique(); - m_ui->setupUi(this); - SetViewStyle(STYLE_GRID); - - connect(this, &QListWidget::itemActivated, this, &DGameGrid::StartGame); -} - -DGameGrid::~DGameGrid() -{ - for (QListWidgetItem* i : m_items.keys()) - delete i; -} - -GameFile* DGameGrid::SelectedGame() -{ - if (!selectedItems().empty()) - return m_items.value(selectedItems().at(0)); - else - return nullptr; -} - -void DGameGrid::SelectGame(GameFile* game) -{ - if (game == nullptr) - return; - if (!selectedItems().empty()) - selectedItems().at(0)->setSelected(false); - m_items.key(game)->setSelected(true); -} - -void DGameGrid::SetViewStyle(GameListStyle newStyle) -{ - if (newStyle == STYLE_GRID) - { - m_current_style = STYLE_GRID; - setIconSize(QSize(GRID_BANNER_WIDTH, GRID_BANNER_HEIGHT)); - setViewMode(QListView::IconMode); - } - else - { - m_current_style = STYLE_ICON; - setIconSize(QSize(ICON_BANNER_WIDTH, ICON_BANNER_HEIGHT)); - setViewMode(QListView::ListMode); - } - - // QListView resets this when you change the view mode, so let's set it again - setDragEnabled(false); -} - -void DGameGrid::AddGame(GameFile* gameItem) -{ - if (m_items.values().contains(gameItem)) - return; - m_items.values().append(gameItem); - - QListWidgetItem* i = new QListWidgetItem; - i->setIcon(QIcon(gameItem->GetBitmap() - .scaled(GRID_BANNER_WIDTH, GRID_BANNER_HEIGHT, Qt::KeepAspectRatio, Qt::SmoothTransformation))); - i->setText(gameItem->GetName(false)); - if (gameItem->IsCompressed()) - i->setTextColor(QColor("#00F")); - - addItem(i); - m_items.insert(i, gameItem); -} - -void DGameGrid::RemoveGame(GameFile* gameItem) -{ - if (!m_items.values().contains(gameItem)) - return; - - QListWidgetItem* i = m_items.key(gameItem); - m_items.remove(i); - delete i; -} diff --git a/Source/Core/DolphinQt/GameList/GameGrid.h b/Source/Core/DolphinQt/GameList/GameGrid.h deleted file mode 100644 index 63e665e8a4..0000000000 --- a/Source/Core/DolphinQt/GameList/GameGrid.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include - -#include - -#include "DolphinQt/GameList/GameTracker.h" - -// Predefinitions -namespace Ui -{ -class DGameGrid; -} - -class DGameGrid final : public QListWidget, public AbstractGameList -{ - Q_OBJECT - -public: - explicit DGameGrid(QWidget* parent_widget = nullptr); - ~DGameGrid(); - - // AbstractGameList stuff - virtual GameFile* SelectedGame(); - virtual void SelectGame(GameFile* game); - - virtual void SetViewStyle(GameListStyle newStyle); - - virtual void AddGame(GameFile* gameItem); - virtual void RemoveGame(GameFile* gameItem); - -signals: - void StartGame(); - -private: - std::unique_ptr m_ui; - - QMap m_items; - GameListStyle m_current_style; -}; diff --git a/Source/Core/DolphinQt/GameList/GameGrid.ui b/Source/Core/DolphinQt/GameList/GameGrid.ui deleted file mode 100644 index cc910ee63b..0000000000 --- a/Source/Core/DolphinQt/GameList/GameGrid.ui +++ /dev/null @@ -1,25 +0,0 @@ - - - DGameGrid - - - - 0 - 0 - 254 - 190 - - - - true - - - QListView::Adjust - - - true - - - - - diff --git a/Source/Core/DolphinQt/GameList/GameTracker.cpp b/Source/Core/DolphinQt/GameList/GameTracker.cpp deleted file mode 100644 index 3973af7d1b..0000000000 --- a/Source/Core/DolphinQt/GameList/GameTracker.cpp +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include "Common/CDUtils.h" -#include "Common/FileSearch.h" -#include "Common/FileUtil.h" -#include "Core/ConfigManager.h" - -#include "DolphinQt/GameList/GameGrid.h" -#include "DolphinQt/GameList/GameTracker.h" -#include "DolphinQt/GameList/GameTree.h" - -void AbstractGameList::AddGames(QList items) -{ - for (GameFile* o : items) - AddGame(o); -} -void AbstractGameList::RemoveGames(QList items) -{ - for (GameFile* o : items) - RemoveGame(o); -} - - -DGameTracker::DGameTracker(QWidget* parent_widget) - : QStackedWidget(parent_widget), - m_watcher(new QFileSystemWatcher(this)) -{ - connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, &DGameTracker::ScanForGames); - - m_tree_widget = new DGameTree(this); - addWidget(m_tree_widget); - connect(m_tree_widget, &DGameTree::StartGame, this, &DGameTracker::StartGame); - - m_grid_widget = new DGameGrid(this); - addWidget(m_grid_widget); - connect(m_grid_widget, &DGameGrid::StartGame, this, &DGameTracker::StartGame); - - SetViewStyle(STYLE_LIST); -} - -DGameTracker::~DGameTracker() -{ - for (GameFile* file : m_games.values()) - delete file; -} - -void DGameTracker::SetViewStyle(GameListStyle newStyle) -{ - if (newStyle == m_current_style) - return; - m_current_style = newStyle; - - if (newStyle == STYLE_LIST || newStyle == STYLE_TREE) - { - m_tree_widget->SelectGame(SelectedGame()); - setCurrentWidget(m_tree_widget); - m_tree_widget->SetViewStyle(newStyle); - } - else - { - m_grid_widget->SelectGame(SelectedGame()); - setCurrentWidget(m_grid_widget); - m_grid_widget->SetViewStyle(newStyle); - } -} - -GameFile* DGameTracker::SelectedGame() -{ - if (currentWidget() == m_grid_widget) - return m_grid_widget->SelectedGame(); - else - return m_tree_widget->SelectedGame(); -} - -void DGameTracker::ScanForGames() -{ - setDisabled(true); - - delete m_watcher; - m_watcher = new QFileSystemWatcher(this); - for (std::string dir : SConfig::GetInstance().m_ISOFolder) - m_watcher->addPath(QString::fromStdString(dir)); - if (SConfig::GetInstance().m_RecursiveISOFolder) - { - for (std::string dir : FindSubdirectories(SConfig::GetInstance().m_ISOFolder, /*recursive*/ true)) - m_watcher->addPath(QString::fromStdString(dir)); - } - - std::vector exts; - if (SConfig::GetInstance().m_ListGC) - { - exts.push_back(".gcm"); - exts.push_back(".gcz"); - } - if (SConfig::GetInstance().m_ListWii || SConfig::GetInstance().m_ListGC) - { - exts.push_back(".iso"); - exts.push_back(".ciso"); - exts.push_back(".wbfs"); - } - if (SConfig::GetInstance().m_ListWad) - exts.push_back(".wad"); - if (SConfig::GetInstance().m_ListElfDol) - { - exts.push_back(".dol"); - exts.push_back(".elf"); - } - - auto rFilenames = DoFileSearch(exts, SConfig::GetInstance().m_ISOFolder, SConfig::GetInstance().m_RecursiveISOFolder); - QList newItems; - QStringList allItems; - - if (!rFilenames.empty()) - { - for (u32 i = 0; i < rFilenames.size(); i++) - { - std::string FileName; - SplitPath(rFilenames[i], nullptr, &FileName, nullptr); - QString NameAndPath = QString::fromStdString(rFilenames[i]); - allItems.append(NameAndPath); - - if (m_games.keys().contains(NameAndPath)) - continue; - - GameFile* obj = new GameFile(rFilenames[i]); - if (obj->IsValid()) - { - bool list = true; - - switch (obj->GetCountry()) - { - case DiscIO::IVolume::COUNTRY_AUSTRALIA: - if (!SConfig::GetInstance().m_ListAustralia) - list = false; - break; - case DiscIO::IVolume::COUNTRY_EUROPE: - if (!SConfig::GetInstance().m_ListPal) - list = false; - break; - case DiscIO::IVolume::COUNTRY_FRANCE: - if (!SConfig::GetInstance().m_ListFrance) - list = false; - break; - case DiscIO::IVolume::COUNTRY_GERMANY: - if (!SConfig::GetInstance().m_ListGermany) - list = false; - break; - case DiscIO::IVolume::COUNTRY_ITALY: - if (!SConfig::GetInstance().m_ListItaly) - list = false; - break; - case DiscIO::IVolume::COUNTRY_JAPAN: - if (!SConfig::GetInstance().m_ListJap) - list = false; - break; - case DiscIO::IVolume::COUNTRY_KOREA: - if (!SConfig::GetInstance().m_ListKorea) - list = false; - break; - case DiscIO::IVolume::COUNTRY_NETHERLANDS: - if (!SConfig::GetInstance().m_ListNetherlands) - list = false; - break; - case DiscIO::IVolume::COUNTRY_RUSSIA: - if (!SConfig::GetInstance().m_ListRussia) - list = false; - break; - case DiscIO::IVolume::COUNTRY_SPAIN: - if (!SConfig::GetInstance().m_ListSpain) - list = false; - break; - case DiscIO::IVolume::COUNTRY_TAIWAN: - if (!SConfig::GetInstance().m_ListTaiwan) - list = false; - break; - case DiscIO::IVolume::COUNTRY_USA: - if (!SConfig::GetInstance().m_ListUsa) - list = false; - break; - case DiscIO::IVolume::COUNTRY_WORLD: - if (!SConfig::GetInstance().m_ListWorld) - list = false; - break; - case DiscIO::IVolume::COUNTRY_UNKNOWN: - default: - if (!SConfig::GetInstance().m_ListUnknown) - list = false; - break; - } - - if (list) - newItems.append(obj); - } - } - } - - // Process all the new GameFiles - for (GameFile* o : newItems) - m_games.insert(o->GetFileName(), o); - - // Check for games that were removed - QList removedGames; - for (QString& path : m_games.keys()) - { - if (!allItems.contains(path)) - { - removedGames.append(m_games.value(path)); - m_games.remove(path); - } - } - - m_tree_widget->AddGames(newItems); - m_grid_widget->AddGames(newItems); - - m_tree_widget->RemoveGames(removedGames); - m_grid_widget->RemoveGames(removedGames); - - for (GameFile* file : removedGames) - delete file; - - setDisabled(false); -} - -void DGameTracker::SelectLastBootedGame() -{ - if (!SConfig::GetInstance().m_LastFilename.empty() && File::Exists(SConfig::GetInstance().m_LastFilename)) - { - QString lastfilename = QString::fromStdString(SConfig::GetInstance().m_LastFilename); - for (GameFile* game : m_games.values()) - { - if (game->GetFileName() == lastfilename) - { - m_tree_widget->SelectGame(game); - break; - } - } - } -} diff --git a/Source/Core/DolphinQt/GameList/GameTracker.h b/Source/Core/DolphinQt/GameList/GameTracker.h deleted file mode 100644 index 7f92ac2c00..0000000000 --- a/Source/Core/DolphinQt/GameList/GameTracker.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include -#include -#include -#include - -#include "DolphinQt/GameList/GameFile.h" - -// Predefinitions -class DGameGrid; -class DGameTree; - -enum GameListStyle -{ - STYLE_LIST, - STYLE_TREE, - STYLE_GRID, - STYLE_ICON -}; - -class AbstractGameList -{ -public: - virtual GameFile* SelectedGame() = 0; - virtual void SelectGame(GameFile* game) = 0; - - virtual void SetViewStyle(GameListStyle newStyle) = 0; - - virtual void AddGame(GameFile* item) = 0; - void AddGames(QList items); - - virtual void RemoveGame(GameFile* item) = 0; - void RemoveGames(QList items); -}; - -class DGameTracker final : public QStackedWidget -{ - Q_OBJECT - -public: - DGameTracker(QWidget* parent_widget = nullptr); - ~DGameTracker(); - - GameListStyle ViewStyle() const { return m_current_style; } - void SetViewStyle(GameListStyle newStyle); - - GameFile* SelectedGame(); - void SelectLastBootedGame(); - -signals: - void StartGame(); - -public slots: - void ScanForGames(); - -private: - QMap m_games; - QFileSystemWatcher* m_watcher; - - GameListStyle m_current_style; - DGameGrid* m_grid_widget = nullptr; - DGameTree* m_tree_widget = nullptr; -}; diff --git a/Source/Core/DolphinQt/GameList/GameTree.cpp b/Source/Core/DolphinQt/GameList/GameTree.cpp deleted file mode 100644 index 4925af6313..0000000000 --- a/Source/Core/DolphinQt/GameList/GameTree.cpp +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include - -#include "ui_GameTree.h" - -#include "DolphinQt/GameList/GameTree.h" -#include "DolphinQt/Utils/Resources.h" -#include "DolphinQt/Utils/Utils.h" - -// Game banner image size -static const u32 BANNER_WIDTH = 96; -static const u32 BANNER_HEIGHT = 32; - -DGameTree::DGameTree(QWidget* parent_widget) : - QTreeWidget(parent_widget) -{ - m_ui = std::make_unique(); - m_ui->setupUi(this); - - SetViewStyle(STYLE_TREE); - setIconSize(QSize(BANNER_WIDTH, BANNER_HEIGHT)); - sortByColumn(COL_TITLE, Qt::AscendingOrder); - - connect(this, &QTreeWidget::itemActivated, this, &DGameTree::ItemActivated); -} - -DGameTree::~DGameTree() -{ - int count = topLevelItemCount(); - for (int a = 0; a < count; a++) - takeTopLevelItem(0); - - for (QTreeWidgetItem* i : m_path_nodes.values()) - { - count = i->childCount(); - for (int a = 0; a < count; a++) - i->takeChild(0); - } - - for (QTreeWidgetItem* i : m_path_nodes.values()) - delete i; - for (QTreeWidgetItem* i : m_items.keys()) - delete i; -} - -void DGameTree::ResizeAllCols() -{ - for (int i = 0; i < columnCount(); i++) - resizeColumnToContents(i); -} - -void DGameTree::ItemActivated(QTreeWidgetItem* item) -{ - if (!m_path_nodes.values().contains(item)) - emit StartGame(); -} - -GameFile* DGameTree::SelectedGame() -{ - if (!selectedItems().empty()) - return m_items.value(selectedItems().at(0)); - else - return nullptr; -} - -void DGameTree::SelectGame(GameFile* game) -{ - if (game == nullptr) - return; - if (!selectedItems().empty()) - selectedItems().at(0)->setSelected(false); - m_items.key(game)->setSelected(true); -} - -void DGameTree::SetViewStyle(GameListStyle newStyle) -{ - if (newStyle == STYLE_LIST) - { - m_current_style = STYLE_LIST; - setIndentation(0); - RebuildTree(); - } - else - { - m_current_style = STYLE_TREE; - setIndentation(20); - RebuildTree(); - } -} - -void DGameTree::AddGame(GameFile* item) -{ - if (m_items.values().contains(item)) - return; - - QString folder = item->GetFolderName(); - if (!m_path_nodes.contains(folder)) - { - QTreeWidgetItem* i = new QTreeWidgetItem; - i->setText(0, folder); - m_path_nodes.insert(folder, i); - if (m_current_style == STYLE_TREE) - addTopLevelItem(i); - } - - QTreeWidgetItem* i = new QTreeWidgetItem; - i->setIcon(COL_TYPE, QIcon(Resources::GetPlatformPixmap(item->GetPlatform()))); - i->setIcon(COL_BANNER, QIcon(item->GetBitmap())); - i->setText(COL_TITLE, item->GetName(true)); - i->setText(COL_DESCRIPTION, item->GetDescription()); - i->setIcon(COL_REGION, QIcon(Resources::GetRegionPixmap(item->GetCountry()))); - i->setText(COL_SIZE, NiceSizeFormat(item->GetFileSize())); - i->setIcon(COL_STATE, QIcon(Resources::GetRatingPixmap(item->GetEmuState()))); - if (item->IsCompressed()) - { - for (int col = 0; col < columnCount(); col++) - i->setTextColor(col, QColor("#00F")); - } - m_items.insert(i, item); - - RebuildTree(); // TODO: only call this once per group of items added -} - -void DGameTree::RemoveGame(GameFile* item) -{ - if (!m_items.values().contains(item)) - return; - QTreeWidgetItem* i = m_items.key(item); - m_items.remove(i); - delete i; -} - -void DGameTree::RebuildTree() -{ - GameFile* currentGame = SelectedGame(); - - int count = topLevelItemCount(); - for (int a = 0; a < count; a++) - takeTopLevelItem(0); - - for (QTreeWidgetItem* i : m_path_nodes.values()) - { - count = i->childCount(); - for (int a = 0; a < count; a++) - i->takeChild(0); - } - - if (m_current_style == STYLE_TREE) - { - for (QTreeWidgetItem* i : m_path_nodes.values()) - addTopLevelItem(i); - for (QTreeWidgetItem* i : m_items.keys()) - m_path_nodes.value(m_items.value(i)->GetFolderName())->addChild(i); - } - else - { - for (QTreeWidgetItem* i : m_items.keys()) - addTopLevelItem(i); - } - - expandAll(); - ResizeAllCols(); - SelectGame(currentGame); -} diff --git a/Source/Core/DolphinQt/GameList/GameTree.h b/Source/Core/DolphinQt/GameList/GameTree.h deleted file mode 100644 index 37a1d0dfc7..0000000000 --- a/Source/Core/DolphinQt/GameList/GameTree.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include - -#include - -#include "DolphinQt/GameList/GameTracker.h" - -// Predefinitions -namespace Ui -{ -class DGameTree; -} - -class DGameTree final : public QTreeWidget, public AbstractGameList -{ - Q_OBJECT - -public: - explicit DGameTree(QWidget* parent_widget = nullptr); - ~DGameTree(); - - // AbstractGameList stuff - virtual GameFile* SelectedGame(); - virtual void SelectGame(GameFile* game); - - virtual void SetViewStyle(GameListStyle newStyle); - - virtual void AddGame(GameFile* item); - virtual void RemoveGame(GameFile* item); - -signals: - void StartGame(); - -private slots: - void ItemActivated(QTreeWidgetItem* item); - -private: - enum Columns - { - COL_TYPE = 0, - COL_BANNER = 1, - COL_TITLE = 2, - COL_DESCRIPTION = 3, - COL_REGION = 4, - COL_SIZE = 5, - COL_STATE = 6 - }; - - std::unique_ptr m_ui; - GameListStyle m_current_style; - - QMap m_items; - QMap m_path_nodes; - - void RebuildTree(); - void ResizeAllCols(); -}; diff --git a/Source/Core/DolphinQt/GameList/GameTree.ui b/Source/Core/DolphinQt/GameList/GameTree.ui deleted file mode 100644 index 22b63d82c3..0000000000 --- a/Source/Core/DolphinQt/GameList/GameTree.ui +++ /dev/null @@ -1,54 +0,0 @@ - - - DGameTree - - - - 0 - 0 - 396 - 296 - - - - true - - - - Type - - - - - Banner - - - - - Title - - - - - Description - - - - - Region - - - - - Size - - - - - State - - - - - - diff --git a/Source/Core/DolphinQt/Host.cpp b/Source/Core/DolphinQt/Host.cpp deleted file mode 100644 index e07796a18b..0000000000 --- a/Source/Core/DolphinQt/Host.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include - -#include -#include - -#include "Common/MsgHandler.h" -#include "Core/Host.h" - -#include "DolphinQt/Host.h" -#include "DolphinQt/MainWindow.h" - -HostTitleEvent::HostTitleEvent(const std::string& title) - : QEvent((QEvent::Type)HostEvent::TitleEvent), - m_title(title) -{ -} - -void Host_Message(int id) -{ - // TODO -} - -void Host_UpdateMainFrame() -{ - // TODO -} - -void Host_UpdateTitle(const std::string& title) -{ - qApp->postEvent(g_main_window, new HostTitleEvent(title)); -} - -void* Host_GetRenderHandle() -{ - return (void*)(g_main_window->GetRenderWidget()->winId()); -} - -void Host_RequestRenderWindowSize(int w, int h) -{ - DRenderWidget* render_widget = g_main_window->GetRenderWidget(); - qApp->postEvent(render_widget, new QResizeEvent(QSize(w, h), render_widget->size())); -} - -bool Host_RendererHasFocus() -{ - return g_main_window->RenderWidgetHasFocus(); -} - -bool Host_UIHasFocus() -{ - return g_main_window->isActiveWindow(); -} - -bool Host_RendererIsFullscreen() -{ - return false; // TODO -} - -void Host_RequestFullscreen(bool enable) -{ - // TODO -} - -void Host_NotifyMapLoaded() -{ - // TODO -} - -void Host_UpdateDisasmDialog() -{ - // TODO -} - -void Host_SetStartupDebuggingParameters() -{ - // TODO -} - -void Host_SetWiiMoteConnectionState(int state) -{ - // TODO -} - -void Host_ConnectWiimote(int wm_idx, bool connect) -{ - // TODO -} - -void Host_ShowVideoConfig(void* parent, const std::string& backend_name, - const std::string& config_name) -{ - // TODO -} - -void Host_RefreshDSPDebuggerWindow() -{ - // TODO -} diff --git a/Source/Core/DolphinQt/Host.h b/Source/Core/DolphinQt/Host.h deleted file mode 100644 index 40c4b6c54a..0000000000 --- a/Source/Core/DolphinQt/Host.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2015 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include -#include - -enum HostEvent { - TitleEvent = QEvent::User + 1, -}; - -class HostTitleEvent final : public QEvent -{ -public: - HostTitleEvent(const std::string& title); - const std::string m_title; -}; diff --git a/Source/Core/DolphinQt/Info.plist.in b/Source/Core/DolphinQt/Info.plist.in deleted file mode 100644 index aa3f6cb7e2..0000000000 --- a/Source/Core/DolphinQt/Info.plist.in +++ /dev/null @@ -1,80 +0,0 @@ - - - - - CFBundleDocumentTypes - - - CFBundleTypeExtensions - - ciso - dol - elf - gcm - gcz - iso - wad - wbfs - - CFBundleTypeIconFile - Dolphin.icns - CFBundleTypeName - Nintendo GC/Wii file - CFBundleTypeRole - Viewer - - - CFBundleExecutable - DolphinQt - CFBundleIconFile - Resources/Dolphin.icns - CFBundleIdentifier - org.dolphin-emu.dolphin - CFBundleDevelopmentRegion - English - CFBundleLocalizations - - ar - ca - cs - de - el - en - es - fa - fr - he - hu - it - ja - ko - nb - nl - pl - pt - pt_BR - ru - sr - sv - tr - zh_CN - zh_TW - - CFBundlePackageType - APPL - CFBundleShortVersionString - ${DOLPHIN_WC_DESCRIBE} - CFBundleLongVersionString - ${DOLPHIN_WC_REVISION} - CFBundleVersion - ${DOLPHIN_VERSION_MAJOR}.${DOLPHIN_VERSION_MINOR} - NSHumanReadableCopyright - Licensed under GPL version 2 - LSMinimumSystemVersion - ${OSX_MIN_VERSION} - NSHighResolutionCapable - - CSResourcesFileMapped - - - diff --git a/Source/Core/DolphinQt/Main.cpp b/Source/Core/DolphinQt/Main.cpp deleted file mode 100644 index 4d64c70f1f..0000000000 --- a/Source/Core/DolphinQt/Main.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include -#include -#include -#include -#include -#include - -#include "MainWindow.h" - -#include "UICommon/UICommon.h" - -static bool IsOsSupported() -{ -#ifdef Q_OS_OSX - return QSysInfo::MacintoshVersion >= QSysInfo::MV_10_9; -#elif defined(Q_OS_WIN) - return (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) >= QSysInfo::WV_VISTA; -#else - return true; -#endif -} - -static QString LowestSupportedOsVersion() -{ -#ifdef Q_OS_OSX - return QStringLiteral("Mac OS X 10.9"); -#elif defined(Q_OS_WIN) - return QStringLiteral("Windows Vista SP2"); -#else - return QStringLiteral("Unknown"); -#endif -} - -int main(int argc, char* argv[]) -{ - QApplication app(argc, argv); - app.setAttribute(Qt::AA_UseHighDpiPixmaps); - // TODO: Add command line options - - UICommon::SetUserDirectory(""); // Auto-detect user folder - UICommon::CreateDirectories(); - UICommon::Init(); - - if (!IsOsSupported()) - { - QMessageBox::critical(nullptr, QObject::tr("Unsupported OS"), - QObject::tr("Dolphin requires %1 or greater.\n" - "Please upgrade to %1 or greater to use Dolphin.") - .arg(LowestSupportedOsVersion())); - return 1; - } - - g_main_window = new DMainWindow(); - g_main_window->show(); - - int retcode = app.exec(); - delete g_main_window; - Core::Shutdown(); - UICommon::Shutdown(); - return retcode; -} diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp deleted file mode 100644 index 467337489d..0000000000 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ /dev/null @@ -1,379 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include -#include -#include -#include -#include -#include -#include - -#include "ui_MainWindow.h" - -#include "Core/BootManager.h" -#include "Core/ConfigManager.h" -#include "Core/HW/ProcessorInterface.h" - -#include "DolphinQt/AboutDialog.h" -#include "DolphinQt/Host.h" -#include "DolphinQt/MainWindow.h" -#include "DolphinQt/SystemInfo.h" -#include "DolphinQt/Utils/Resources.h" - -#include "VideoCommon/VideoConfig.h" - -// The "g_main_window" object as defined in MainWindow.h -DMainWindow* g_main_window = nullptr; - -DMainWindow::DMainWindow(QWidget* parent_widget) - : QMainWindow(parent_widget) -{ - m_ui = std::make_unique(); - m_ui->setupUi(this); - - Resources::Init(); - UpdateIcons(); - setWindowIcon(Resources::GetIcon(Resources::DOLPHIN_LOGO)); - - // Create the GameList - m_game_tracker = new DGameTracker(this); - m_ui->centralWidget->addWidget(m_game_tracker); - m_game_tracker->ScanForGames(); - m_game_tracker->SelectLastBootedGame(); - - // Setup the GameList style switching actions - QActionGroup* gamelistGroup = new QActionGroup(this); - gamelistGroup->addAction(m_ui->actionListView); - gamelistGroup->addAction(m_ui->actionTreeView); - gamelistGroup->addAction(m_ui->actionGridView); - gamelistGroup->addAction(m_ui->actionIconView); - - // TODO: save/load this from user prefs! - m_ui->actionListView->setChecked(true); - OnGameListStyleChanged(); - - // Connect all the signals/slots - connect(this, &DMainWindow::CoreStateChanged, this, &DMainWindow::OnCoreStateChanged); - - connect(m_ui->actionOpen, &QAction::triggered, this, [&]() { - QString filename = ShowFileDialog(); - if (!filename.isNull()) - StartGame(filename); - }); - connect(m_ui->actionBrowse, &QAction::triggered, this, &DMainWindow::OnBrowse); - connect(m_ui->actionExit, &QAction::triggered, this, [&]() { - close(); - }); - - connect(m_ui->actionListView, &QAction::triggered, this, &DMainWindow::OnGameListStyleChanged); - connect(m_ui->actionTreeView, &QAction::triggered, this, &DMainWindow::OnGameListStyleChanged); - connect(m_ui->actionGridView, &QAction::triggered, this, &DMainWindow::OnGameListStyleChanged); - connect(m_ui->actionIconView, &QAction::triggered, this, &DMainWindow::OnGameListStyleChanged); - - connect(m_ui->actionPlay, &QAction::triggered, this, &DMainWindow::OnPlay); - connect(m_game_tracker, &DGameTracker::StartGame, this, &DMainWindow::OnPlay); - connect(m_ui->actionStop, &QAction::triggered, this, &DMainWindow::OnStop); - connect(m_ui->actionReset, &QAction::triggered, this, &DMainWindow::OnReset); - connect(m_ui->actionScreenshot, &QAction::triggered, this, []() { - Core::SaveScreenShot(); - }); - - connect(m_ui->actionWebsite, &QAction::triggered, this, []() { - QDesktopServices::openUrl(QUrl(QStringLiteral("https://dolphin-emu.org/"))); - }); - connect(m_ui->actionOnlineDocs, &QAction::triggered, this, []() { - QDesktopServices::openUrl(QUrl(QStringLiteral("https://dolphin-emu.org/docs/guides/"))); - }); - connect(m_ui->actionGitHub, &QAction::triggered, this, []() { - QDesktopServices::openUrl(QUrl(QStringLiteral("https://github.com/dolphin-emu/dolphin"))); - }); - connect(m_ui->actionSystemInfo, &QAction::triggered, this, [&]() { - DSystemInfo* dlg = new DSystemInfo(this); - dlg->open(); - }); - connect(m_ui->actionAbout, &QAction::triggered, this, [&]() { - DAboutDialog* dlg = new DAboutDialog(this); - dlg->open(); - }); - connect(m_ui->actionAboutQt, &QAction::triggered, this, [&]() { - QApplication::aboutQt(); - }); - - // Update GUI items - emit CoreStateChanged(Core::CORE_UNINITIALIZED); - - // Platform-specific stuff -#ifdef Q_OS_MACX - m_ui->toolbar->setMovable(false); -#endif -} - -DMainWindow::~DMainWindow() -{ -} - -bool DMainWindow::event(QEvent* e) -{ - if (e->type() == HostEvent::TitleEvent) - { - HostTitleEvent* htev = (HostTitleEvent*)e; - m_ui->statusbar->showMessage(QString::fromStdString(htev->m_title), 1500); - return true; - } - return QMainWindow::event(e); -} - -void DMainWindow::closeEvent(QCloseEvent* ce) -{ - if (!OnStop()) - ce->ignore(); - else - QMainWindow::closeEvent(ce); -} - -// Emulation - -void DMainWindow::StartGame(const QString filename) -{ - m_render_widget = std::make_unique(); - m_render_widget->setWindowTitle(tr("Dolphin")); // TODO - m_render_widget->setWindowIcon(windowIcon()); - - if (SConfig::GetInstance().bFullscreen) - { - m_render_widget->setWindowFlags(m_render_widget->windowFlags() | Qt::BypassWindowManagerHint); - g_Config.bFullscreen = !g_Config.bBorderlessFullscreen; - m_render_widget->showFullScreen(); - } - else - { - m_ui->centralWidget->addWidget(m_render_widget.get()); - m_ui->centralWidget->setCurrentWidget(m_render_widget.get()); - - if (SConfig::GetInstance().bRenderWindowAutoSize) - { - // Resize main window to fit render - m_render_widget->setMinimumSize(SConfig::GetInstance().iRenderWindowWidth, - SConfig::GetInstance().iRenderWindowHeight); - qApp->processEvents(); // Force a redraw so the window has time to resize - m_render_widget->setMinimumSize(0, 0); // Allow the widget to scale down - } - m_render_widget->adjustSize(); - } - - if (!BootManager::BootCore(filename.toStdString())) - { - QMessageBox::critical(this, tr("Fatal error"), tr("Failed to init Core"), QMessageBox::Ok); - if (SConfig::GetInstance().bFullscreen) - m_render_widget->close(); - else - m_ui->centralWidget->removeWidget(m_render_widget.get()); - m_render_widget.reset(); - } - else - { - DisableScreensaver(); - emit CoreStateChanged(Core::CORE_RUN); - } -} - -void DMainWindow::DisableScreensaver() -{ -#ifdef Q_OS_WIN - // Prevents Windows from sleeping or turning off the display - SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED); -#endif -} - -void DMainWindow::EnableScreensaver() -{ -#ifdef Q_OS_WIN - // Allows Windows to sleep and turn off the display - SetThreadExecutionState(ES_CONTINUOUS); -#endif -} - -QString DMainWindow::RequestBootFilename() -{ - // If a game is already selected, just return the filename - if (m_game_tracker->SelectedGame() != nullptr) - return m_game_tracker->SelectedGame()->GetFileName(); - - return ShowFileDialog(); -} - -QString DMainWindow::ShowFileDialog() -{ - return QFileDialog::getOpenFileName(this, tr("Open File"), QString(), - tr("All supported ROMs (%1);;All files (*)") - .arg(QStringLiteral("*.gcm *.iso *.ciso *.gcz *.wbfs *.elf *.dol *.dff *.tmd *.wad"))); -} - -QString DMainWindow::ShowFolderDialog() -{ - return QFileDialog::getExistingDirectory(this, tr("Browse for a directory to add"), - QDir::homePath(), QFileDialog::ShowDirsOnly); -} - -void DMainWindow::DoStartPause() -{ - if (Core::GetState() == Core::CORE_RUN) - { - Core::SetState(Core::CORE_PAUSE); - emit CoreStateChanged(Core::CORE_PAUSE); - } - else - { - Core::SetState(Core::CORE_RUN); - emit CoreStateChanged(Core::CORE_RUN); - } - if (SConfig::GetInstance().bHideCursor) - m_render_widget->setCursor(Qt::BlankCursor); -} - -void DMainWindow::OnBrowse() -{ - std::string path = ShowFolderDialog().toStdString(); - std::vector& iso_folder = SConfig::GetInstance().m_ISOFolder; - if (!path.empty()) - { - auto itResult = std::find(iso_folder.begin(), iso_folder.end(), path); - - if (itResult == iso_folder.end()) - { - iso_folder.push_back(path); - SConfig::GetInstance().SaveSettings(); - } - } - m_game_tracker->ScanForGames(); -} - -void DMainWindow::OnPlay() -{ - if (Core::GetState() != Core::CORE_UNINITIALIZED) - { - DoStartPause(); - } - else - { - // initialize Core and boot the game - QString filename = RequestBootFilename(); - if (!filename.isNull()) - StartGame(filename); - } -} - -bool DMainWindow::OnStop() -{ - if (Core::GetState() == Core::CORE_UNINITIALIZED || m_isStopping) - return true; - - // Ask for confirmation in case the user accidentally clicked Stop / Escape - if (SConfig::GetInstance().bConfirmStop) - { - // Pause emulation if it isn't already - bool wasPaused = false; - if (Core::GetState() == Core::CORE_PAUSE) - { - wasPaused = true; - } - else - { - Core::SetState(Core::CORE_PAUSE); - emit CoreStateChanged(Core::CORE_PAUSE); - } - - QMessageBox::StandardButton ret = QMessageBox::question(m_render_widget.get(), tr("Please confirm..."), - tr("Do you want to stop the current emulation?"), - QMessageBox::Yes | QMessageBox::No, QMessageBox::No); - - if (ret == QMessageBox::No) - { - if (!wasPaused) - DoStartPause(); - return false; - } - } - - return Stop(); -} - -bool DMainWindow::Stop() -{ - m_isStopping = true; - - // TODO: Movie stuff - // TODO: Show the author/description dialog here - - BootManager::Stop(); - EnableScreensaver(); - // TODO: Restore original window title - - // TODO: - // If batch mode was specified on the command-line, exit now. - //if (m_bBatchMode) - // Close(true); - - if (SConfig::GetInstance().bFullscreen) - m_render_widget->close(); - else - m_ui->centralWidget->removeWidget(m_render_widget.get()); - m_render_widget.reset(); - - emit CoreStateChanged(Core::CORE_UNINITIALIZED); - m_isStopping = false; - return true; -} - -void DMainWindow::OnReset() -{ - // TODO: Movie needs to be reset here - ProcessorInterface::ResetButton_Tap(); -} - -void DMainWindow::OnGameListStyleChanged() -{ - if (m_ui->actionListView->isChecked()) - m_game_tracker->SetViewStyle(STYLE_LIST); - else if (m_ui->actionTreeView->isChecked()) - m_game_tracker->SetViewStyle(STYLE_TREE); - else if (m_ui->actionGridView->isChecked()) - m_game_tracker->SetViewStyle(STYLE_GRID); - else if (m_ui->actionIconView->isChecked()) - m_game_tracker->SetViewStyle(STYLE_ICON); -} - -void DMainWindow::OnCoreStateChanged(Core::EState state) -{ - bool is_not_initialized = (state == Core::CORE_UNINITIALIZED); - bool is_running = (state == Core::CORE_RUN); - bool is_paused = (state == Core::CORE_PAUSE); - - // Update the toolbar - m_ui->actionPlay->setEnabled(is_not_initialized || is_running || is_paused); - if (is_running) - { - m_ui->actionPlay->setIcon(Resources::GetIcon(Resources::TOOLBAR_PAUSE)); - m_ui->actionPlay->setText(tr("Pause")); - } - else if (is_paused || is_not_initialized) - { - m_ui->actionPlay->setIcon(Resources::GetIcon(Resources::TOOLBAR_PLAY)); - m_ui->actionPlay->setText(tr("Play")); - } - - m_ui->actionStop->setEnabled(!is_not_initialized); - m_ui->actionOpen->setEnabled(is_not_initialized); - m_game_tracker->setEnabled(is_not_initialized); -} - -// Update all the icons used in DMainWindow with fresh ones from -// "Resources". Call this function after changing the icon theme. -void DMainWindow::UpdateIcons() -{ - // Play/Pause is handled in OnCoreStateChanged(). - m_ui->actionStop->setIcon(Resources::GetIcon(Resources::TOOLBAR_STOP)); - m_ui->actionScreenshot->setIcon(Resources::GetIcon(Resources::TOOLBAR_SCREENSHOT)); -} diff --git a/Source/Core/DolphinQt/MainWindow.h b/Source/Core/DolphinQt/MainWindow.h deleted file mode 100644 index 0b2eb74b91..0000000000 --- a/Source/Core/DolphinQt/MainWindow.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include -#include - -#include "Core/Core.h" - -#include "DolphinQt/GameList/GameTracker.h" -#include "DolphinQt/VideoInterface/RenderWidget.h" - -// Predefinitions -namespace Ui -{ -class DMainWindow; -} - -class DMainWindow final : public QMainWindow -{ - Q_OBJECT - -public: - explicit DMainWindow(QWidget* parent_widget = nullptr); - ~DMainWindow(); - - // DRenderWidget - bool RenderWidgetHasFocus() const { return m_render_widget->isActiveWindow(); } - DRenderWidget* GetRenderWidget() { return m_render_widget.get(); } - -signals: - void CoreStateChanged(Core::EState state); - -public slots: - // Main toolbar (also used by DRenderWidget) - bool OnStop(); - -private slots: - // Emulation - void StartGame(const QString filename); - void OnCoreStateChanged(Core::EState state); - - // Main toolbar - void OnBrowse(); - void OnPlay(); - void OnReset(); - - // View menu - void OnGameListStyleChanged(); - - // Misc. - void UpdateIcons(); - -private: - bool event(QEvent* e) override; - void closeEvent(QCloseEvent* ce) override; - std::unique_ptr m_ui; - DGameTracker* m_game_tracker; - - // Misc. - void DisableScreensaver(); - void EnableScreensaver(); - // Emulation - QString RequestBootFilename(); - QString ShowFileDialog(); - QString ShowFolderDialog(); - void DoStartPause(); - bool Stop(); - - std::unique_ptr m_render_widget; - bool m_isStopping = false; -}; - -// Pointer to the only instance of DMainWindow, used by Host_* -extern DMainWindow* g_main_window; diff --git a/Source/Core/DolphinQt/MainWindow.ui b/Source/Core/DolphinQt/MainWindow.ui deleted file mode 100644 index 4f1a209d09..0000000000 --- a/Source/Core/DolphinQt/MainWindow.ui +++ /dev/null @@ -1,253 +0,0 @@ - - - DMainWindow - - - - 0 - 0 - 990 - 590 - - - - Dolphin - - - - 32 - 32 - - - - true - - - - - - 0 - 0 - 990 - 21 - - - - true - - - - Fi&le - - - - - - - - - - E&mulation - - - - - - - - - - Optio&ns - - - - - Tools - - - - - &View - - - - &List style - - - - - - - - - - - Help - - - - - - - - - - - - Movie - - - - - - - - - - - - - - Toolbar - - - Qt::ToolButtonTextUnderIcon - - - TopToolBarArea - - - false - - - - - - - - &Website - - - - - &Online Documentation - - - - - &GitHub Repository - - - - - &About - - - QAction::AboutRole - - - - - &Open... - - - Open file... - - - Ctrl+O - - - - - &System Information - - - - - Play - - - F10 - - - false - - - - - Stop - - - Esc - - - false - - - - - About &Qt - - - QAction::AboutQtRole - - - - - true - - - &List view - - - - - true - - - &Tree view - - - - - true - - - &Grid view - - - - - true - - - &Icon view - - - - - &Browse for ISOs... - - - - - Exit - - - - - &Reset - - - - - Screenshot - - - false - - - - - - diff --git a/Source/Core/DolphinQt/Resources/Dolphin.icns b/Source/Core/DolphinQt/Resources/Dolphin.icns deleted file mode 100644 index 4a17b18dec2d820f0bd4d7c3875ac2791c463457..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 103023 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

8{sHLS~a#eJ>+ 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 wdEU#c_H`x5L -#include -#include -#include - -#include "ui_SystemInfo.h" - -#include "Common/Common.h" -#include "Common/CPUDetect.h" - -#include "DolphinQt/SystemInfo.h" - -DSystemInfo::DSystemInfo(QWidget* parent_widget) : - QDialog(parent_widget) -{ - setWindowModality(Qt::WindowModal); - setAttribute(Qt::WA_DeleteOnClose); - - m_ui = std::make_unique(); - m_ui->setupUi(this); - - UpdateSystemInfo(); - - QPushButton* btn = m_ui->buttonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole); - connect(btn, &QPushButton::pressed, this, &DSystemInfo::CopyPressed); -} - -DSystemInfo::~DSystemInfo() -{ -} - -void DSystemInfo::CopyPressed() -{ - QClipboard* clipboard = QApplication::clipboard(); - clipboard->setText(m_ui->txtSysInfo->toPlainText()); -} - -void DSystemInfo::UpdateSystemInfo() -{ - QString sysinfo; - - sysinfo += QStringLiteral("System\n===========================\n"); - sysinfo += QStringLiteral("OS: %1\n").arg(GetOS()); - sysinfo += QStringLiteral("CPU: %1, %2 logical processors\n") - .arg(QString::fromStdString(cpu_info.Summarize())) - .arg(QThread::idealThreadCount()); - - sysinfo += QStringLiteral("\nDolphin\n===========================\n"); - sysinfo += QStringLiteral("SCM: branch %1, rev %2\n") - .arg(QString::fromUtf8(scm_branch_str)) - .arg(QString::fromUtf8(scm_rev_git_str)); - - sysinfo += QStringLiteral("\nGUI\n===========================\n"); - sysinfo += QStringLiteral("Compiled for Qt: %1\n").arg(QStringLiteral(QT_VERSION_STR)); - sysinfo += QStringLiteral("Running on Qt: %1").arg(QString::fromUtf8(qVersion())); - - m_ui->txtSysInfo->setPlainText(sysinfo); -} - -QString DSystemInfo::GetOS() const -{ - QString ret; - /* DON'T REORDER WITHOUT READING Qt DOCS! */ -#if defined(Q_OS_WIN) - ret += QStringLiteral("Windows "); - switch (QSysInfo::WindowsVersion) { - case QSysInfo::WV_VISTA: ret += QStringLiteral("Vista"); break; - case QSysInfo::WV_WINDOWS7: ret += QStringLiteral("7"); break; - case QSysInfo::WV_WINDOWS8: ret += QStringLiteral("8"); break; - case QSysInfo::WV_WINDOWS8_1: ret += QStringLiteral("8.1"); break; - case QSysInfo::WV_WINDOWS10: ret += QStringLiteral("10"); break; - default: ret += QStringLiteral("(unknown)"); break; - } -#elif defined(Q_OS_MAC) - ret += QStringLiteral("Mac OS X "); - switch (QSysInfo::MacintoshVersion) { - case QSysInfo::MV_10_9: ret += QStringLiteral("10.9"); break; - case QSysInfo::MV_10_10: ret += QStringLiteral("10.10"); break; - case QSysInfo::MV_10_11: ret += QStringLiteral("10.11"); break; - default: ret += QStringLiteral("(unknown)"); break; - } -#elif defined(Q_OS_LINUX) - ret += QStringLiteral("Linux"); -#elif defined(Q_OS_FREEBSD) - ret += QStringLiteral("FreeBSD"); -#elif defined(Q_OS_OPENBSD) - ret += QStringLiteral("OpenBSD"); -#elif defined(Q_OS_NETBSD) - ret += QStringLiteral("NetBSD"); -#elif defined(Q_OS_BSD4) - ret += QStringLiteral("Other BSD"); -#elif defined(Q_OS_UNIX) - ret += QStringLiteral("Unix"); -#else - ret += QStringLiteral("Unknown"); -#endif - -#if defined(Q_WS_X11) || defined(Q_OS_X11) - ret += QStringLiteral(" X11"); -#elif defined(Q_WS_WAYLAND) - ret += QStringLiteral(" Wayland"); -#endif - - return ret; -} diff --git a/Source/Core/DolphinQt/SystemInfo.h b/Source/Core/DolphinQt/SystemInfo.h deleted file mode 100644 index 3e010b0259..0000000000 --- a/Source/Core/DolphinQt/SystemInfo.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include -#include - -namespace Ui -{ -class DSystemInfo; -} - -class DSystemInfo final : public QDialog -{ - Q_OBJECT - -public: - explicit DSystemInfo(QWidget* parent_widget = nullptr); - ~DSystemInfo(); - -private slots: - void CopyPressed(); - -private: - std::unique_ptr m_ui; - - void UpdateSystemInfo(); - QString GetOS() const; -}; diff --git a/Source/Core/DolphinQt/SystemInfo.ui b/Source/Core/DolphinQt/SystemInfo.ui deleted file mode 100644 index 95506a9857..0000000000 --- a/Source/Core/DolphinQt/SystemInfo.ui +++ /dev/null @@ -1,71 +0,0 @@ - - - DSystemInfo - - - - 0 - 0 - 446 - 298 - - - - System Information - - - - - - true - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Close - - - - - - - - - buttonBox - accepted() - DSystemInfo - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - DSystemInfo - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/Source/Core/DolphinQt/Utils/Resources.cpp b/Source/Core/DolphinQt/Utils/Resources.cpp deleted file mode 100644 index f0f8784316..0000000000 --- a/Source/Core/DolphinQt/Utils/Resources.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include -#include - -#include "Common/CommonPaths.h" -#include "Common/FileUtil.h" -#include "Core/ConfigManager.h" - -#include "DolphinQt/Utils/Resources.h" - -QVector Resources::m_platforms; -QVector Resources::m_regions; -QVector Resources::m_ratings; -QVector Resources::m_pixmaps; - -void Resources::Init() -{ - QString dir = QString::fromStdString(File::GetSysDirectory() + RESOURCES_DIR + DIR_SEP); - - m_regions.resize(DiscIO::IVolume::NUMBER_OF_COUNTRIES); - m_regions[DiscIO::IVolume::COUNTRY_JAPAN].load(GetImageFilename("Flag_Japan", dir)); - m_regions[DiscIO::IVolume::COUNTRY_EUROPE].load(GetImageFilename("Flag_Europe", dir)); - m_regions[DiscIO::IVolume::COUNTRY_USA].load(GetImageFilename("Flag_USA", dir)); - - m_regions[DiscIO::IVolume::COUNTRY_AUSTRALIA].load(GetImageFilename("Flag_Australia", dir)); - m_regions[DiscIO::IVolume::COUNTRY_FRANCE].load(GetImageFilename("Flag_France", dir)); - m_regions[DiscIO::IVolume::COUNTRY_GERMANY].load(GetImageFilename("Flag_Germany", dir)); - m_regions[DiscIO::IVolume::COUNTRY_ITALY].load(GetImageFilename("Flag_Italy", dir)); - m_regions[DiscIO::IVolume::COUNTRY_KOREA].load(GetImageFilename("Flag_Korea", dir)); - m_regions[DiscIO::IVolume::COUNTRY_NETHERLANDS].load(GetImageFilename("Flag_Netherlands", dir)); - m_regions[DiscIO::IVolume::COUNTRY_RUSSIA].load(GetImageFilename("Flag_Russia", dir)); - m_regions[DiscIO::IVolume::COUNTRY_SPAIN].load(GetImageFilename("Flag_Spain", dir)); - m_regions[DiscIO::IVolume::COUNTRY_TAIWAN].load(GetImageFilename("Flag_Taiwan", dir)); - m_regions[DiscIO::IVolume::COUNTRY_WORLD].load(GetImageFilename("Flag_International", dir)); - m_regions[DiscIO::IVolume::COUNTRY_UNKNOWN].load(GetImageFilename("Flag_Unknown", dir)); - - m_platforms.resize(4); - m_platforms[0].load(GetImageFilename("Platform_Gamecube", dir)); - m_platforms[1].load(GetImageFilename("Platform_Wii", dir)); - m_platforms[2].load(GetImageFilename("Platform_Wad", dir)); - m_platforms[3].load(GetImageFilename("Platform_File", dir)); - - m_ratings.resize(6); - m_ratings[0].load(GetImageFilename("rating0", dir)); - m_ratings[1].load(GetImageFilename("rating1", dir)); - m_ratings[2].load(GetImageFilename("rating2", dir)); - m_ratings[3].load(GetImageFilename("rating3", dir)); - m_ratings[4].load(GetImageFilename("rating4", dir)); - m_ratings[5].load(GetImageFilename("rating5", dir)); - - m_pixmaps.resize(NUM_ICONS); - m_pixmaps[DOLPHIN_LOGO].load(GetImageFilename("Dolphin", dir)); - m_pixmaps[DOLPHIN_LOGO_LARGE].load(GetImageFilename("dolphin_logo", dir)); - m_pixmaps[BANNER_MISSING].load(GetImageFilename("nobanner", dir)); - UpdatePixmaps(); -} - -void Resources::UpdatePixmaps() -{ - QString dir = QString::fromStdString(File::GetThemeDir(SConfig::GetInstance().theme_name)); - m_pixmaps[TOOLBAR_OPEN].load(GetImageFilename("open", dir)); - m_pixmaps[TOOLBAR_REFRESH].load(GetImageFilename("refresh", dir)); - m_pixmaps[TOOLBAR_BROWSE].load(GetImageFilename("browse", dir)); - m_pixmaps[TOOLBAR_PLAY].load(GetImageFilename("play", dir)); - m_pixmaps[TOOLBAR_STOP].load(GetImageFilename("stop", dir)); - m_pixmaps[TOOLBAR_PAUSE].load(GetImageFilename("pause", dir)); - m_pixmaps[TOOLBAR_FULLSCREEN].load(GetImageFilename("fullscreen", dir)); - m_pixmaps[TOOLBAR_SCREENSHOT].load(GetImageFilename("screenshot", dir)); - m_pixmaps[TOOLBAR_CONFIGURE].load(GetImageFilename("config", dir)); - m_pixmaps[TOOLBAR_GRAPHICS].load(GetImageFilename("graphics", dir)); - m_pixmaps[TOOLBAR_CONTROLLERS].load(GetImageFilename("classic", dir)); - m_pixmaps[TOOLBAR_HELP].load(GetImageFilename("config", dir)); // TODO - // TODO: toolbar[MEMCARD]; - // TODO: toolbar[HOTKEYS]; -} - -QString Resources::GetImageFilename(const char* name, QString dir) -{ - QString fileName = QString::fromUtf8(name); - if (qApp->devicePixelRatio() >= 2) - { - fileName.prepend(dir).append(QStringLiteral("@2x.png")); - if (QFile::exists(fileName)) - return fileName; - } - return fileName.prepend(dir).append(QStringLiteral(".png")); -} - -QPixmap& Resources::GetRegionPixmap(DiscIO::IVolume::ECountry region) -{ - return m_regions[region]; -} - -QPixmap& Resources::GetPlatformPixmap(int console) -{ - if (console >= m_platforms.size() || console < 0) - return m_platforms[0]; - return m_platforms[console]; -} - -QPixmap& Resources::GetRatingPixmap(int rating) -{ - if (rating >= m_ratings.size() || rating < 0) - return m_ratings[0]; - return m_ratings[rating]; -} - -QPixmap& Resources::GetPixmap(int id) -{ - if (id >= m_pixmaps.size() || id < 0) - return m_pixmaps[0]; - return m_pixmaps[id]; -} - -QIcon Resources::GetIcon(int id) -{ - return QIcon(GetPixmap(id)); -} diff --git a/Source/Core/DolphinQt/Utils/Resources.h b/Source/Core/DolphinQt/Utils/Resources.h deleted file mode 100644 index 40a74455a2..0000000000 --- a/Source/Core/DolphinQt/Utils/Resources.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include -#include -#include - -#include "DiscIO/Volume.h" - -class Resources -{ -public: - static void Init(); - static void UpdatePixmaps(); - - static QPixmap& GetPlatformPixmap(int console); - static QPixmap& GetRegionPixmap(DiscIO::IVolume::ECountry region); - static QPixmap& GetRatingPixmap(int rating); - static QPixmap& GetPixmap(int id); - static QIcon GetIcon(int id); - - enum - { - TOOLBAR_OPEN = 0, - TOOLBAR_REFRESH, - TOOLBAR_BROWSE, - TOOLBAR_PLAY, - TOOLBAR_STOP, - TOOLBAR_PAUSE, - TOOLBAR_FULLSCREEN, - TOOLBAR_SCREENSHOT, - TOOLBAR_CONFIGURE, - TOOLBAR_GRAPHICS, - TOOLBAR_CONTROLLERS, - TOOLBAR_HELP, - MEMCARD, - HOTKEYS, - DOLPHIN_LOGO, - DOLPHIN_LOGO_LARGE, - BANNER_MISSING, - NUM_ICONS - }; - -private: - static QVector m_platforms; - static QVector m_regions; - static QVector m_ratings; - static QVector m_pixmaps; - - static QString GetImageFilename(const char* name, QString dir); -}; diff --git a/Source/Core/DolphinQt/Utils/Utils.cpp b/Source/Core/DolphinQt/Utils/Utils.cpp deleted file mode 100644 index b4497e4d6f..0000000000 --- a/Source/Core/DolphinQt/Utils/Utils.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include - -#include "Utils.h" - -QString NiceSizeFormat(s64 size) -{ - QStringList list = { - QStringLiteral("KB"), - QStringLiteral("MB"), - QStringLiteral("GB"), - QStringLiteral("TB"), - QStringLiteral("PB"), - QStringLiteral("EB") - }; - QStringListIterator i(list); - QString unit = QStringLiteral("b"); - double num = size; - while (num >= 1024.0 && i.hasNext()) - { - unit = i.next(); - num /= 1024.0; - } - return QStringLiteral("%1 %2").arg(QString::number(num, 'f', 1)).arg(unit); -} diff --git a/Source/Core/DolphinQt/Utils/Utils.h b/Source/Core/DolphinQt/Utils/Utils.h deleted file mode 100644 index 4ef7823525..0000000000 --- a/Source/Core/DolphinQt/Utils/Utils.h +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include - -#include "Common/CommonTypes.h" - -QString NiceSizeFormat(s64 size); diff --git a/Source/Core/DolphinQt/VideoInterface/RenderWidget.cpp b/Source/Core/DolphinQt/VideoInterface/RenderWidget.cpp deleted file mode 100644 index 5162d2b230..0000000000 --- a/Source/Core/DolphinQt/VideoInterface/RenderWidget.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include -#include - -#include "DolphinQt/MainWindow.h" -#include "DolphinQt/VideoInterface/RenderWidget.h" - -DRenderWidget::DRenderWidget(QWidget* parent_widget) - : QWidget(parent_widget) -{ - setAttribute(Qt::WA_NativeWindow, true); - setAttribute(Qt::WA_OpaquePaintEvent, true); - setAttribute(Qt::WA_NoSystemBackground, true); -} - -void DRenderWidget::closeEvent(QCloseEvent* e) -{ - if (!g_main_window->OnStop()) - { - e->ignore(); - return; - } - QWidget::closeEvent(e); -} diff --git a/Source/Core/DolphinQt/VideoInterface/RenderWidget.h b/Source/Core/DolphinQt/VideoInterface/RenderWidget.h deleted file mode 100644 index 67639e7322..0000000000 --- a/Source/Core/DolphinQt/VideoInterface/RenderWidget.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2014 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include - -class DRenderWidget final : public QWidget -{ - Q_OBJECT - -public: - DRenderWidget(QWidget* parent_widget = nullptr); - -protected: - // Some window managers start window dragging if an "empty" window area was clicked. - // Prevent this by intercepting the mouse press event. - void mousePressEvent(QMouseEvent*) override {} - void paintEvent(QPaintEvent*) override {} - -private: - void closeEvent(QCloseEvent* e) override; -}; - diff --git a/Source/dolphin-emu.sln b/Source/dolphin-emu.sln index f80da90dc2..3deb2a6ca2 100644 --- a/Source/dolphin-emu.sln +++ b/Source/dolphin-emu.sln @@ -5,8 +5,6 @@ VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dolphin", "Core\DolphinWX\DolphinWX.vcxproj", "{47411FDB-1BF2-48D0-AB4E-C7C41160F898}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DolphinQt", "Core\DolphinQt\DolphinQt.vcxproj", "{69D2B16E-122A-4E5D-8C37-8EC7B0F7CEB0}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Core", "Core\Core\Core.vcxproj", "{E54CF649-140E-4255-81A5-30A673C1FB36}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AudioCommon", "Core\AudioCommon\AudioCommon.vcxproj", "{54AA7840-5BEB-4A0C-9452-74BA4CC7FD44}"