diff --git a/Source/Core/Common/CPUDetect.h b/Source/Core/Common/CPUDetect.h index 5d73be28ee..d66ace3c62 100644 --- a/Source/Core/Common/CPUDetect.h +++ b/Source/Core/Common/CPUDetect.h @@ -20,8 +20,8 @@ struct CPUInfo { CPUVendor vendor; - char cpu_string[0x21]; - char brand_string[0x41]; + char cpu_string[0x41]; + char brand_string[0x21]; bool OS64bit; bool CPU64bit; bool Mode64bit; diff --git a/Source/Core/Common/x64CPUDetect.cpp b/Source/Core/Common/x64CPUDetect.cpp index d0dab9a256..4150a4159f 100644 --- a/Source/Core/Common/x64CPUDetect.cpp +++ b/Source/Core/Common/x64CPUDetect.cpp @@ -102,25 +102,25 @@ void CPUInfo::Detect() // Assume CPU supports the CPUID instruction. Those that don't can barely // boot modern OS:es anyway. int cpu_id[4]; - memset(cpu_string, 0, sizeof(cpu_string)); + memset(brand_string, 0, sizeof(brand_string)); // Detect CPU's CPUID capabilities, and grab cpu string __cpuid(cpu_id, 0x00000000); u32 max_std_fn = cpu_id[0]; // EAX - *((int *)cpu_string) = cpu_id[1]; - *((int *)(cpu_string + 4)) = cpu_id[3]; - *((int *)(cpu_string + 8)) = cpu_id[2]; + *((int *)brand_string) = cpu_id[1]; + *((int *)(brand_string + 4)) = cpu_id[3]; + *((int *)(brand_string + 8)) = cpu_id[2]; __cpuid(cpu_id, 0x80000000); u32 max_ex_fn = cpu_id[0]; - if (!strcmp(cpu_string, "GenuineIntel")) + if (!strcmp(brand_string, "GenuineIntel")) vendor = VENDOR_INTEL; - else if (!strcmp(cpu_string, "AuthenticAMD")) + else if (!strcmp(brand_string, "AuthenticAMD")) vendor = VENDOR_AMD; else vendor = VENDOR_OTHER; // Set reasonable default brand string even if brand string not available. - strcpy(brand_string, cpu_string); + strcpy(cpu_string, brand_string); // Detect family and other misc stuff. bool ht = false; @@ -178,13 +178,13 @@ void CPUInfo::Detect() if (max_ex_fn >= 0x80000004) { - // Extract brand string + // Extract CPU model string __cpuid(cpu_id, 0x80000002); - memcpy(brand_string, cpu_id, sizeof(cpu_id)); + memcpy(cpu_string, cpu_id, sizeof(cpu_id)); __cpuid(cpu_id, 0x80000003); - memcpy(brand_string + 16, cpu_id, sizeof(cpu_id)); + memcpy(cpu_string + 16, cpu_id, sizeof(cpu_id)); __cpuid(cpu_id, 0x80000004); - memcpy(brand_string + 32, cpu_id, sizeof(cpu_id)); + memcpy(cpu_string + 32, cpu_id, sizeof(cpu_id)); } if (max_ex_fn >= 0x80000001) { @@ -229,6 +229,10 @@ void CPUInfo::Detect() std::string CPUInfo::Summarize() { std::string sum(cpu_string); + sum += " ("; + sum += brand_string; + sum += ")"; + if (bSSE) sum += ", SSE"; if (bSSE2) { diff --git a/Source/Core/DolphinQt/AboutDialog.cpp b/Source/Core/DolphinQt/AboutDialog.cpp index f76fe2decc..0e8f30d355 100644 --- a/Source/Core/DolphinQt/AboutDialog.cpp +++ b/Source/Core/DolphinQt/AboutDialog.cpp @@ -5,29 +5,27 @@ #include #include -#include "AboutDialog.h" #include "ui_AboutDialog.h" + #include "Common/Common.h" #include "Common/StdMakeUnique.h" -DAboutDialog::DAboutDialog(QWidget* p) - : QDialog(p) +#include "DolphinQt/AboutDialog.h" +#include "DolphinQt/Utils/Utils.h" + +DAboutDialog::DAboutDialog(QWidget* parent_widget) + : QDialog(parent_widget) { - ui = std::make_unique(); - ui->setupUi(this); - ui->label->setText(ui->label->text().arg(QLatin1String(scm_desc_str), - QStringLiteral("2014"), - QLatin1String(scm_branch_str), - QLatin1String(scm_rev_git_str), - QStringLiteral(__DATE__), - QStringLiteral(__TIME__))); + setWindowModality(Qt::WindowModal); + setAttribute(Qt::WA_DeleteOnClose); + + m_ui = std::make_unique(); + m_ui->setupUi(this); + m_ui->label->setText(m_ui->label->text().arg(SC(scm_desc_str), + SL("2014"), SC(scm_branch_str), SC(scm_rev_git_str), + SL(__DATE__), SL(__TIME__))); } DAboutDialog::~DAboutDialog() { } - -void DAboutDialog::on_label_linkActivated(const QString &link) -{ - QDesktopServices::openUrl(QUrl(link)); -} diff --git a/Source/Core/DolphinQt/AboutDialog.h b/Source/Core/DolphinQt/AboutDialog.h index 74b13e0a0a..6f5988aad0 100644 --- a/Source/Core/DolphinQt/AboutDialog.h +++ b/Source/Core/DolphinQt/AboutDialog.h @@ -17,12 +17,9 @@ class DAboutDialog : public QDialog Q_OBJECT public: - explicit DAboutDialog(QWidget* p = nullptr); + explicit DAboutDialog(QWidget* parent_widget = nullptr); ~DAboutDialog(); -private slots: - void on_label_linkActivated(const QString& link); - private: - std::unique_ptr ui; + std::unique_ptr m_ui; }; diff --git a/Source/Core/DolphinQt/AboutDialog.ui b/Source/Core/DolphinQt/AboutDialog.ui index 339140d79c..df77fa4686 100644 --- a/Source/Core/DolphinQt/AboutDialog.ui +++ b/Source/Core/DolphinQt/AboutDialog.ui @@ -6,57 +6,39 @@ 0 0 - 375 - 534 + 504 + 458 - + 0 0 - - - 375 - 0 - - - - - 375 - 16777215 - - About Dolphin - - + + - - - 0 - 0 - - <big><b>Dolphin</b></big> %1<br> © 2003-%2 Dolphin Team<br> Branch: %3<br> Revision: %4<br> Compiled: %5 @ %6<br> -Dolphin is a GameCube/Wii emulator, which was originally written by F|RES and ector. Today Dolphin is an open source project with many contributors, too many to list. If interested, just go check out <a href="https://github.com/dolphin-emu/dolphin">the project page</a>.<br> +Dolphin is a GameCube/Wii emulator, which was originally written by<br>F|RES and ector. Today Dolphin is an open source project with many<br> contributors, too many to list. If interested, just go check out <a href="https://github.com/dolphin-emu/dolphin">the project<br>page</a>.<br> <br> -Special thanks to Bushing, Costis, CrowTRobo, Marcan, Segher, Titanik, or9, and Hotquik for their reverse engineering and docs/demos.<br> +Special thanks to Bushing, Costis, CrowTRobo, Marcan, Segher, Titanik,<br>or9, and Hotquik for their reverse engineering and docs/demos.<br> <br> -Big thanks to Gilles Mouchard whose Microlib PPC emulator gave our development a kickstart.<br> +Big thanks to Gilles Mouchard whose Microlib PPC emulator gave our<br> development a kickstart.<br> <br> -Thanks to Frank Wille for his PowerPC disassembler, which or9 and we modified to include Gekko specifics.<br> +Thanks to Frank Wille for his PowerPC disassembler, which or9 and we<br> modified to include Gekko specifics.<br> <br> Thanks to hcs/destop for their GC ADPCM decoder.<br> <br> -We are not affiliated with Nintendo in any way. GameCube and Wii are trademarks of Nintendo. This emulator should not be used to play games you do not legally own. +We are not affiliated with Nintendo in any way. GameCube and Wii are<br> trademarks of Nintendo. This emulator should not be used to play games<br>you do not legally own. Qt::RichText @@ -64,12 +46,12 @@ We are not affiliated with Nintendo in any way. GameCube and Wii are trademarks Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - + true - + Qt::Horizontal diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index 8bbd09ed2f..96db4ebcca 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -7,21 +7,35 @@ set(CMAKE_AUTOMOC ON) set(SRCS AboutDialog.cpp AboutDialog.h + Host.cpp Main.cpp MainWindow.cpp MainWindow.h - Host.cpp + SystemInfo.cpp Utils/Resources.cpp Utils/Utils.cpp - VideoInterface/VideoInterface.cpp) + VideoInterface/VideoInterface.cpp + ) set(UIS AboutDialog.ui - MainWindow.ui) + MainWindow.ui + SystemInfo.ui + ) set(LIBS core uicommon) if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + # Link against OS X system frameworks. + list(APPEND LIBS + ${APPKIT_LIBRARY} + ${AU_LIBRARY} + ${COREAUDIO_LIBRARY} + ${COREFUND_LIBRARY} + ${CORESERV_LIBRARY} + ${IOK_LIBRARY} + ${FORCEFEEDBACK} + ) set(DOLPHINQT_BINARY DolphinQt) else() set(DOLPHINQT_BINARY dolphin-emu-qt) @@ -31,3 +45,46 @@ 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(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + # 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) + fixup_bundle(\"${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(CopyDataIntoBundle ALL + DEPENDS ${BUNDLE_PATH}/Contents/Resources/Sys + ) + endif() +endif() diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index 7399f17771..08b4484179 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -61,11 +61,14 @@ + + + diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj.filters b/Source/Core/DolphinQt/DolphinQt.vcxproj.filters index d94c197d64..e81be15e09 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj.filters +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj.filters @@ -14,10 +14,12 @@ Utils + + diff --git a/Source/Core/DolphinQt/Info.plist.in b/Source/Core/DolphinQt/Info.plist.in new file mode 100644 index 0000000000..aa3f6cb7e2 --- /dev/null +++ b/Source/Core/DolphinQt/Info.plist.in @@ -0,0 +1,80 @@ + + + + + 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/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index b67ec2198a..62382e10c5 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -11,17 +11,22 @@ #include "DolphinQt/AboutDialog.h" #include "DolphinQt/MainWindow.h" +#include "DolphinQt/SystemInfo.h" #include "DolphinQt/Utils/Resources.h" #include "DolphinQt/Utils/Utils.h" DMainWindow::DMainWindow(QWidget* parent_widget) : QMainWindow(parent_widget) { - ui = std::make_unique(); - ui->setupUi(this); + m_ui = std::make_unique(); + m_ui->setupUi(this); Resources::Init(); - ui->actOpen->setIcon(Resources::GetIcon(Resources::TOOLBAR_OPEN)); + m_ui->actOpen->setIcon(Resources::GetIcon(Resources::TOOLBAR_OPEN)); + +#ifdef Q_OS_MACX + m_ui->toolbar->setMovable(false); +#endif } DMainWindow::~DMainWindow() @@ -43,8 +48,14 @@ void DMainWindow::on_actGitHub_triggered() QDesktopServices::openUrl(QUrl(SL("https://github.com/dolphin-emu/dolphin/"))); } +void DMainWindow::on_actSystemInfo_triggered() +{ + DSystemInfo* dlg = new DSystemInfo(this); + dlg->open(); +} + void DMainWindow::on_actAbout_triggered() { - DAboutDialog dlg; - dlg.exec(); + DAboutDialog* dlg = new DAboutDialog(this); + dlg->open(); } diff --git a/Source/Core/DolphinQt/MainWindow.h b/Source/Core/DolphinQt/MainWindow.h index d7db3b6294..286dc4fae8 100644 --- a/Source/Core/DolphinQt/MainWindow.h +++ b/Source/Core/DolphinQt/MainWindow.h @@ -26,8 +26,9 @@ private slots: void on_actWebsite_triggered(); void on_actOnlineDocs_triggered(); void on_actGitHub_triggered(); + void on_actSystemInfo_triggered(); void on_actAbout_triggered(); private: - std::unique_ptr ui; + std::unique_ptr m_ui; }; diff --git a/Source/Core/DolphinQt/MainWindow.ui b/Source/Core/DolphinQt/MainWindow.ui index 7172fc4424..c63d5610c0 100644 --- a/Source/Core/DolphinQt/MainWindow.ui +++ b/Source/Core/DolphinQt/MainWindow.ui @@ -6,8 +6,8 @@ 0 0 - 996 - 596 + 992 + 592 @@ -31,8 +31,8 @@ 0 0 - 996 - 21 + 992 + 24 @@ -69,6 +69,7 @@ + @@ -87,7 +88,7 @@ - toolBar + Toolbar TopToolBarArea @@ -119,11 +120,19 @@ - Open + &Open Open file... + + Ctrl+O + + + + + &System Information + diff --git a/Source/Core/DolphinQt/Resources/Dolphin.icns b/Source/Core/DolphinQt/Resources/Dolphin.icns new file mode 100644 index 0000000000..4a17b18dec Binary files /dev/null and b/Source/Core/DolphinQt/Resources/Dolphin.icns differ diff --git a/Source/Core/DolphinQt/SystemInfo.cpp b/Source/Core/DolphinQt/SystemInfo.cpp new file mode 100644 index 0000000000..ca9ff2e07f --- /dev/null +++ b/Source/Core/DolphinQt/SystemInfo.cpp @@ -0,0 +1,106 @@ +// Copyright 2014 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include +#include +#include + +#include "ui_SystemInfo.h" + +#include "Common/Common.h" +#include "Common/CPUDetect.h" +#include "Common/StdMakeUnique.h" + +#include "DolphinQt/SystemInfo.h" +#include "DolphinQt/Utils/Utils.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, SIGNAL(pressed()), this, SLOT(btnCopy_pressed())); +} + +DSystemInfo::~DSystemInfo() +{ +} + +void DSystemInfo::btnCopy_pressed() +{ + QClipboard* clipboard = QApplication::clipboard(); + clipboard->setText(m_ui->txtSysInfo->toPlainText()); +} + +void DSystemInfo::UpdateSystemInfo() +{ + QString sysinfo; + + sysinfo += SL("System\n===========================\n"); + sysinfo += SL("OS: %1\n").arg(GetOS()); + sysinfo += SL("CPU: %1, %2 cores\n").arg(QString::fromStdString(cpu_info.Summarize())) + .arg(QThread::idealThreadCount()); + + sysinfo += SL("\nDolphin\n===========================\n"); + sysinfo += SL("SCM: branch %1, rev %2\n").arg(SC(scm_branch_str)).arg(SC(scm_rev_git_str)); + sysinfo += SL("Compiled: %1, %2\n").arg(SL(__DATE__)).arg(SL(__TIME__)); + + sysinfo += SL("\nGUI\n===========================\n"); + sysinfo += SL("Compiled for Qt: %1\n").arg(SL(QT_VERSION_STR)); + sysinfo += SL("Running on Qt: %1").arg(SC(qVersion())); + + m_ui->txtSysInfo->setPlainText(sysinfo); +} + +QString DSystemInfo::GetOS() +{ + QString ret; + /* DON'T REORDER WITHOUT READING Qt DOCS! */ +#if defined(Q_OS_WIN) + ret += SL("Windows "); + switch (QSysInfo::WindowsVersion) { + case QSysInfo::WV_VISTA: ret += SL("Vista"); break; + case QSysInfo::WV_WINDOWS7: ret += SL("7"); break; + case QSysInfo::WV_WINDOWS8: ret += SL("8"); break; + default: ret += SL("(unknown)"); break; + } +#elif defined(Q_OS_MAC) + ret += SL("Mac OS X "); + switch (QSysInfo::MacintoshVersion) { + case QSysInfo::MV_10_7: ret += SL("10.7"); break; + case QSysInfo::MV_10_8: ret += SL("10.8"); break; + case QSysInfo::MV_10_9: ret += SL("10.9"); break; + default: ret += SL("(unknown)"); break; + } +#elif defined(Q_OS_LINUX) + ret += SL("Linux"); +#elif defined(Q_OS_FREEBSD) + ret += SL("FreeBSD"); +#elif defined(Q_OS_OPENBSD) + ret += SL("OpenBSD"); +#elif defined(Q_OS_NETBSD) + ret += SL("NetBSD"); +#elif defined(Q_OS_BSD4) + ret += SL("Other BSD"); +#elif defined(Q_OS_UNIX) + ret += SL("Unix"); +#else + ret += SL("Unknown"); +#endif + +#if defined(Q_WS_X11) || defined(Q_OS_X11) + ret += SL(" X11"); +#elif defined(Q_WS_WAYLAND) + ret += SL(" Wayland"); +#endif + + return ret; +} diff --git a/Source/Core/DolphinQt/SystemInfo.h b/Source/Core/DolphinQt/SystemInfo.h new file mode 100644 index 0000000000..fc34ab7517 --- /dev/null +++ b/Source/Core/DolphinQt/SystemInfo.h @@ -0,0 +1,31 @@ +// 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 : public QDialog +{ + Q_OBJECT + +public: + explicit DSystemInfo(QWidget* parent_widget = nullptr); + ~DSystemInfo(); + +private slots: + void btnCopy_pressed(); + +private: + std::unique_ptr m_ui; + + void UpdateSystemInfo(); + QString GetOS(); +}; diff --git a/Source/Core/DolphinQt/SystemInfo.ui b/Source/Core/DolphinQt/SystemInfo.ui new file mode 100644 index 0000000000..95506a9857 --- /dev/null +++ b/Source/Core/DolphinQt/SystemInfo.ui @@ -0,0 +1,71 @@ + + + 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/Utils.h b/Source/Core/DolphinQt/Utils/Utils.h index 9591d4dd98..8b149c6fe8 100644 --- a/Source/Core/DolphinQt/Utils/Utils.h +++ b/Source/Core/DolphinQt/Utils/Utils.h @@ -8,7 +8,11 @@ #include "Common/CommonTypes.h" -// Shorter version of QStringLiteral(str) +// Use this to encapsulate ASCII string literals #define SL(str) QStringLiteral(str) +// Use this to encapsulate string constants and functions that +// return "char*"s +#define SC(str) QString::fromLatin1(str) + QString NiceSizeFormat(s64 size);