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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

|&q865A=wcgqq7AqNr(9*atqWfpN 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 -#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}"