New code style refactor

This commit is contained in:
Jack Andersen 2018-12-07 19:19:40 -10:00
parent a1ed397436
commit 39a8b1608d
24 changed files with 2019 additions and 2329 deletions

View File

@ -16,148 +16,130 @@ const QString CurPlatformString = QStringLiteral("linux");
#error HECL does not know which OS to fetch for #error HECL does not know which OS to fetch for
#endif #endif
QString PlatformToString(Platform plat) QString PlatformToString(Platform plat) {
{ switch (plat) {
switch (plat) case Platform::MacOS:
{ return QStringLiteral("macos");
case Platform::MacOS: case Platform::Win32:
return QStringLiteral("macos"); return QStringLiteral("win32");
case Platform::Win32: case Platform::Linux:
return QStringLiteral("win32"); return QStringLiteral("linux");
case Platform::Linux: default:
return QStringLiteral("linux"); return QString();
default: }
return QString();
}
} }
Architecture CurArchitecture = Architecture::Invalid; Architecture CurArchitecture = Architecture::Invalid;
QString CurArchitectureString; QString CurArchitectureString;
Platform StringToPlatform(const QString& str) Platform StringToPlatform(const QString& str) {
{ for (int i = 1; i < int(Platform::MAXPlatform); ++i)
for (int i = 1; i < int(Platform::MAXPlatform); ++i) if (!str.compare(PlatformToString(Platform(i)), Qt::CaseInsensitive))
if (!str.compare(PlatformToString(Platform(i)), Qt::CaseInsensitive)) return Platform(i);
return Platform(i); return Platform::Invalid;
return Platform::Invalid;
} }
QString ArchitectureToString(Architecture arch) QString ArchitectureToString(Architecture arch) {
{ switch (arch) {
switch (arch) case Architecture::X86:
{ return QStringLiteral("x86");
case Architecture::X86: case Architecture::X86_64:
return QStringLiteral("x86"); return QStringLiteral("x86_64");
case Architecture::X86_64: case Architecture::ARM:
return QStringLiteral("x86_64"); return QStringLiteral("arm");
case Architecture::ARM: case Architecture::AARCH64:
return QStringLiteral("arm"); return QStringLiteral("aarch64");
case Architecture::AARCH64: default:
return QStringLiteral("aarch64"); return QString();
default: }
return QString();
}
} }
Architecture StringToArchitecture(const QString& str) Architecture StringToArchitecture(const QString& str) {
{ for (int i = 1; i < int(Architecture::MAXArchitecture); ++i)
for (int i = 1; i < int(Architecture::MAXArchitecture); ++i) if (!str.compare(ArchitectureToString(Architecture(i)), Qt::CaseInsensitive))
if (!str.compare(ArchitectureToString(Architecture(i)), Qt::CaseInsensitive)) return Architecture(i);
return Architecture(i); return Architecture::Invalid;
return Architecture::Invalid;
} }
QString VectorISAToString(VectorISA visa) QString VectorISAToString(VectorISA visa) {
{ switch (visa) {
switch (visa) case VectorISA::X87:
{ return QStringLiteral("x87");
case VectorISA::X87: case VectorISA::SSE:
return QStringLiteral("x87"); return QStringLiteral("sse");
case VectorISA::SSE: case VectorISA::SSE2:
return QStringLiteral("sse"); return QStringLiteral("sse2");
case VectorISA::SSE2: case VectorISA::SSE3:
return QStringLiteral("sse2"); return QStringLiteral("sse3");
case VectorISA::SSE3: case VectorISA::SSE41:
return QStringLiteral("sse3"); return QStringLiteral("sse41");
case VectorISA::SSE41: case VectorISA::AVX:
return QStringLiteral("sse41"); return QStringLiteral("avx");
case VectorISA::AVX: case VectorISA::AVX2:
return QStringLiteral("avx"); return QStringLiteral("avx2");
case VectorISA::AVX2: default:
return QStringLiteral("avx2"); return QString();
default: }
return QString();
}
} }
VectorISA StringToVectorISA(const QString& str) VectorISA StringToVectorISA(const QString& str) {
{ for (int i = 1; i < int(VectorISA::MAXVectorISA); ++i)
for (int i = 1; i < int(VectorISA::MAXVectorISA); ++i) if (!str.compare(VectorISAToString(VectorISA(i)), Qt::CaseInsensitive))
if (!str.compare(VectorISAToString(VectorISA(i)), Qt::CaseInsensitive)) return VectorISA(i);
return VectorISA(i); return VectorISA::Invalid;
return VectorISA::Invalid;
} }
URDEVersion::URDEVersion(const QString& filename) URDEVersion::URDEVersion(const QString& filename) {
{ int idx;
int idx; QString useFilename = filename;
QString useFilename = filename; if ((idx = filename.indexOf('.')) >= 0) {
if ((idx = filename.indexOf('.')) >= 0) m_extension = QString(filename).remove(0, idx);
{ useFilename.truncate(idx);
m_extension = QString(filename).remove(0, idx); }
useFilename.truncate(idx); QStringList list = useFilename.split('-');
} if (list.size() >= 2)
QStringList list = useFilename.split('-'); m_version = list[1].toInt();
if (list.size() >= 2) if (list.size() >= 3)
m_version = list[1].toInt(); m_platform = StringToPlatform(list[2]);
if (list.size() >= 3) if (list.size() >= 4)
m_platform = StringToPlatform(list[2]); m_architecture = StringToArchitecture(list[3]);
if (list.size() >= 4) if (list.size() >= 5)
m_architecture = StringToArchitecture(list[3]); m_vectorISA = StringToVectorISA(list[4]);
if (list.size() >= 5)
m_vectorISA = StringToVectorISA(list[4]);
} }
QString URDEVersion::fileString(bool withExtension) const QString URDEVersion::fileString(bool withExtension) const {
{ if (m_version < 0)
if (m_version < 0) return {};
return {}; if (withExtension && !m_extension.isEmpty())
if (withExtension && !m_extension.isEmpty()) return QString("urde-%1-%2-%3-%4%5")
return QString("urde-%1-%2-%3-%4%5").arg(QString::number(m_version), .arg(QString::number(m_version), PlatformToString(m_platform), ArchitectureToString(m_architecture),
PlatformToString(m_platform), VectorISAToString(m_vectorISA), m_extension);
ArchitectureToString(m_architecture), else
VectorISAToString(m_vectorISA), return QString("urde-%1-%2-%3-%4")
m_extension); .arg(QString::number(m_version), PlatformToString(m_platform), ArchitectureToString(m_architecture),
else VectorISAToString(m_vectorISA));
return QString("urde-%1-%2-%3-%4").arg(QString::number(m_version),
PlatformToString(m_platform),
ArchitectureToString(m_architecture),
VectorISAToString(m_vectorISA));
} }
#ifndef _WIN32 #ifndef _WIN32
static void HUPHandler(int) {} static void HUPHandler(int) {}
#endif #endif
void InitializePlatform() void InitializePlatform() {
{
#ifndef _WIN32 #ifndef _WIN32
/* This can happen when terminating hecl - do nothing */ /* This can happen when terminating hecl - do nothing */
signal(SIGHUP, HUPHandler); signal(SIGHUP, HUPHandler);
#endif #endif
#if ZEUS_ARCH_X86_64 #if ZEUS_ARCH_X86_64
const_cast<Architecture&>(CurArchitecture) = Architecture::X86_64; const_cast<Architecture&>(CurArchitecture) = Architecture::X86_64;
#elif ZEUS_ARCH_X86 #elif ZEUS_ARCH_X86
#if !defined(__APPLE__) && !defined(_WIN32) #if !defined(__APPLE__) && !defined(_WIN32)
const_cast<Architecture&>(CurArchitecture) = const_cast<Architecture&>(CurArchitecture) = (sysconf(_SC_WORD_BIT) == 64 ? Architecture::X86_64 : Architecture::X86);
(sysconf(_SC_WORD_BIT) == 64 ? Architecture::X86_64 : Architecture::X86);
#elif _WIN32 #elif _WIN32
bool isWOW = false; bool isWOW = false;
IsWow64Process(GetCurrentProcess(), &isWOW); IsWow64Process(GetCurrentProcess(), &isWOW);
const_cast<Architecture&>(CurArchitecture) = const_cast<Architecture&>(CurArchitecture) = (isWOW ? Architecture::X86_64 : Architecture::X86);
(isWOW ? Architecture::X86_64 : Architecture::X86);
#endif #endif
#endif #endif
const_cast<QString&>(CurArchitectureString) = ArchitectureToString(CurArchitecture); const_cast<QString&>(CurArchitectureString) = ArchitectureToString(CurArchitecture);
} }

View File

@ -4,14 +4,7 @@
#include <QMetaType> #include <QMetaType>
#include "zeus/Math.hpp" #include "zeus/Math.hpp"
enum class Platform enum class Platform { Invalid, MacOS, Win32, Linux, MAXPlatform };
{
Invalid,
MacOS,
Win32,
Linux,
MAXPlatform
};
QString PlatformToString(Platform plat); QString PlatformToString(Platform plat);
Platform StringToPlatform(const QString& str); Platform StringToPlatform(const QString& str);
@ -25,54 +18,34 @@ constexpr Platform CurPlatform = Platform::Linux;
extern const QString CurPlatformString; extern const QString CurPlatformString;
enum class Architecture enum class Architecture { Invalid, X86, X86_64, ARM, AARCH64, MAXArchitecture };
{
Invalid,
X86,
X86_64,
ARM,
AARCH64,
MAXArchitecture
};
QString ArchitectureToString(Architecture arch); QString ArchitectureToString(Architecture arch);
Architecture StringToArchitecture(const QString& str); Architecture StringToArchitecture(const QString& str);
extern Architecture CurArchitecture; extern Architecture CurArchitecture;
extern QString CurArchitectureString; extern QString CurArchitectureString;
enum class VectorISA enum class VectorISA { Invalid, X87, SSE, SSE2, SSE3, SSE41, AVX, AVX2, MAXVectorISA };
{
Invalid,
X87,
SSE,
SSE2,
SSE3,
SSE41,
AVX,
AVX2,
MAXVectorISA
};
QString VectorISAToString(VectorISA visa); QString VectorISAToString(VectorISA visa);
VectorISA StringToVectorISA(const QString& str); VectorISA StringToVectorISA(const QString& str);
class URDEVersion class URDEVersion {
{ int m_version = -1;
int m_version = -1; Platform m_platform = CurPlatform;
Platform m_platform = CurPlatform; Architecture m_architecture = CurArchitecture;
Architecture m_architecture = CurArchitecture; VectorISA m_vectorISA = VectorISA::Invalid;
VectorISA m_vectorISA = VectorISA::Invalid; QString m_extension;
QString m_extension;
public: public:
URDEVersion() = default; URDEVersion() = default;
explicit URDEVersion(const QString& filename); explicit URDEVersion(const QString& filename);
bool isValid() const { return m_version >= 0; } bool isValid() const { return m_version >= 0; }
QString fileString(bool withExtension) const; QString fileString(bool withExtension) const;
int getVersion() const { return m_version; } int getVersion() const { return m_version; }
Platform getPlatform() const { return m_platform; } Platform getPlatform() const { return m_platform; }
Architecture getArchitecture() const { return m_architecture; } Architecture getArchitecture() const { return m_architecture; }
VectorISA getVectorISA() const { return m_vectorISA; } VectorISA getVectorISA() const { return m_vectorISA; }
}; };
Q_DECLARE_METATYPE(URDEVersion); Q_DECLARE_METATYPE(URDEVersion);
void InitializePlatform(); void InitializePlatform();

View File

@ -6,179 +6,153 @@
#if KEY_PINNING #if KEY_PINNING
static const char AxioDLPublicKeyPEM[] = static const char AxioDLPublicKeyPEM[] =
"-----BEGIN PUBLIC KEY-----\n" "-----BEGIN PUBLIC KEY-----\n"
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvtshImzoP1a++9P5RK0k\n" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvtshImzoP1a++9P5RK0k\n"
"btTOpwie7O7S/wWFZxwwbMezEPhjw2uu86TPqJe3P/1v+6xRKrEf9zFn/sKNygvD\n" "btTOpwie7O7S/wWFZxwwbMezEPhjw2uu86TPqJe3P/1v+6xRKrEf9zFn/sKNygvD\n"
"bO64ZkJre4M46IYd0XxwIhiu7PBR+13CD+fqbrbYwPkoG090CP4MtZZN6mt5NAKB\n" "bO64ZkJre4M46IYd0XxwIhiu7PBR+13CD+fqbrbYwPkoG090CP4MtZZN6mt5NAKB\n"
"QHoIj0wV5K/jJE9cBQxViwOqrxK05Cl/ivy0gRtpL7Ot6S+QHL3++rb6U2hWydIQ\n" "QHoIj0wV5K/jJE9cBQxViwOqrxK05Cl/ivy0gRtpL7Ot6S+QHL3++rb6U2hWydIQ\n"
"kS+ucufKCIL77RcDwAc9vwNvzxf9EUU2pmq+EsEtLgRw3fR6BInoltOI8P9X5Wo6\n" "kS+ucufKCIL77RcDwAc9vwNvzxf9EUU2pmq+EsEtLgRw3fR6BInoltOI8P9X5Wo6\n"
"/skeg92xZA++vv0neq5gjjDfa2A1zDgJRysz3Xps/AMlLOe55XCzXse9BpvChT+Z\n" "/skeg92xZA++vv0neq5gjjDfa2A1zDgJRysz3Xps/AMlLOe55XCzXse9BpvChT+Z\n"
"pwIDAQAB\n" "pwIDAQAB\n"
"-----END PUBLIC KEY-----\n"; "-----END PUBLIC KEY-----\n";
static const QSslKey AxioDLPublicKey = static const QSslKey AxioDLPublicKey = QSslKey({AxioDLPublicKeyPEM}, QSsl::Rsa, QSsl::Pem, QSsl::PublicKey);
QSslKey({AxioDLPublicKeyPEM}, QSsl::Rsa, QSsl::Pem, QSsl::PublicKey);
static const char AxioDLEdgePublicKeyPEM[] = static const char AxioDLEdgePublicKeyPEM[] =
"-----BEGIN PUBLIC KEY-----\n" "-----BEGIN PUBLIC KEY-----\n"
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4a8ZLg3LRU0FiK6m8g2pT3qVBTMA\n" "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4a8ZLg3LRU0FiK6m8g2pT3qVBTMA\n"
"K2Uu5VGl7iamdGpUjynQ4uYWMx+WXf2Qkh7UZZgYvA6UeWHEs3M6ME8T6g==\n" "K2Uu5VGl7iamdGpUjynQ4uYWMx+WXf2Qkh7UZZgYvA6UeWHEs3M6ME8T6g==\n"
"-----END PUBLIC KEY-----\n"; "-----END PUBLIC KEY-----\n";
static const QSslKey AxioDLEdgePublicKey = static const QSslKey AxioDLEdgePublicKey = QSslKey({AxioDLEdgePublicKeyPEM}, QSsl::Ec, QSsl::Pem, QSsl::PublicKey);
QSslKey({AxioDLEdgePublicKeyPEM}, QSsl::Ec, QSsl::Pem, QSsl::PublicKey);
#endif #endif
void DownloadManager::_validateCert(QNetworkReply* reply) void DownloadManager::_validateCert(QNetworkReply* reply) {
{
#if KEY_PINNING #if KEY_PINNING
QSslCertificate peerCert = reply->sslConfiguration().peerCertificate(); QSslCertificate peerCert = reply->sslConfiguration().peerCertificate();
QSslKey peerKey = peerCert.publicKey(); QSslKey peerKey = peerCert.publicKey();
if (peerKey != AxioDLPublicKey && peerKey != AxioDLEdgePublicKey) if (peerKey != AxioDLPublicKey && peerKey != AxioDLEdgePublicKey) {
{ auto cn = peerCert.subjectInfo(QSslCertificate::CommonName);
auto cn = peerCert.subjectInfo(QSslCertificate::CommonName); if (!cn.empty())
if (!cn.empty()) setError(QNetworkReply::SslHandshakeFailedError,
setError(QNetworkReply::SslHandshakeFailedError, QStringLiteral("Certificate pinning mismatch \"") + cn.first() + "\"");
QStringLiteral("Certificate pinning mismatch \"") + cn.first() + "\""); else
else setError(QNetworkReply::SslHandshakeFailedError, QStringLiteral("Certificate pinning mismatch"));
setError(QNetworkReply::SslHandshakeFailedError, reply->abort();
QStringLiteral("Certificate pinning mismatch")); }
reply->abort();
}
#endif #endif
} }
static const QString Domain = QStringLiteral("https://releases.axiodl.com/"); static const QString Domain = QStringLiteral("https://releases.axiodl.com/");
static const QString Index = QStringLiteral("index.txt"); static const QString Index = QStringLiteral("index.txt");
void DownloadManager::fetchIndex() void DownloadManager::fetchIndex() {
{ if (m_indexInProgress)
if (m_indexInProgress) return;
return;
resetError(); resetError();
QString url = Domain + CurPlatformString + '/' + Index; QString url = Domain + CurPlatformString + '/' + Index;
m_indexInProgress = m_netManager.get(QNetworkRequest(url)); m_indexInProgress = m_netManager.get(QNetworkRequest(url));
connect(m_indexInProgress, SIGNAL(finished()), connect(m_indexInProgress, SIGNAL(finished()), this, SLOT(indexFinished()));
this, SLOT(indexFinished())); connect(m_indexInProgress, SIGNAL(error(QNetworkReply::NetworkError)), this,
connect(m_indexInProgress, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(indexError(QNetworkReply::NetworkError)));
this, SLOT(indexError(QNetworkReply::NetworkError))); connect(m_indexInProgress, SIGNAL(encrypted()), this, SLOT(indexValidateCert()));
connect(m_indexInProgress, SIGNAL(encrypted()),
this, SLOT(indexValidateCert()));
} }
void DownloadManager::fetchBinary(const QString& str, const QString& outPath) void DownloadManager::fetchBinary(const QString& str, const QString& outPath) {
{ if (m_binaryInProgress)
if (m_binaryInProgress) return;
return;
resetError(); resetError();
m_outPath = outPath; m_outPath = outPath;
QString url = Domain + CurPlatformString + '/' + str; QString url = Domain + CurPlatformString + '/' + str;
m_binaryInProgress = m_netManager.get(QNetworkRequest(url)); m_binaryInProgress = m_netManager.get(QNetworkRequest(url));
connect(m_binaryInProgress, SIGNAL(finished()), connect(m_binaryInProgress, SIGNAL(finished()), this, SLOT(binaryFinished()));
this, SLOT(binaryFinished())); connect(m_binaryInProgress, SIGNAL(error(QNetworkReply::NetworkError)), this,
connect(m_binaryInProgress, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(binaryError(QNetworkReply::NetworkError)));
this, SLOT(binaryError(QNetworkReply::NetworkError))); connect(m_binaryInProgress, SIGNAL(encrypted()), this, SLOT(binaryValidateCert()));
connect(m_binaryInProgress, SIGNAL(encrypted()), connect(m_binaryInProgress, SIGNAL(downloadProgress(qint64, qint64)), this,
this, SLOT(binaryValidateCert())); SLOT(binaryDownloadProgress(qint64, qint64)));
connect(m_binaryInProgress, SIGNAL(downloadProgress(qint64, qint64)),
this, SLOT(binaryDownloadProgress(qint64, qint64)));
if (m_progBar) if (m_progBar) {
{ m_progBar->setEnabled(true);
m_progBar->setEnabled(true); m_progBar->setValue(0);
m_progBar->setValue(0); }
}
} }
void DownloadManager::indexFinished() void DownloadManager::indexFinished() {
{ if (m_hasError)
if (m_hasError) return;
return;
QStringList files; QStringList files;
while (!m_indexInProgress->atEnd()) while (!m_indexInProgress->atEnd()) {
{ QString line = QString::fromUtf8(m_indexInProgress->readLine()).trimmed();
QString line = QString::fromUtf8(m_indexInProgress->readLine()).trimmed(); if (line.isEmpty())
if (line.isEmpty()) continue;
continue; files.push_back(line);
files.push_back(line); }
}
if (m_indexCompletionHandler) if (m_indexCompletionHandler)
m_indexCompletionHandler(files); m_indexCompletionHandler(files);
m_indexInProgress->deleteLater(); m_indexInProgress->deleteLater();
m_indexInProgress = nullptr; m_indexInProgress = nullptr;
} }
void DownloadManager::indexError(QNetworkReply::NetworkError error) void DownloadManager::indexError(QNetworkReply::NetworkError error) {
{ setError(error, m_indexInProgress->errorString());
setError(error, m_indexInProgress->errorString()); m_indexInProgress->deleteLater();
m_indexInProgress->deleteLater(); m_indexInProgress = nullptr;
m_indexInProgress = nullptr;
} }
void DownloadManager::indexValidateCert() void DownloadManager::indexValidateCert() { _validateCert(m_indexInProgress); }
{
_validateCert(m_indexInProgress);
}
void DownloadManager::binaryFinished() void DownloadManager::binaryFinished() {
{ if (m_hasError)
if (m_hasError) return;
return;
if (m_progBar) if (m_progBar)
m_progBar->setValue(100); m_progBar->setValue(100);
QByteArray all = m_binaryInProgress->readAll();
QBuffer buff(&all);
QuaZip zip(&buff);
if (!zip.open(QuaZip::mdUnzip))
{
setError(QNetworkReply::UnknownContentError, "Unable to open zip archive.");
m_binaryInProgress->deleteLater();
m_binaryInProgress = nullptr;
return;
}
if (m_completionHandler)
m_completionHandler(zip);
QByteArray all = m_binaryInProgress->readAll();
QBuffer buff(&all);
QuaZip zip(&buff);
if (!zip.open(QuaZip::mdUnzip)) {
setError(QNetworkReply::UnknownContentError, "Unable to open zip archive.");
m_binaryInProgress->deleteLater(); m_binaryInProgress->deleteLater();
m_binaryInProgress = nullptr; m_binaryInProgress = nullptr;
return;
}
if (m_completionHandler)
m_completionHandler(zip);
m_binaryInProgress->deleteLater();
m_binaryInProgress = nullptr;
} }
void DownloadManager::binaryError(QNetworkReply::NetworkError error) void DownloadManager::binaryError(QNetworkReply::NetworkError error) {
{ setError(error, m_binaryInProgress->errorString());
setError(error, m_binaryInProgress->errorString()); m_binaryInProgress->deleteLater();
m_binaryInProgress->deleteLater(); m_binaryInProgress = nullptr;
m_binaryInProgress = nullptr;
if (m_progBar) if (m_progBar)
m_progBar->setEnabled(false); m_progBar->setEnabled(false);
if (m_failedHandler) if (m_failedHandler)
m_failedHandler(); m_failedHandler();
} }
void DownloadManager::binaryValidateCert() void DownloadManager::binaryValidateCert() { _validateCert(m_binaryInProgress); }
{
_validateCert(m_binaryInProgress);
}
void DownloadManager::binaryDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) void DownloadManager::binaryDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
{ if (m_progBar) {
if (m_progBar) if (bytesReceived == bytesTotal)
{ m_progBar->setValue(100);
if (bytesReceived == bytesTotal) else
m_progBar->setValue(100); m_progBar->setValue(int(bytesReceived * 100 / bytesTotal));
else }
m_progBar->setValue(int(bytesReceived * 100 / bytesTotal));
}
} }

View File

@ -8,65 +8,57 @@
class QuaZip; class QuaZip;
class DownloadManager : public QObject class DownloadManager : public QObject {
{ Q_OBJECT
Q_OBJECT QNetworkAccessManager m_netManager;
QNetworkAccessManager m_netManager; QNetworkReply* m_indexInProgress = nullptr;
QNetworkReply* m_indexInProgress = nullptr; QNetworkReply* m_binaryInProgress = nullptr;
QNetworkReply* m_binaryInProgress = nullptr; QString m_outPath;
QString m_outPath; bool m_hasError = false;
bool m_hasError = false; QProgressBar* m_progBar = nullptr;
QProgressBar* m_progBar = nullptr; QLabel* m_errorLabel = nullptr;
QLabel* m_errorLabel = nullptr; std::function<void(const QStringList& index)> m_indexCompletionHandler;
std::function<void(const QStringList& index)> m_indexCompletionHandler; std::function<void(QuaZip& file)> m_completionHandler;
std::function<void(QuaZip& file)> m_completionHandler; std::function<void()> m_failedHandler;
std::function<void()> m_failedHandler;
void resetError() void resetError() {
{ m_hasError = false;
m_hasError = false; if (m_errorLabel)
if (m_errorLabel) m_errorLabel->setText(QString());
m_errorLabel->setText(QString()); }
}
void setError(QNetworkReply::NetworkError error, const QString& errStr) void setError(QNetworkReply::NetworkError error, const QString& errStr) {
{ if (m_hasError && error == QNetworkReply::OperationCanceledError)
if (m_hasError && error == QNetworkReply::OperationCanceledError) return;
return; m_hasError = true;
m_hasError = true; if (m_errorLabel)
if (m_errorLabel) m_errorLabel->setText(errStr);
m_errorLabel->setText(errStr); }
}
void _validateCert(QNetworkReply* reply); void _validateCert(QNetworkReply* reply);
public: public:
explicit DownloadManager(QObject* parent = Q_NULLPTR) explicit DownloadManager(QObject* parent = Q_NULLPTR) : QObject(parent), m_netManager(this) {}
: QObject(parent), m_netManager(this) {} void connectWidgets(QProgressBar* progBar, QLabel* errorLabel,
void connectWidgets(QProgressBar* progBar, QLabel* errorLabel, std::function<void(const QStringList& index)>&& indexCompletionHandler,
std::function<void(const QStringList& index)>&& indexCompletionHandler, std::function<void(QuaZip& file)>&& completionHandler, std::function<void()>&& failedHandler) {
std::function<void(QuaZip& file)>&& completionHandler, m_progBar = progBar;
std::function<void()>&& failedHandler) m_errorLabel = errorLabel;
{ m_indexCompletionHandler = std::move(indexCompletionHandler);
m_progBar = progBar; m_completionHandler = std::move(completionHandler);
m_errorLabel = errorLabel; m_failedHandler = std::move(failedHandler);
m_indexCompletionHandler = std::move(indexCompletionHandler); }
m_completionHandler = std::move(completionHandler); void fetchIndex();
m_failedHandler = std::move(failedHandler); void fetchBinary(const QString& str, const QString& outPath);
} bool hasError() const { return m_hasError; }
void fetchIndex();
void fetchBinary(const QString& str, const QString& outPath);
bool hasError() const { return m_hasError; }
public slots: public slots:
void indexFinished(); void indexFinished();
void indexError(QNetworkReply::NetworkError error); void indexError(QNetworkReply::NetworkError error);
void indexValidateCert(); void indexValidateCert();
void binaryFinished();
void binaryError(QNetworkReply::NetworkError error);
void binaryValidateCert();
void binaryDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
void binaryFinished();
void binaryError(QNetworkReply::NetworkError error);
void binaryValidateCert();
void binaryDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
}; };

View File

@ -2,19 +2,16 @@
#include <QLabel> #include <QLabel>
class ErrorLabel : public QLabel class ErrorLabel : public QLabel {
{
public: public:
ErrorLabel(QWidget* parent = Q_NULLPTR) : QLabel(parent) {} ErrorLabel(QWidget* parent = Q_NULLPTR) : QLabel(parent) {}
void setText(const QString& str, bool success = false) void setText(const QString& str, bool success = false) {
{ QPalette pal = QLabel::palette();
QPalette pal = QLabel::palette(); if (success)
if (success) pal.setColor(QPalette::WindowText, QColor(0, 255, 0));
pal.setColor(QPalette::WindowText, QColor(0,255,0)); else
else pal.setColor(QPalette::WindowText, QColor(255, 47, 0));
pal.setColor(QPalette::WindowText, QColor(255,47,0)); QLabel::setPalette(pal);
QLabel::setPalette(pal); QLabel::setText(str);
QLabel::setText(str); }
}
}; };

File diff suppressed because it is too large Load Diff

View File

@ -10,4 +10,3 @@ void ParseEscapeSequence(int attribute, QListIterator<QString>& i, QTextCharForm
void ReturnInsert(QTextCursor& cur, const QString& text); void ReturnInsert(QTextCursor& cur, const QString& text);
void ReturnInsert(QTextCursor& cur, const QString& text, const QTextCharFormat& format); void ReturnInsert(QTextCursor& cur, const QString& text, const QTextCharFormat& format);

View File

@ -8,32 +8,30 @@
* Only contains directory extraction functionality. * Only contains directory extraction functionality.
*/ */
static bool copyData(QIODevice &inFile, QIODevice &outFile) static bool copyData(QIODevice& inFile, QIODevice& outFile) {
{ while (!inFile.atEnd()) {
while (!inFile.atEnd()) { char buf[4096];
char buf[4096]; qint64 readLen = inFile.read(buf, 4096);
qint64 readLen = inFile.read(buf, 4096); if (readLen <= 0)
if (readLen <= 0) return false;
return false; if (outFile.write(buf, readLen) != readLen)
if (outFile.write(buf, readLen) != readLen) return false;
return false; }
} return true;
return true;
} }
QStringList ExtractZip::getFileList(QuaZip& zip) QStringList ExtractZip::getFileList(QuaZip& zip) {
{ // Estraggo i nomi dei file
// Estraggo i nomi dei file QStringList lst;
QStringList lst; QuaZipFileInfo64 info;
QuaZipFileInfo64 info; for (bool more = zip.goToFirstFile(); more; more = zip.goToNextFile()) {
for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { if (!zip.getCurrentFileInfo(&info))
if(!zip.getCurrentFileInfo(&info)) return {};
return {}; lst << info.name;
lst << info.name; // info.name.toLocal8Bit().constData()
//info.name.toLocal8Bit().constData() }
}
return lst; return lst;
} }
/**OK /**OK
@ -50,67 +48,69 @@ QStringList ExtractZip::getFileList(QuaZip& zip)
* *
* (1): prima di uscire dalla funzione cancella il file estratto. * (1): prima di uscire dalla funzione cancella il file estratto.
*/ */
bool ExtractZip::extractFile(QuaZip& zip, QString fileName, QString fileDest) bool ExtractZip::extractFile(QuaZip& zip, QString fileName, QString fileDest) {
{ // zip: oggetto dove aggiungere il file
// zip: oggetto dove aggiungere il file // filename: nome del file reale
// filename: nome del file reale // fileincompress: nome del file all'interno del file compresso
// fileincompress: nome del file all'interno del file compresso
// Controllo l'apertura dello zip // Controllo l'apertura dello zip
if (zip.getMode()!=QuaZip::mdUnzip) return false; if (zip.getMode() != QuaZip::mdUnzip)
return false;
// Apro il file compresso // Apro il file compresso
if (!fileName.isEmpty()) if (!fileName.isEmpty())
zip.setCurrentFile(fileName); zip.setCurrentFile(fileName);
QuaZipFile inFile(&zip); QuaZipFile inFile(&zip);
if(!inFile.open(QIODevice::ReadOnly) || inFile.getZipError()!=UNZ_OK) return false; if (!inFile.open(QIODevice::ReadOnly) || inFile.getZipError() != UNZ_OK)
return false;
// Controllo esistenza cartella file risultato // Controllo esistenza cartella file risultato
QDir curDir; QDir curDir;
if (fileDest.endsWith('/')) { if (fileDest.endsWith('/')) {
if (!curDir.mkpath(fileDest)) { if (!curDir.mkpath(fileDest)) {
return false; return false;
}
} else {
if (!curDir.mkpath(QFileInfo(fileDest).absolutePath())) {
return false;
}
} }
} else {
QuaZipFileInfo64 info; if (!curDir.mkpath(QFileInfo(fileDest).absolutePath())) {
if (!zip.getCurrentFileInfo(&info)) return false;
return false;
QFile::Permissions srcPerm = info.getPermissions();
if (fileDest.endsWith('/') && QFileInfo(fileDest).isDir()) {
if (srcPerm != 0) {
QFile(fileDest).setPermissions(srcPerm);
}
return true;
} }
}
// Apro il file risultato QuaZipFileInfo64 info;
QFile outFile; if (!zip.getCurrentFileInfo(&info))
outFile.setFileName(fileDest); return false;
if(!outFile.open(QIODevice::WriteOnly)) return false;
// Copio i dati
if (!copyData(inFile, outFile) || inFile.getZipError()!=UNZ_OK) {
outFile.close();
return false;
}
outFile.close();
// Chiudo i file
inFile.close();
if (inFile.getZipError()!=UNZ_OK) {
return false;
}
QFile::Permissions srcPerm = info.getPermissions();
if (fileDest.endsWith('/') && QFileInfo(fileDest).isDir()) {
if (srcPerm != 0) { if (srcPerm != 0) {
outFile.setPermissions(srcPerm); QFile(fileDest).setPermissions(srcPerm);
} }
return true; return true;
}
// Apro il file risultato
QFile outFile;
outFile.setFileName(fileDest);
if (!outFile.open(QIODevice::WriteOnly))
return false;
// Copio i dati
if (!copyData(inFile, outFile) || inFile.getZipError() != UNZ_OK) {
outFile.close();
return false;
}
outFile.close();
// Chiudo i file
inFile.close();
if (inFile.getZipError() != UNZ_OK) {
return false;
}
if (srcPerm != 0) {
outFile.setPermissions(srcPerm);
}
return true;
} }
/**OK /**OK
@ -124,18 +124,17 @@ bool ExtractZip::extractFile(QuaZip& zip, QString fileName, QString fileDest)
* * la compressione di un file fallisce; * * la compressione di un file fallisce;
* * non si riesce a chiudere l'oggetto zip; * * non si riesce a chiudere l'oggetto zip;
*/ */
bool ExtractZip::extractDir(QuaZip& zip, QString dir) bool ExtractZip::extractDir(QuaZip& zip, QString dir) {
{ QDir directory(dir);
QDir directory(dir); if (!zip.goToFirstFile()) {
if (!zip.goToFirstFile()) { return false;
return false; }
} do {
do { QString name = zip.getCurrentFileName();
QString name = zip.getCurrentFileName(); QString absFilePath = directory.absoluteFilePath(name);
QString absFilePath = directory.absoluteFilePath(name); if (!extractFile(zip, "", absFilePath))
if (!extractFile(zip, "", absFilePath)) return false;
return false; } while (zip.goToNextFile());
} while (zip.goToNextFile());
return true; return true;
} }

View File

@ -4,11 +4,9 @@ class QStringList;
class QuaZip; class QuaZip;
class QString; class QString;
class ExtractZip class ExtractZip {
{
public: public:
static QStringList getFileList(QuaZip& zip); static QStringList getFileList(QuaZip& zip);
static bool extractFile(QuaZip& zip, QString fileName, QString fileDest); static bool extractFile(QuaZip& zip, QString fileName, QString fileDest);
static bool extractDir(QuaZip& zip, QString dir); static bool extractDir(QuaZip& zip, QString dir);
}; };

View File

@ -2,10 +2,8 @@
#include <QFileDialog> #include <QFileDialog>
class FileDirDialog : public QFileDialog class FileDirDialog : public QFileDialog {
{ Q_OBJECT
Q_OBJECT
public: public:
FileDirDialog(QWidget* parent = nullptr) : QFileDialog(parent) { setFileMode(QFileDialog::Directory); } FileDirDialog(QWidget* parent = nullptr) : QFileDialog(parent) { setFileMode(QFileDialog::Directory); }
}; };

View File

@ -2,8 +2,7 @@
#include "hecl/SteamFinder.hpp" #include "hecl/SteamFinder.hpp"
#include "hecl/hecl.hpp" #include "hecl/hecl.hpp"
namespace hecl::blender namespace hecl::blender {
{
#ifdef __APPLE__ #ifdef __APPLE__
#define DEFAULT_BLENDER_BIN "/Applications/Blender.app/Contents/MacOS/blender" #define DEFAULT_BLENDER_BIN "/Applications/Blender.app/Contents/MacOS/blender"
@ -14,120 +13,104 @@ namespace hecl::blender
#endif #endif
static const std::regex regBlenderVersion(R"(Blender ([0-9]+).([0-9]+) )", static const std::regex regBlenderVersion(R"(Blender ([0-9]+).([0-9]+) )",
std::regex::ECMAScript|std::regex::optimize); std::regex::ECMAScript | std::regex::optimize);
static bool RegFileExists(const hecl::SystemChar* path) static bool RegFileExists(const hecl::SystemChar* path) {
{ if (!path)
if (!path) return false;
return false; hecl::Sstat theStat;
hecl::Sstat theStat; return !hecl::Stat(path, &theStat) && S_ISREG(theStat.st_mode);
return !hecl::Stat(path, &theStat) && S_ISREG(theStat.st_mode);
} }
hecl::SystemString FindBlender(int& major, int& minor) hecl::SystemString FindBlender(int& major, int& minor) {
{ major = 0;
major = 0; minor = 0;
minor = 0;
/* User-specified blender path */ /* User-specified blender path */
#if _WIN32 #if _WIN32
wchar_t BLENDER_BIN_BUF[2048]; wchar_t BLENDER_BIN_BUF[2048];
const wchar_t* blenderBin = _wgetenv(L"BLENDER_BIN"); const wchar_t* blenderBin = _wgetenv(L"BLENDER_BIN");
#else #else
const char* blenderBin = getenv("BLENDER_BIN"); const char* blenderBin = getenv("BLENDER_BIN");
#endif #endif
/* Steam blender */ /* Steam blender */
hecl::SystemString steamBlender; hecl::SystemString steamBlender;
/* Child process of blender */ /* Child process of blender */
#if _WIN32 #if _WIN32
if (!blenderBin || !RegFileExists(blenderBin)) if (!blenderBin || !RegFileExists(blenderBin)) {
{ /* Environment not set; try steam */
/* Environment not set; try steam */ steamBlender = hecl::FindCommonSteamApp(_SYS_STR("Blender"));
steamBlender = hecl::FindCommonSteamApp(_SYS_STR("Blender")); if (steamBlender.size()) {
if (steamBlender.size()) steamBlender += _SYS_STR("\\blender.exe");
{ blenderBin = steamBlender.c_str();
steamBlender += _SYS_STR("\\blender.exe"); }
blenderBin = steamBlender.c_str();
}
if (!RegFileExists(blenderBin)) {
/* No steam; try default */
wchar_t progFiles[256];
if (GetEnvironmentVariableW(L"ProgramFiles", progFiles, 256)) {
_snwprintf(BLENDER_BIN_BUF, 2048, L"%s\\Blender Foundation\\Blender\\blender.exe", progFiles);
blenderBin = BLENDER_BIN_BUF;
if (!RegFileExists(blenderBin)) if (!RegFileExists(blenderBin))
{ blenderBin = nullptr;
/* No steam; try default */ } else
wchar_t progFiles[256]; blenderBin = nullptr;
if (GetEnvironmentVariableW(L"ProgramFiles", progFiles, 256))
{
_snwprintf(BLENDER_BIN_BUF, 2048, L"%s\\Blender Foundation\\Blender\\blender.exe", progFiles);
blenderBin = BLENDER_BIN_BUF;
if (!RegFileExists(blenderBin))
blenderBin = nullptr;
}
else
blenderBin = nullptr;
}
} }
}
#else #else
if (!RegFileExists(blenderBin)) if (!RegFileExists(blenderBin)) {
{ /* Try steam */
/* Try steam */ steamBlender = hecl::FindCommonSteamApp(_SYS_STR("Blender"));
steamBlender = hecl::FindCommonSteamApp(_SYS_STR("Blender")); if (steamBlender.size()) {
if (steamBlender.size())
{
#ifdef __APPLE__ #ifdef __APPLE__
steamBlender += "/blender.app/Contents/MacOS/blender"; steamBlender += "/blender.app/Contents/MacOS/blender";
#else #else
steamBlender += "/blender"; steamBlender += "/blender";
#endif #endif
blenderBin = steamBlender.c_str(); blenderBin = steamBlender.c_str();
if (!RegFileExists(blenderBin)) if (!RegFileExists(blenderBin)) {
{ blenderBin = DEFAULT_BLENDER_BIN;
blenderBin = DEFAULT_BLENDER_BIN; if (!RegFileExists(blenderBin)) {
if (!RegFileExists(blenderBin)) blenderBin = nullptr;
{
blenderBin = nullptr;
}
}
}
else
{
blenderBin = DEFAULT_BLENDER_BIN;
if (!RegFileExists(blenderBin))
{
blenderBin = nullptr;
}
} }
}
} else {
blenderBin = DEFAULT_BLENDER_BIN;
if (!RegFileExists(blenderBin)) {
blenderBin = nullptr;
}
} }
}
#endif #endif
if (!blenderBin) if (!blenderBin)
return {}; return {};
hecl::SystemString command = hecl::SystemString(_SYS_STR("\"")) + blenderBin + _SYS_STR("\" --version"); hecl::SystemString command = hecl::SystemString(_SYS_STR("\"")) + blenderBin + _SYS_STR("\" --version");
#if _WIN32 #if _WIN32
FILE* fp = _wpopen(command.c_str(), _SYS_STR("r")); FILE* fp = _wpopen(command.c_str(), _SYS_STR("r"));
#else #else
FILE* fp = popen(command.c_str(), "r"); FILE* fp = popen(command.c_str(), "r");
#endif #endif
char versionBuf[256]; char versionBuf[256];
size_t rdSize = fread(versionBuf, 1, 255, fp); size_t rdSize = fread(versionBuf, 1, 255, fp);
versionBuf[rdSize] = '\0'; versionBuf[rdSize] = '\0';
#if _WIN32 #if _WIN32
_pclose(fp); _pclose(fp);
#else #else
pclose(fp); pclose(fp);
#endif #endif
std::cmatch match; std::cmatch match;
if (std::regex_search(versionBuf, match, regBlenderVersion)) if (std::regex_search(versionBuf, match, regBlenderVersion)) {
{ major = atoi(match[1].str().c_str());
major = atoi(match[1].str().c_str()); minor = atoi(match[2].str().c_str());
minor = atoi(match[2].str().c_str());
return blenderBin;
}
return blenderBin; return blenderBin;
}
return blenderBin;
} }
} } // namespace hecl::blender

View File

@ -2,10 +2,8 @@
#include "hecl/hecl.hpp" #include "hecl/hecl.hpp"
namespace hecl::blender namespace hecl::blender {
{
hecl::SystemString FindBlender(int& major, int& minor); hecl::SystemString FindBlender(int& major, int& minor);
} }

View File

@ -4,123 +4,112 @@
extern hecl::CVar* hecl::com_developer; extern hecl::CVar* hecl::com_developer;
LaunchMenu::LaunchMenu(hecl::CVarCommons& commons, QWidget* parent) LaunchMenu::LaunchMenu(hecl::CVarCommons& commons, QWidget* parent)
: QMenu("Launch Menu", parent), : QMenu("Launch Menu", parent)
m_commons(commons), , m_commons(commons)
m_apiMenu("Graphics API", this), , m_apiMenu("Graphics API", this)
m_msaaMenu("Anti-Aliasing", this), , m_msaaMenu("Anti-Aliasing", this)
m_anisoMenu("Anisotropic Filtering", this), , m_anisoMenu("Anisotropic Filtering", this)
m_apiGroup(this), , m_apiGroup(this)
m_msaaGroup(this), , m_msaaGroup(this)
m_anisoGroup(this) , m_anisoGroup(this) {
{
#ifdef _WIN32 #ifdef _WIN32
initApiAction(QStringLiteral("D3D11")); initApiAction(QStringLiteral("D3D11"));
initApiAction(QStringLiteral("Vulkan")); initApiAction(QStringLiteral("Vulkan"));
initApiAction(QStringLiteral("OpenGL")); initApiAction(QStringLiteral("OpenGL"));
#elif defined(__APPLE__) #elif defined(__APPLE__)
initApiAction(QStringLiteral("Metal")); initApiAction(QStringLiteral("Metal"));
initApiAction(QStringLiteral("OpenGL")); initApiAction(QStringLiteral("OpenGL"));
#else #else
initApiAction(QStringLiteral("OpenGL")); initApiAction(QStringLiteral("OpenGL"));
initApiAction(QStringLiteral("Vulkan")); initApiAction(QStringLiteral("Vulkan"));
#endif #endif
initMsaaAction(QStringLiteral("1")); initMsaaAction(QStringLiteral("1"));
initMsaaAction(QStringLiteral("2")); initMsaaAction(QStringLiteral("2"));
initMsaaAction(QStringLiteral("4")); initMsaaAction(QStringLiteral("4"));
initMsaaAction(QStringLiteral("8")); initMsaaAction(QStringLiteral("8"));
initMsaaAction(QStringLiteral("16")); initMsaaAction(QStringLiteral("16"));
initAnisoAction(QStringLiteral("1")); initAnisoAction(QStringLiteral("1"));
initAnisoAction(QStringLiteral("2")); initAnisoAction(QStringLiteral("2"));
initAnisoAction(QStringLiteral("4")); initAnisoAction(QStringLiteral("4"));
initAnisoAction(QStringLiteral("8")); initAnisoAction(QStringLiteral("8"));
initAnisoAction(QStringLiteral("16")); initAnisoAction(QStringLiteral("16"));
m_apiMenu.addActions(m_apiGroup.actions()); m_apiMenu.addActions(m_apiGroup.actions());
m_msaaMenu.addActions(m_msaaGroup.actions()); m_msaaMenu.addActions(m_msaaGroup.actions());
m_anisoMenu.addActions(m_anisoGroup.actions()); m_anisoMenu.addActions(m_anisoGroup.actions());
addMenu(&m_apiMenu)->setToolTip(m_commons.m_graphicsApi->rawHelp().data()); addMenu(&m_apiMenu)->setToolTip(m_commons.m_graphicsApi->rawHelp().data());
addMenu(&m_msaaMenu)->setToolTip(m_commons.m_drawSamples->rawHelp().data()); addMenu(&m_msaaMenu)->setToolTip(m_commons.m_drawSamples->rawHelp().data());
addMenu(&m_anisoMenu)->setToolTip(m_commons.m_texAnisotropy->rawHelp().data()); addMenu(&m_anisoMenu)->setToolTip(m_commons.m_texAnisotropy->rawHelp().data());
initDeepColor(); initDeepColor();
initDeveloperMode(); initDeveloperMode();
} }
void LaunchMenu::initApiAction(const QString& action) void LaunchMenu::initApiAction(const QString& action) {
{ QAction* act = m_apiGroup.addAction(action);
QAction* act = m_apiGroup.addAction(action); connect(act, SIGNAL(triggered()), this, SLOT(apiTriggered()));
connect(act, SIGNAL(triggered()), this, SLOT(apiTriggered())); act->setCheckable(true);
act->setCheckable(true); if (!action.compare(QString::fromStdString(m_commons.getGraphicsApi()), Qt::CaseInsensitive))
if (!action.compare(QString::fromStdString(m_commons.getGraphicsApi()), Qt::CaseInsensitive)) act->setChecked(true);
act->setChecked(true);
} }
void LaunchMenu::initMsaaAction(const QString& action) void LaunchMenu::initMsaaAction(const QString& action) {
{ QAction* act = m_msaaGroup.addAction(action);
QAction* act = m_msaaGroup.addAction(action); connect(act, SIGNAL(triggered()), this, SLOT(msaaTriggered()));
connect(act, SIGNAL(triggered()), this, SLOT(msaaTriggered())); act->setCheckable(true);
act->setCheckable(true); if (!action.compare(QString::number(m_commons.getSamples()), Qt::CaseInsensitive))
if (!action.compare(QString::number(m_commons.getSamples()), Qt::CaseInsensitive)) act->setChecked(true);
act->setChecked(true);
} }
void LaunchMenu::initAnisoAction(const QString& action) void LaunchMenu::initAnisoAction(const QString& action) {
{ QAction* act = m_anisoGroup.addAction(action);
QAction* act = m_anisoGroup.addAction(action); connect(act, SIGNAL(triggered()), this, SLOT(anisoTriggered()));
connect(act, SIGNAL(triggered()), this, SLOT(anisoTriggered())); act->setCheckable(true);
act->setCheckable(true); if (!action.compare(QString::number(m_commons.getAnisotropy()), Qt::CaseInsensitive))
if (!action.compare(QString::number(m_commons.getAnisotropy()), Qt::CaseInsensitive)) act->setChecked(true);
act->setChecked(true);
} }
void LaunchMenu::initDeepColor() void LaunchMenu::initDeepColor() {
{ QAction* act = addAction("Deep Color");
QAction* act = addAction("Deep Color"); act->setToolTip(m_commons.m_deepColor->rawHelp().data());
act->setToolTip(m_commons.m_deepColor->rawHelp().data()); act->setCheckable(true);
act->setCheckable(true); act->setChecked(m_commons.getDeepColor());
act->setChecked(m_commons.getDeepColor()); connect(act, SIGNAL(triggered()), this, SLOT(deepColorTriggered()));
connect(act, SIGNAL(triggered()), this, SLOT(deepColorTriggered()));
} }
void LaunchMenu::initDeveloperMode() void LaunchMenu::initDeveloperMode() {
{ QAction* act = addAction("Developer Mode");
QAction* act = addAction("Developer Mode"); act->setToolTip(hecl::com_developer->rawHelp().data());
act->setToolTip(hecl::com_developer->rawHelp().data()); act->setCheckable(true);
act->setCheckable(true); act->setChecked(hecl::com_developer->toBoolean());
act->setChecked(hecl::com_developer->toBoolean()); connect(act, SIGNAL(triggered()), this, SLOT(developerModeTriggered()));
connect(act, SIGNAL(triggered()), this, SLOT(developerModeTriggered()));
} }
void LaunchMenu::apiTriggered() void LaunchMenu::apiTriggered() {
{ QString apiStr = qobject_cast<QAction*>(sender())->text();
QString apiStr = qobject_cast<QAction*>(sender())->text(); apiStr = apiStr.remove('&');
apiStr = apiStr.remove('&'); m_commons.setGraphicsApi(apiStr.toStdString());
m_commons.setGraphicsApi(apiStr.toStdString()); m_commons.serialize();
m_commons.serialize();
} }
void LaunchMenu::msaaTriggered() void LaunchMenu::msaaTriggered() {
{ m_commons.setSamples(qobject_cast<QAction*>(sender())->text().toUInt());
m_commons.setSamples(qobject_cast<QAction*>(sender())->text().toUInt()); m_commons.serialize();
m_commons.serialize();
} }
void LaunchMenu::anisoTriggered() void LaunchMenu::anisoTriggered() {
{ m_commons.setAnisotropy(qobject_cast<QAction*>(sender())->text().toUInt());
m_commons.setAnisotropy(qobject_cast<QAction*>(sender())->text().toUInt()); m_commons.serialize();
m_commons.serialize();
} }
void LaunchMenu::deepColorTriggered() void LaunchMenu::deepColorTriggered() {
{ m_commons.setDeepColor(qobject_cast<QAction*>(sender())->isChecked());
m_commons.setDeepColor(qobject_cast<QAction*>(sender())->isChecked()); m_commons.serialize();
m_commons.serialize();
} }
void LaunchMenu::developerModeTriggered() void LaunchMenu::developerModeTriggered() {
{ hecl::CVarManager::instance()->setDeveloperMode(qobject_cast<QAction*>(sender())->isChecked(), true);
hecl::CVarManager::instance()->setDeveloperMode(qobject_cast<QAction*>(sender())->isChecked(), true); m_commons.serialize();
m_commons.serialize();
} }

View File

@ -1,35 +1,35 @@
#pragma once #pragma once
#include <QMenu> #include <QMenu>
namespace hecl { struct CVarCommons; } namespace hecl {
struct CVarCommons;
}
class LaunchMenu : public QMenu class LaunchMenu : public QMenu {
{ Q_OBJECT
Q_OBJECT hecl::CVarCommons& m_commons;
hecl::CVarCommons& m_commons;
QMenu m_apiMenu; QMenu m_apiMenu;
QMenu m_msaaMenu; QMenu m_msaaMenu;
QMenu m_anisoMenu; QMenu m_anisoMenu;
QActionGroup m_apiGroup; QActionGroup m_apiGroup;
QActionGroup m_msaaGroup; QActionGroup m_msaaGroup;
QActionGroup m_anisoGroup; QActionGroup m_anisoGroup;
void initApiAction(const QString& action); void initApiAction(const QString& action);
void initMsaaAction(const QString& action); void initMsaaAction(const QString& action);
void initAnisoAction(const QString& action); void initAnisoAction(const QString& action);
void initDeepColor(); void initDeepColor();
void initDeveloperMode(); void initDeveloperMode();
public: public:
LaunchMenu(hecl::CVarCommons& commons, QWidget* parent = Q_NULLPTR); LaunchMenu(hecl::CVarCommons& commons, QWidget* parent = Q_NULLPTR);
public slots: public slots:
void apiTriggered(); void apiTriggered();
void msaaTriggered(); void msaaTriggered();
void anisoTriggered(); void anisoTriggered();
void deepColorTriggered(); void deepColorTriggered();
void developerModeTriggered(); void developerModeTriggered();
}; };

View File

@ -1,4 +1,3 @@
#pragma once #pragma once
void GetMacOSSystemVersion(int& major, int& minor, int& patch); void GetMacOSSystemVersion(int& major, int& minor, int& patch);

View File

@ -11,571 +11,502 @@
#include <shellapi.h> #include <shellapi.h>
#include <TlHelp32.h> #include <TlHelp32.h>
static void KillProcessTree(QProcess& proc) static void KillProcessTree(QProcess& proc) {
{ Q_PID pid = proc.pid();
Q_PID pid = proc.pid(); if (!pid)
if (!pid) return;
return;
DWORD myprocID = pid->dwProcessId; DWORD myprocID = pid->dwProcessId;
PROCESSENTRY32 pe = {}; PROCESSENTRY32 pe = {};
pe.dwSize = sizeof(PROCESSENTRY32); pe.dwSize = sizeof(PROCESSENTRY32);
HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (::Process32First(hSnap, &pe)) if (::Process32First(hSnap, &pe)) {
{ BOOL bContinue = TRUE;
BOOL bContinue = TRUE;
// kill child processes // kill child processes
while (bContinue) while (bContinue) {
{ // only kill child processes
// only kill child processes if (pe.th32ParentProcessID == myprocID) {
if (pe.th32ParentProcessID == myprocID) HANDLE hChildProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
{
HANDLE hChildProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
if (hChildProc) if (hChildProc) {
{ ::TerminateProcess(hChildProc, 1);
::TerminateProcess(hChildProc, 1); ::CloseHandle(hChildProc);
::CloseHandle(hChildProc);
}
}
bContinue = ::Process32Next(hSnap, &pe);
} }
} }
proc.close(); bContinue = ::Process32Next(hSnap, &pe);
proc.terminate(); }
}
proc.close();
proc.terminate();
} }
#else #else
static void KillProcessTree(QProcess& proc) static void KillProcessTree(QProcess& proc) {
{ proc.close();
proc.close(); proc.terminate();
proc.terminate();
} }
#endif #endif
MainWindow::MainWindow(QWidget *parent) : MainWindow::MainWindow(QWidget* parent)
QMainWindow(parent) : QMainWindow(parent)
, m_fileMgr(_SYS_STR("urde")) , m_fileMgr(_SYS_STR("urde"))
, m_cvarManager(m_fileMgr) , m_cvarManager(m_fileMgr)
, m_cvarCommons(m_cvarManager) , m_cvarCommons(m_cvarManager)
, m_ui(new Ui::MainWindow) , m_ui(new Ui::MainWindow)
, m_heclProc(this) , m_heclProc(this)
, m_dlManager(this) , m_dlManager(this)
, m_launchMenu(m_cvarCommons, this) , m_launchMenu(m_cvarCommons, this)
, m_settings("AxioDL", "HECL", this) , m_settings("AxioDL", "HECL", this) {
{ m_ui->setupUi(this);
m_ui->setupUi(this); m_ui->heclTabs->setCurrentIndex(0);
m_ui->heclTabs->setCurrentIndex(0);
m_ui->aboutIcon->setPixmap(QApplication::windowIcon().pixmap(256, 256)); m_ui->aboutIcon->setPixmap(QApplication::windowIcon().pixmap(256, 256));
QFont mFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); QFont mFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
mFont.setPointSize(m_ui->currentBinaryLabel->font().pointSize()); mFont.setPointSize(m_ui->currentBinaryLabel->font().pointSize());
m_ui->currentBinaryLabel->setFont(mFont); m_ui->currentBinaryLabel->setFont(mFont);
m_ui->recommendedBinaryLabel->setFont(mFont); m_ui->recommendedBinaryLabel->setFont(mFont);
mFont.setPointSize(10); mFont.setPointSize(10);
m_ui->processOutput->setFont(mFont); m_ui->processOutput->setFont(mFont);
m_cursor = QTextCursor(m_ui->processOutput->document()); m_cursor = QTextCursor(m_ui->processOutput->document());
m_updateURDEButton = new QPushButton(QStringLiteral("Update URDE"), m_ui->centralwidget); m_updateURDEButton = new QPushButton(QStringLiteral("Update URDE"), m_ui->centralwidget);
m_ui->gridLayout->addWidget(m_updateURDEButton, 2, 3, 1, 1); m_ui->gridLayout->addWidget(m_updateURDEButton, 2, 3, 1, 1);
m_updateURDEButton->hide(); m_updateURDEButton->hide();
QPalette pal = m_updateURDEButton->palette(); QPalette pal = m_updateURDEButton->palette();
pal.setColor(QPalette::Button, QColor(53,53,72)); pal.setColor(QPalette::Button, QColor(53, 53, 72));
m_updateURDEButton->setPalette(pal); m_updateURDEButton->setPalette(pal);
connect(m_updateURDEButton, SIGNAL(clicked()), this, SLOT(onUpdateURDEPressed())); connect(m_updateURDEButton, SIGNAL(clicked()), this, SLOT(onUpdateURDEPressed()));
m_dlManager.connectWidgets(m_ui->downloadProgressBar, m_ui->downloadErrorLabel, m_dlManager.connectWidgets(m_ui->downloadProgressBar, m_ui->downloadErrorLabel,
std::bind(&MainWindow::onIndexDownloaded, this, std::placeholders::_1), std::bind(&MainWindow::onIndexDownloaded, this, std::placeholders::_1),
std::bind(&MainWindow::onBinaryDownloaded, this, std::placeholders::_1), std::bind(&MainWindow::onBinaryDownloaded, this, std::placeholders::_1),
std::bind(&MainWindow::onBinaryFailed, this)); std::bind(&MainWindow::onBinaryFailed, this));
initSlots(); initSlots();
m_dlManager.fetchIndex(); m_dlManager.fetchIndex();
setPath(m_settings.value(QStringLiteral("working_dir")).toString()); setPath(m_settings.value(QStringLiteral("working_dir")).toString());
} }
MainWindow::~MainWindow() MainWindow::~MainWindow() {
{ KillProcessTree(m_heclProc);
KillProcessTree(m_heclProc); delete m_ui;
delete m_ui;
} }
void MainWindow::onExtract() void MainWindow::onExtract() {
{ if (m_path.isEmpty())
if (m_path.isEmpty()) return;
return; QString imgPath = QFileDialog::getOpenFileName(this, QStringLiteral("Extract Image"), m_path,
QString imgPath = QFileDialog::getOpenFileName(this, QStringLiteral("Extract Image"), m_path, QStringLiteral("Images (*.iso *.wbfs *.gcm)"));
QStringLiteral("Images (*.iso *.wbfs *.gcm)")); if (imgPath.isEmpty())
if (imgPath.isEmpty()) return;
return;
m_ui->processOutput->clear(); m_ui->processOutput->clear();
KillProcessTree(m_heclProc); KillProcessTree(m_heclProc);
m_heclProc.setProcessChannelMode(QProcess::ProcessChannelMode::MergedChannels); m_heclProc.setProcessChannelMode(QProcess::ProcessChannelMode::MergedChannels);
m_heclProc.setWorkingDirectory(m_path); m_heclProc.setWorkingDirectory(m_path);
QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("TERM", "xterm-color"); env.insert("TERM", "xterm-color");
env.insert("ConEmuANSI", "ON"); env.insert("ConEmuANSI", "ON");
m_heclProc.setProcessEnvironment(env); m_heclProc.setProcessEnvironment(env);
disconnect(&m_heclProc, SIGNAL(finished(int)), nullptr, nullptr); disconnect(&m_heclProc, SIGNAL(finished(int)), nullptr, nullptr);
connect(&m_heclProc, SIGNAL(finished(int)), this, SLOT(onExtractFinished(int))); connect(&m_heclProc, SIGNAL(finished(int)), this, SLOT(onExtractFinished(int)));
m_heclProc.start(m_heclPath, {"extract", "-y", "-g", "-o", m_path, imgPath}, m_heclProc.start(m_heclPath, {"extract", "-y", "-g", "-o", m_path, imgPath},
QIODevice::ReadOnly | QIODevice::Unbuffered); QIODevice::ReadOnly | QIODevice::Unbuffered);
m_ui->heclTabs->setCurrentIndex(0); m_ui->heclTabs->setCurrentIndex(0);
disableOperations(); disableOperations();
m_ui->extractBtn->setText(QStringLiteral("Cancel")); m_ui->extractBtn->setText(QStringLiteral("Cancel"));
m_ui->extractBtn->setEnabled(true); m_ui->extractBtn->setEnabled(true);
disconnect(m_ui->extractBtn, SIGNAL(clicked()), nullptr, nullptr); disconnect(m_ui->extractBtn, SIGNAL(clicked()), nullptr, nullptr);
connect(m_ui->extractBtn, SIGNAL(clicked()), this, SLOT(doHECLTerminate())); connect(m_ui->extractBtn, SIGNAL(clicked()), this, SLOT(doHECLTerminate()));
} }
void MainWindow::onExtractFinished(int returnCode) void MainWindow::onExtractFinished(int returnCode) {
{ m_cursor.movePosition(QTextCursor::End);
m_cursor.movePosition(QTextCursor::End); m_cursor.insertBlock();
m_cursor.insertBlock(); disconnect(m_ui->extractBtn, SIGNAL(clicked()), nullptr, nullptr);
disconnect(m_ui->extractBtn, SIGNAL(clicked()), nullptr, nullptr); connect(m_ui->extractBtn, SIGNAL(clicked()), this, SLOT(onExtract()));
connect(m_ui->extractBtn, SIGNAL(clicked()), this, SLOT(onExtract())); checkDownloadedBinary();
}
void MainWindow::onPackage() {
if (m_path.isEmpty())
return;
m_ui->processOutput->clear();
KillProcessTree(m_heclProc);
m_heclProc.setProcessChannelMode(QProcess::ProcessChannelMode::MergedChannels);
m_heclProc.setWorkingDirectory(m_path);
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("TERM", "xterm-color");
env.insert("ConEmuANSI", "ON");
m_heclProc.setProcessEnvironment(env);
disconnect(&m_heclProc, SIGNAL(finished(int)), nullptr, nullptr);
connect(&m_heclProc, SIGNAL(finished(int)), this, SLOT(onPackageFinished(int)));
m_heclProc.start(m_heclPath, {"package", "-y", "-g"}, QIODevice::ReadOnly | QIODevice::Unbuffered);
m_ui->heclTabs->setCurrentIndex(0);
disableOperations();
m_ui->packageBtn->setText(QStringLiteral("Cancel"));
m_ui->packageBtn->setEnabled(true);
disconnect(m_ui->packageBtn, SIGNAL(clicked()), nullptr, nullptr);
connect(m_ui->packageBtn, SIGNAL(clicked()), this, SLOT(doHECLTerminate()));
QSize size = QWidget::size();
if (size.width() < 1100)
size.setWidth(1100);
resize(size);
}
void MainWindow::onPackageFinished(int returnCode) {
m_cursor.movePosition(QTextCursor::End);
m_cursor.insertBlock();
disconnect(m_ui->packageBtn, SIGNAL(clicked()), nullptr, nullptr);
connect(m_ui->packageBtn, SIGNAL(clicked()), this, SLOT(onPackage()));
checkDownloadedBinary();
}
void MainWindow::onLaunch() {
if (m_path.isEmpty())
return;
m_ui->processOutput->clear();
KillProcessTree(m_heclProc);
m_heclProc.setProcessChannelMode(QProcess::ProcessChannelMode::MergedChannels);
m_heclProc.setWorkingDirectory(m_path);
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("TERM", "xterm-color");
env.insert("ConEmuANSI", "ON");
m_heclProc.setProcessEnvironment(env);
disconnect(&m_heclProc, SIGNAL(finished(int)), nullptr, nullptr);
connect(&m_heclProc, SIGNAL(finished(int)), this, SLOT(onLaunchFinished(int)));
m_heclProc.start(m_urdePath, {"--no-shader-warmup", m_path + "/out"}, QIODevice::ReadOnly | QIODevice::Unbuffered);
m_ui->heclTabs->setCurrentIndex(0);
disableOperations();
}
void MainWindow::onLaunchFinished(int returnCode) {
m_cursor.movePosition(QTextCursor::End);
m_cursor.insertBlock();
checkDownloadedBinary();
}
void MainWindow::doHECLTerminate() { KillProcessTree(m_heclProc); }
void MainWindow::onReturnPressed() {
if (sender() == m_ui->pathEdit)
setPath(m_ui->pathEdit->text());
}
void MainWindow::onIndexDownloaded(const QStringList& index) {
int bestVersion = 0;
m_ui->binaryComboBox->clear();
for (const QString& str : index) {
URDEVersion version(str);
if (m_ui->sysReqTable->willRun(version))
bestVersion = m_ui->binaryComboBox->count();
m_ui->binaryComboBox->addItem(version.fileString(false), QVariant::fromValue(version));
}
m_ui->binaryComboBox->setCurrentIndex(bestVersion);
m_recommendedVersion = m_ui->binaryComboBox->itemData(bestVersion).value<URDEVersion>();
m_ui->recommendedBinaryLabel->setText(m_recommendedVersion.fileString(false));
m_ui->binaryComboBox->setEnabled(true);
if (!m_path.isEmpty()) {
checkDownloadedBinary(); checkDownloadedBinary();
}
void MainWindow::onPackage()
{
if (m_path.isEmpty())
return;
m_ui->processOutput->clear();
KillProcessTree(m_heclProc);
m_heclProc.setProcessChannelMode(QProcess::ProcessChannelMode::MergedChannels);
m_heclProc.setWorkingDirectory(m_path);
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("TERM", "xterm-color");
env.insert("ConEmuANSI", "ON");
m_heclProc.setProcessEnvironment(env);
disconnect(&m_heclProc, SIGNAL(finished(int)), nullptr, nullptr);
connect(&m_heclProc, SIGNAL(finished(int)), this, SLOT(onPackageFinished(int)));
m_heclProc.start(m_heclPath, {"package", "-y", "-g"},
QIODevice::ReadOnly | QIODevice::Unbuffered);
m_ui->heclTabs->setCurrentIndex(0);
disableOperations();
m_ui->packageBtn->setText(QStringLiteral("Cancel"));
m_ui->packageBtn->setEnabled(true);
disconnect(m_ui->packageBtn, SIGNAL(clicked()), nullptr, nullptr);
connect(m_ui->packageBtn, SIGNAL(clicked()), this, SLOT(doHECLTerminate()));
QSize size = QWidget::size();
if (size.width() < 1100)
size.setWidth(1100);
resize(size);
}
void MainWindow::onPackageFinished(int returnCode)
{
m_cursor.movePosition(QTextCursor::End);
m_cursor.insertBlock();
disconnect(m_ui->packageBtn, SIGNAL(clicked()), nullptr, nullptr);
connect(m_ui->packageBtn, SIGNAL(clicked()), this, SLOT(onPackage()));
checkDownloadedBinary();
}
void MainWindow::onLaunch()
{
if (m_path.isEmpty())
return;
m_ui->processOutput->clear();
KillProcessTree(m_heclProc);
m_heclProc.setProcessChannelMode(QProcess::ProcessChannelMode::MergedChannels);
m_heclProc.setWorkingDirectory(m_path);
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("TERM", "xterm-color");
env.insert("ConEmuANSI", "ON");
m_heclProc.setProcessEnvironment(env);
disconnect(&m_heclProc, SIGNAL(finished(int)), nullptr, nullptr);
connect(&m_heclProc, SIGNAL(finished(int)), this, SLOT(onLaunchFinished(int)));
m_heclProc.start(m_urdePath, {"--no-shader-warmup", m_path + "/out"},
QIODevice::ReadOnly | QIODevice::Unbuffered);
m_ui->heclTabs->setCurrentIndex(0);
disableOperations();
}
void MainWindow::onLaunchFinished(int returnCode)
{
m_cursor.movePosition(QTextCursor::End);
m_cursor.insertBlock();
checkDownloadedBinary();
}
void MainWindow::doHECLTerminate()
{
KillProcessTree(m_heclProc);
}
void MainWindow::onReturnPressed()
{
if (sender() == m_ui->pathEdit)
setPath(m_ui->pathEdit->text());
}
void MainWindow::onIndexDownloaded(const QStringList& index)
{
int bestVersion = 0;
m_ui->binaryComboBox->clear();
for (const QString& str : index)
{
URDEVersion version(str);
if (m_ui->sysReqTable->willRun(version))
bestVersion = m_ui->binaryComboBox->count();
m_ui->binaryComboBox->addItem(version.fileString(false), QVariant::fromValue(version));
}
m_ui->binaryComboBox->setCurrentIndex(bestVersion);
m_recommendedVersion = m_ui->binaryComboBox->itemData(bestVersion).value<URDEVersion>();
m_ui->recommendedBinaryLabel->setText(m_recommendedVersion.fileString(false));
m_ui->binaryComboBox->setEnabled(true);
if (!m_path.isEmpty())
{
checkDownloadedBinary();
m_ui->downloadButton->setEnabled(true);
}
}
void MainWindow::onDownloadPressed()
{
m_updateURDEButton->hide();
QString filename = m_ui->binaryComboBox->currentData().value<URDEVersion>().fileString(true);
disableOperations();
m_ui->downloadButton->setEnabled(false);
m_dlManager.fetchBinary(filename, m_path + '/' + filename);
}
void MainWindow::onUpdateURDEPressed()
{
m_ui->heclTabs->setCurrentIndex(1);
onDownloadPressed();
}
void MainWindow::onBinaryDownloaded(QuaZip& file)
{
bool err = !ExtractZip::extractDir(file, m_path);
if (err)
m_ui->downloadErrorLabel->setText(QStringLiteral("Error extracting zip"));
else
m_ui->downloadErrorLabel->setText(QStringLiteral("Download successful"), true);
m_ui->downloadButton->setEnabled(true); m_ui->downloadButton->setEnabled(true);
checkDownloadedBinary(); }
}
if (!err && m_ui->extractBtn->isEnabled()) void MainWindow::onDownloadPressed() {
m_ui->downloadErrorLabel->setText(QStringLiteral("Download successful - Press 'Extract' to continue."), true); m_updateURDEButton->hide();
if (!err && !m_ui->sysReqTable->isBlenderVersionOk()) QString filename = m_ui->binaryComboBox->currentData().value<URDEVersion>().fileString(true);
m_ui->downloadErrorLabel->setText( disableOperations();
m_ui->downloadButton->setEnabled(false);
m_dlManager.fetchBinary(filename, m_path + '/' + filename);
}
void MainWindow::onUpdateURDEPressed() {
m_ui->heclTabs->setCurrentIndex(1);
onDownloadPressed();
}
void MainWindow::onBinaryDownloaded(QuaZip& file) {
bool err = !ExtractZip::extractDir(file, m_path);
if (err)
m_ui->downloadErrorLabel->setText(QStringLiteral("Error extracting zip"));
else
m_ui->downloadErrorLabel->setText(QStringLiteral("Download successful"), true);
m_ui->downloadButton->setEnabled(true);
checkDownloadedBinary();
if (!err && m_ui->extractBtn->isEnabled())
m_ui->downloadErrorLabel->setText(QStringLiteral("Download successful - Press 'Extract' to continue."), true);
if (!err && !m_ui->sysReqTable->isBlenderVersionOk())
m_ui->downloadErrorLabel->setText(
QStringLiteral("Blender 2.78+ must be installed. Please download via Steam or blender.org.")); QStringLiteral("Blender 2.78+ must be installed. Please download via Steam or blender.org."));
} }
void MainWindow::onBinaryFailed() void MainWindow::onBinaryFailed() {
{ m_ui->downloadButton->setEnabled(true);
m_ui->downloadButton->setEnabled(true); checkDownloadedBinary();
checkDownloadedBinary();
} }
void MainWindow::disableOperations() void MainWindow::disableOperations() {
{ m_ui->extractBtn->setEnabled(false);
m_ui->extractBtn->setEnabled(false); m_ui->packageBtn->setEnabled(false);
m_ui->packageBtn->setEnabled(false); m_ui->launchBtn->setEnabled(false);
m_ui->launchBtn->setEnabled(false); m_ui->pathEdit->setEnabled(false);
m_ui->pathEdit->setEnabled(false); m_ui->browseBtn->setEnabled(false);
m_ui->browseBtn->setEnabled(false); m_ui->downloadButton->setEnabled(false);
m_ui->downloadButton->setEnabled(false);
} }
void MainWindow::enableOperations() void MainWindow::enableOperations() {
{ disableOperations();
disableOperations(); m_ui->pathEdit->setEnabled(true);
m_ui->pathEdit->setEnabled(true); m_ui->browseBtn->setEnabled(true);
m_ui->browseBtn->setEnabled(true);
if (m_path.isEmpty()) if (m_path.isEmpty())
return; return;
m_ui->downloadButton->setEnabled(true); m_ui->downloadButton->setEnabled(true);
if (m_heclPath.isEmpty()) if (m_heclPath.isEmpty())
return; return;
m_ui->extractBtn->setText(QStringLiteral("Extract")); m_ui->extractBtn->setText(QStringLiteral("Extract"));
m_ui->packageBtn->setText(QStringLiteral("Package")); m_ui->packageBtn->setText(QStringLiteral("Package"));
m_ui->launchBtn->setText(QStringLiteral("Launch")); m_ui->launchBtn->setText(QStringLiteral("Launch"));
m_ui->extractBtn->setEnabled(true); m_ui->extractBtn->setEnabled(true);
if (QFile::exists(m_path + "/MP1/!original_ids.yaml")) if (QFile::exists(m_path + "/MP1/!original_ids.yaml")) {
{ m_ui->packageBtn->setEnabled(true);
m_ui->packageBtn->setEnabled(true); if (isPackageComplete())
if (isPackageComplete()) m_ui->launchBtn->setEnabled(true);
m_ui->launchBtn->setEnabled(true); }
}
if (!m_ui->sysReqTable->isBlenderVersionOk()) if (!m_ui->sysReqTable->isBlenderVersionOk())
insertContinueNote("Blender 2.78+ must be installed. Please download via Steam or blender.org."); insertContinueNote("Blender 2.78+ must be installed. Please download via Steam or blender.org.");
else if (m_ui->launchBtn->isEnabled()) else if (m_ui->launchBtn->isEnabled())
insertContinueNote("Package complete - Press 'Launch' to start URDE."); insertContinueNote("Package complete - Press 'Launch' to start URDE.");
else if (m_ui->packageBtn->isEnabled()) else if (m_ui->packageBtn->isEnabled())
insertContinueNote("Extract complete - Press 'Package' to continue."); insertContinueNote("Extract complete - Press 'Package' to continue.");
else if (m_ui->extractBtn->isEnabled()) else if (m_ui->extractBtn->isEnabled())
insertContinueNote("Press 'Extract' to begin."); insertContinueNote("Press 'Extract' to begin.");
} }
bool MainWindow::isPackageComplete() const bool MainWindow::isPackageComplete() const {
{ return
return
#if RUNTIME_ORIGINAL_IDS #if RUNTIME_ORIGINAL_IDS
QFile::exists(m_path + "/out/files/!original_ids.upak") && QFile::exists(m_path + "/out/files/!original_ids.upak") &&
#endif #endif
QFile::exists(m_path + "/out/files/AudioGrp.upak") && QFile::exists(m_path + "/out/files/AudioGrp.upak") && QFile::exists(m_path + "/out/files/GGuiSys.upak") &&
QFile::exists(m_path + "/out/files/GGuiSys.upak") && QFile::exists(m_path + "/out/files/Metroid1.upak") && QFile::exists(m_path + "/out/files/Metroid2.upak") &&
QFile::exists(m_path + "/out/files/Metroid1.upak") && QFile::exists(m_path + "/out/files/Metroid3.upak") && QFile::exists(m_path + "/out/files/Metroid4.upak") &&
QFile::exists(m_path + "/out/files/Metroid2.upak") && QFile::exists(m_path + "/out/files/metroid5.upak") && QFile::exists(m_path + "/out/files/Metroid6.upak") &&
QFile::exists(m_path + "/out/files/Metroid3.upak") && QFile::exists(m_path + "/out/files/Metroid7.upak") && QFile::exists(m_path + "/out/files/Metroid8.upak") &&
QFile::exists(m_path + "/out/files/Metroid4.upak") && QFile::exists(m_path + "/out/files/MidiData.upak") && QFile::exists(m_path + "/out/files/MiscData.upak") &&
QFile::exists(m_path + "/out/files/metroid5.upak") && QFile::exists(m_path + "/out/files/NoARAM.upak") && QFile::exists(m_path + "/out/files/SamGunFx.upak") &&
QFile::exists(m_path + "/out/files/Metroid6.upak") && QFile::exists(m_path + "/out/files/SamusGun.upak") && QFile::exists(m_path + "/out/files/SlideShow.upak") &&
QFile::exists(m_path + "/out/files/Metroid7.upak") && QFile::exists(m_path + "/out/files/TestAnim.upak") && QFile::exists(m_path + "/out/files/Tweaks.upak");
QFile::exists(m_path + "/out/files/Metroid8.upak") &&
QFile::exists(m_path + "/out/files/MidiData.upak") &&
QFile::exists(m_path + "/out/files/MiscData.upak") &&
QFile::exists(m_path + "/out/files/NoARAM.upak") &&
QFile::exists(m_path + "/out/files/SamGunFx.upak") &&
QFile::exists(m_path + "/out/files/SamusGun.upak") &&
QFile::exists(m_path + "/out/files/SlideShow.upak") &&
QFile::exists(m_path + "/out/files/TestAnim.upak") &&
QFile::exists(m_path + "/out/files/Tweaks.upak");
} }
static bool GetDLPackage(const QString& path, QString& dlPackage) static bool GetDLPackage(const QString& path, QString& dlPackage) {
{ QProcess proc;
QProcess proc; proc.start(path, {"--dlpackage"}, QIODevice::ReadOnly);
proc.start(path, {"--dlpackage"}, QIODevice::ReadOnly); if (proc.waitForStarted()) {
if (proc.waitForStarted()) proc.waitForFinished();
{ if (proc.exitCode() == 100)
proc.waitForFinished(); dlPackage = QString::fromUtf8(proc.readLine()).trimmed();
if (proc.exitCode() == 100) return true;
dlPackage = QString::fromUtf8(proc.readLine()).trimmed(); }
return true; return false;
} }
bool MainWindow::checkDownloadedBinary() {
m_updateURDEButton->hide();
m_urdePath = QString();
m_heclPath = QString();
if (m_path.isEmpty()) {
m_ui->heclTabs->setCurrentIndex(1);
m_ui->downloadErrorLabel->setText(QStringLiteral("Set working directory to continue."), true);
enableOperations();
return false; return false;
} }
bool MainWindow::checkDownloadedBinary()
{
m_updateURDEButton->hide();
m_urdePath = QString();
m_heclPath = QString();
if (m_path.isEmpty())
{
m_ui->heclTabs->setCurrentIndex(1);
m_ui->downloadErrorLabel->setText(QStringLiteral("Set working directory to continue."), true);
enableOperations();
return false;
}
#if __APPLE__ #if __APPLE__
QString urdePath = m_path + "/URDE.app/Contents/MacOS/urde"; QString urdePath = m_path + "/URDE.app/Contents/MacOS/urde";
QString heclPath = m_path + "/URDE.app/Contents/MacOS/hecl"; QString heclPath = m_path + "/URDE.app/Contents/MacOS/hecl";
QString visigenPath = m_path + "/URDE.app/Contents/MacOS/visigen"; QString visigenPath = m_path + "/URDE.app/Contents/MacOS/visigen";
#elif _WIN32 #elif _WIN32
QString urdePath = m_path + "/urde.exe"; QString urdePath = m_path + "/urde.exe";
QString heclPath = m_path + "/hecl.exe"; QString heclPath = m_path + "/hecl.exe";
QString visigenPath = m_path + "/visigen.exe"; QString visigenPath = m_path + "/visigen.exe";
#else #else
QString urdePath = m_path + "/urde"; QString urdePath = m_path + "/urde";
QString heclPath = m_path + "/hecl"; QString heclPath = m_path + "/hecl";
QString visigenPath = m_path + "/visigen"; QString visigenPath = m_path + "/visigen";
#endif #endif
urdePath = QFileInfo(urdePath).absoluteFilePath(); urdePath = QFileInfo(urdePath).absoluteFilePath();
heclPath = QFileInfo(heclPath).absoluteFilePath(); heclPath = QFileInfo(heclPath).absoluteFilePath();
visigenPath = QFileInfo(visigenPath).absoluteFilePath(); visigenPath = QFileInfo(visigenPath).absoluteFilePath();
QString urdeDlPackage, heclDlPackage, visigenDlPackage; QString urdeDlPackage, heclDlPackage, visigenDlPackage;
if (GetDLPackage(urdePath, urdeDlPackage) && if (GetDLPackage(urdePath, urdeDlPackage) && GetDLPackage(heclPath, heclDlPackage) &&
GetDLPackage(heclPath, heclDlPackage) && GetDLPackage(visigenPath, visigenDlPackage)) {
GetDLPackage(visigenPath, visigenDlPackage)) if (!urdeDlPackage.isEmpty() && urdeDlPackage == heclDlPackage && urdeDlPackage == visigenDlPackage) {
{ URDEVersion v(urdeDlPackage);
if (!urdeDlPackage.isEmpty() && m_ui->currentBinaryLabel->setText(v.fileString(false));
urdeDlPackage == heclDlPackage && if (m_recommendedVersion.isValid() && v.isValid() && m_recommendedVersion.getVersion() > v.getVersion()) {
urdeDlPackage == visigenDlPackage) m_updateURDEButton->show();
{ }
URDEVersion v(urdeDlPackage); } else {
m_ui->currentBinaryLabel->setText(v.fileString(false)); m_ui->currentBinaryLabel->setText(QStringLiteral("unknown -- re-download recommended"));
if (m_recommendedVersion.isValid() && v.isValid() &&
m_recommendedVersion.getVersion() > v.getVersion())
{
m_updateURDEButton->show();
}
}
else
{
m_ui->currentBinaryLabel->setText(QStringLiteral("unknown -- re-download recommended"));
}
m_urdePath = urdePath;
m_heclPath = heclPath;
m_ui->downloadErrorLabel->setText({}, true);
enableOperations();
return true;
} }
m_urdePath = urdePath;
m_heclPath = heclPath;
m_ui->downloadErrorLabel->setText({}, true);
enableOperations();
return true;
} else {
m_ui->currentBinaryLabel->setText(QStringLiteral("none"));
m_ui->heclTabs->setCurrentIndex(1);
m_ui->downloadErrorLabel->setText(QStringLiteral("Press 'Download' to fetch latest URDE binary."), true);
enableOperations();
}
return false;
}
void MainWindow::setPath(const QString& path) {
QFileInfo finfo(path);
QString usePath;
if (!path.isEmpty())
usePath = finfo.absoluteFilePath();
if (!usePath.isEmpty() && !finfo.exists()) {
if (QMessageBox::question(this, QStringLiteral("Make Directory"),
QStringLiteral("%1 does not exist. Create it now?").arg(usePath)) == QMessageBox::Yes)
QDir().mkpath(usePath);
else else
{ usePath = QString();
m_ui->currentBinaryLabel->setText(QStringLiteral("none")); }
m_ui->heclTabs->setCurrentIndex(1);
m_ui->downloadErrorLabel->setText(QStringLiteral("Press 'Download' to fetch latest URDE binary."), true);
enableOperations();
}
return false; if (!usePath.isEmpty() && !finfo.isDir()) {
QMessageBox::warning(this, QStringLiteral("Directory Error"), QStringLiteral("%1 is not a directory").arg(usePath),
QMessageBox::Ok, QMessageBox::NoButton);
usePath = QString();
}
m_path = usePath;
m_settings.setValue(QStringLiteral("working_dir"), m_path);
if (!m_path.isEmpty()) {
m_ui->pathEdit->setText(m_path);
m_ui->downloadButton->setToolTip(QString());
m_ui->downloadButton->setEnabled(m_ui->binaryComboBox->isEnabled());
} else {
m_ui->downloadButton->setToolTip(QStringLiteral("Working directory must be set"));
m_ui->downloadButton->setEnabled(false);
m_ui->currentBinaryLabel->setText(QStringLiteral("none"));
}
m_ui->sysReqTable->updateFreeDiskSpace(m_path);
checkDownloadedBinary();
} }
void MainWindow::setPath(const QString& path) void MainWindow::initSlots() {
{ connect(&m_heclProc, &QProcess::readyRead, [=]() {
QFileInfo finfo(path); QByteArray bytes = m_heclProc.readAll();
QString usePath; setTextTermFormatting(bytes);
if (!path.isEmpty()) });
usePath = finfo.absoluteFilePath();
if (!usePath.isEmpty() && !finfo.exists())
{
if (QMessageBox::question(this, QStringLiteral("Make Directory"),
QStringLiteral("%1 does not exist. Create it now?").arg(usePath)) == QMessageBox::Yes)
QDir().mkpath(usePath);
else
usePath = QString();
}
if (!usePath.isEmpty() && !finfo.isDir()) connect(m_ui->extractBtn, SIGNAL(clicked()), this, SLOT(onExtract()));
{ connect(m_ui->packageBtn, SIGNAL(clicked()), this, SLOT(onPackage()));
QMessageBox::warning(this, QStringLiteral("Directory Error"), connect(m_ui->launchBtn, SIGNAL(clicked()), this, SLOT(onLaunch()));
QStringLiteral("%1 is not a directory").arg(usePath), m_ui->launchMenuBtn->setMenu(&m_launchMenu);
QMessageBox::Ok, QMessageBox::NoButton);
usePath = QString();
}
m_path = usePath; connect(m_ui->browseBtn, &QPushButton::clicked, [=]() {
m_settings.setValue(QStringLiteral("working_dir"), m_path); FileDirDialog dialog(this);
dialog.setDirectory(m_path);
dialog.setWindowTitle("Select Working Directory");
int res = dialog.exec();
if (res == QFileDialog::Rejected)
return;
if (!m_path.isEmpty()) if (dialog.selectedFiles().size() <= 0)
{ return;
m_ui->pathEdit->setText(m_path);
m_ui->downloadButton->setToolTip(QString());
m_ui->downloadButton->setEnabled(m_ui->binaryComboBox->isEnabled());
}
else
{
m_ui->downloadButton->setToolTip(QStringLiteral("Working directory must be set"));
m_ui->downloadButton->setEnabled(false);
m_ui->currentBinaryLabel->setText(QStringLiteral("none"));
}
m_ui->sysReqTable->updateFreeDiskSpace(m_path); setPath(dialog.selectedFiles().at(0));
checkDownloadedBinary(); });
connect(m_ui->downloadButton, SIGNAL(clicked()), this, SLOT(onDownloadPressed()));
} }
void MainWindow::initSlots() void MainWindow::setTextTermFormatting(const QString& text) {
{ m_inContinueNote = false;
connect(&m_heclProc, &QProcess::readyRead, [=](){
QByteArray bytes = m_heclProc.readAll();
setTextTermFormatting(bytes);
});
connect(m_ui->extractBtn, SIGNAL(clicked()), this, SLOT(onExtract())); QRegExp const escapeSequenceExpression(R"(\x1B\[([\d;\?FA]+)([mlh]?))");
connect(m_ui->packageBtn, SIGNAL(clicked()), this, SLOT(onPackage())); QTextCharFormat defaultTextCharFormat = m_cursor.charFormat();
connect(m_ui->launchBtn, SIGNAL(clicked()), this, SLOT(onLaunch())); int offset = escapeSequenceExpression.indexIn(text);
m_ui->launchMenuBtn->setMenu(&m_launchMenu); ReturnInsert(m_cursor, text.mid(0, offset));
QTextCharFormat textCharFormat = defaultTextCharFormat;
connect(m_ui->browseBtn, &QPushButton::clicked, [=]() { while (offset >= 0) {
FileDirDialog dialog(this); int previousOffset = offset + escapeSequenceExpression.matchedLength();
dialog.setDirectory(m_path); QStringList captures = escapeSequenceExpression.capturedTexts();
dialog.setWindowTitle("Select Working Directory"); if (captures.size() >= 3 && captures[2] == "m") {
int res = dialog.exec(); QStringList capturedTexts = captures[1].split(';');
if (res == QFileDialog::Rejected) QListIterator<QString> i(capturedTexts);
return; while (i.hasNext()) {
bool ok = false;
if (dialog.selectedFiles().size() <= 0) int attribute = i.next().toInt(&ok);
return; Q_ASSERT(ok);
ParseEscapeSequence(attribute, i, textCharFormat, defaultTextCharFormat);
setPath(dialog.selectedFiles().at(0)); }
}); } else if (captures.size() >= 2 && (captures[1].endsWith('F') || captures[1].endsWith('A'))) {
int lineCount = captures[1].chopped(1).toInt();
connect(m_ui->downloadButton, SIGNAL(clicked()), this, SLOT(onDownloadPressed())); if (!lineCount)
} lineCount = 1;
for (int i = 0; i < lineCount; ++i) {
void MainWindow::setTextTermFormatting(const QString& text) m_cursor.movePosition(QTextCursor::PreviousBlock);
{ m_cursor.select(QTextCursor::BlockUnderCursor);
m_inContinueNote = false; m_cursor.removeSelectedText();
m_cursor.insertBlock();
QRegExp const escapeSequenceExpression(R"(\x1B\[([\d;\?FA]+)([mlh]?))"); }
QTextCharFormat defaultTextCharFormat = m_cursor.charFormat();
int offset = escapeSequenceExpression.indexIn(text);
ReturnInsert(m_cursor, text.mid(0, offset));
QTextCharFormat textCharFormat = defaultTextCharFormat;
while (offset >= 0) {
int previousOffset = offset + escapeSequenceExpression.matchedLength();
QStringList captures = escapeSequenceExpression.capturedTexts();
if (captures.size() >= 3 && captures[2] == "m")
{
QStringList capturedTexts = captures[1].split(';');
QListIterator<QString> i(capturedTexts);
while (i.hasNext()) {
bool ok = false;
int attribute = i.next().toInt(&ok);
Q_ASSERT(ok);
ParseEscapeSequence(attribute, i, textCharFormat, defaultTextCharFormat);
}
}
else if (captures.size() >= 2 && (captures[1].endsWith('F') || captures[1].endsWith('A')))
{
int lineCount = captures[1].chopped(1).toInt();
if (!lineCount)
lineCount = 1;
for (int i=0 ; i<lineCount ; ++i)
{
m_cursor.movePosition(QTextCursor::PreviousBlock);
m_cursor.select(QTextCursor::BlockUnderCursor);
m_cursor.removeSelectedText();
m_cursor.insertBlock();
}
}
offset = escapeSequenceExpression.indexIn(text, previousOffset);
if (offset < 0) {
ReturnInsert(m_cursor, text.mid(previousOffset), textCharFormat);
} else {
ReturnInsert(m_cursor, text.mid(previousOffset, offset - previousOffset), textCharFormat);
}
} }
m_cursor.setCharFormat(defaultTextCharFormat); offset = escapeSequenceExpression.indexIn(text, previousOffset);
m_ui->processOutput->ensureCursorVisible(); if (offset < 0) {
ReturnInsert(m_cursor, text.mid(previousOffset), textCharFormat);
} else {
ReturnInsert(m_cursor, text.mid(previousOffset, offset - previousOffset), textCharFormat);
}
}
m_cursor.setCharFormat(defaultTextCharFormat);
m_ui->processOutput->ensureCursorVisible();
} }
void MainWindow::insertContinueNote(const QString& text) void MainWindow::insertContinueNote(const QString& text) {
{ if (m_inContinueNote)
if (m_inContinueNote) return;
return; m_inContinueNote = true;
m_inContinueNote = true;
m_cursor.movePosition(QTextCursor::End); m_cursor.movePosition(QTextCursor::End);
QTextCharFormat textCharFormat = m_cursor.charFormat(); QTextCharFormat textCharFormat = m_cursor.charFormat();
textCharFormat.setForeground(QColor(0,255,0)); textCharFormat.setForeground(QColor(0, 255, 0));
m_cursor.insertText(text, textCharFormat); m_cursor.insertText(text, textCharFormat);
m_cursor.insertBlock(); m_cursor.insertBlock();
m_ui->processOutput->ensureCursorVisible(); m_ui->processOutput->ensureCursorVisible();
} }

View File

@ -18,49 +18,49 @@ namespace Ui {
class MainWindow; class MainWindow;
} }
class MainWindow : public QMainWindow class MainWindow : public QMainWindow {
{ Q_OBJECT
Q_OBJECT hecl::Runtime::FileStoreManager m_fileMgr;
hecl::Runtime::FileStoreManager m_fileMgr; hecl::CVarManager m_cvarManager;
hecl::CVarManager m_cvarManager; hecl::CVarCommons m_cvarCommons;
hecl::CVarCommons m_cvarCommons; Ui::MainWindow* m_ui;
Ui::MainWindow* m_ui; QTextCursor m_cursor;
QTextCursor m_cursor; QString m_path;
QString m_path; QString m_urdePath;
QString m_urdePath; QString m_heclPath;
QString m_heclPath; QProcess m_heclProc;
QProcess m_heclProc; DownloadManager m_dlManager;
DownloadManager m_dlManager; LaunchMenu m_launchMenu;
LaunchMenu m_launchMenu; QSettings m_settings;
QSettings m_settings; URDEVersion m_recommendedVersion;
URDEVersion m_recommendedVersion; QPushButton* m_updateURDEButton;
QPushButton* m_updateURDEButton; bool m_inContinueNote = false;
bool m_inContinueNote = false;
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void setTextTermFormatting(const QString& text);
void insertContinueNote(const QString& text);
private slots:
void onExtract();
void onExtractFinished(int exitCode);
void onPackage();
void onPackageFinished(int exitCode);
void onLaunch();
void onLaunchFinished(int exitCode);
void doHECLTerminate();
void onReturnPressed();
void onDownloadPressed();
void onUpdateURDEPressed();
private:
bool checkDownloadedBinary();
void setPath(const QString& path);
void initSlots();
void onIndexDownloaded(const QStringList& index);
void onBinaryDownloaded(QuaZip& file);
void onBinaryFailed();
void disableOperations();
void enableOperations();
bool isPackageComplete() const;
};
public:
explicit MainWindow(QWidget* parent = 0);
~MainWindow();
void setTextTermFormatting(const QString& text);
void insertContinueNote(const QString& text);
private slots:
void onExtract();
void onExtractFinished(int exitCode);
void onPackage();
void onPackageFinished(int exitCode);
void onLaunch();
void onLaunchFinished(int exitCode);
void doHECLTerminate();
void onReturnPressed();
void onDownloadPressed();
void onUpdateURDEPressed();
private:
bool checkDownloadedBinary();
void setPath(const QString& path);
void initSlots();
void onIndexDownloaded(const QStringList& index);
void onBinaryDownloaded(QuaZip& file);
void onBinaryFailed();
void disableOperations();
void enableOperations();
bool isPackageComplete() const;
};

View File

@ -21,343 +21,298 @@
#if __APPLE__ #if __APPLE__
#include "MacOSSystemVersion.hpp" #include "MacOSSystemVersion.hpp"
#elif _WIN32 #elif _WIN32
static QString GetWindowsVersionString() static QString GetWindowsVersionString() {
{ if (IsWindows10OrGreater())
if (IsWindows10OrGreater()) return QStringLiteral("Windows 10");
return QStringLiteral("Windows 10"); else if (IsWindows8Point1OrGreater())
else if (IsWindows8Point1OrGreater()) return QStringLiteral("Windows 8.1");
return QStringLiteral("Windows 8.1"); else if (IsWindows8OrGreater())
else if (IsWindows8OrGreater()) return QStringLiteral("Windows 8");
return QStringLiteral("Windows 8"); else if (IsWindows7SP1OrGreater())
else if (IsWindows7SP1OrGreater()) return QStringLiteral("Windows 7 SP1");
return QStringLiteral("Windows 7 SP1"); else if (IsWindows7OrGreater())
else if (IsWindows7OrGreater()) return QStringLiteral("Windows 7");
return QStringLiteral("Windows 7"); else if (IsWindowsVistaOrGreater())
else if (IsWindowsVistaOrGreater()) return QStringLiteral("Windows Vista");
return QStringLiteral("Windows Vista"); else if (IsWindowsXPOrGreater())
else if (IsWindowsXPOrGreater()) return QStringLiteral("Windows XP");
return QStringLiteral("Windows XP"); else
else return QStringLiteral("Windows Old And Won't Work");
return QStringLiteral("Windows Old And Won't Work");
} }
#endif #endif
SysReqTableModel::SysReqTableModel(QObject* parent) SysReqTableModel::SysReqTableModel(QObject* parent) : QAbstractTableModel(parent) {
: QAbstractTableModel(parent)
{
#ifdef __linux__ #ifdef __linux__
QFile file("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"); QFile file("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq");
if (file.open(QFile::ReadOnly)) if (file.open(QFile::ReadOnly)) {
{ QString str(file.readAll());
QString str(file.readAll()); m_cpuSpeed = str.toInt() / 1000;
m_cpuSpeed = str.toInt() / 1000; m_cpuSpeedStr.sprintf("%g GHz", m_cpuSpeed / 1000.0);
m_cpuSpeedStr.sprintf("%g GHz", m_cpuSpeed / 1000.0); }
}
#elif defined(__APPLE__) #elif defined(__APPLE__)
QProcess spProc; QProcess spProc;
spProc.start("system_profiler", {"-xml", "SPHardwareDataType"}, QProcess::ReadOnly); spProc.start("system_profiler", {"-xml", "SPHardwareDataType"}, QProcess::ReadOnly);
spProc.waitForFinished(); spProc.waitForFinished();
QDomDocument spDoc; QDomDocument spDoc;
spDoc.setContent(spProc.readAll()); spDoc.setContent(spProc.readAll());
QDomElement spDocElem = spDoc.documentElement(); QDomElement spDocElem = spDoc.documentElement();
QDomElement n = spDocElem.firstChildElement("array").firstChildElement("dict").firstChildElement("key"); QDomElement n = spDocElem.firstChildElement("array").firstChildElement("dict").firstChildElement("key");
while (!n.isNull() && n.text() != "_items") while (!n.isNull() && n.text() != "_items")
n = n.nextSiblingElement("key"); n = n.nextSiblingElement("key");
if (!n.isNull()) if (!n.isNull()) {
{ n = n.nextSiblingElement("array").firstChildElement("dict").firstChildElement("key");
n = n.nextSiblingElement("array").firstChildElement("dict").firstChildElement("key"); while (!n.isNull() && n.text() != "current_processor_speed")
while (!n.isNull() && n.text() != "current_processor_speed") n = n.nextSiblingElement("key");
n = n.nextSiblingElement("key"); if (!n.isNull()) {
if (!n.isNull()) n = n.nextSiblingElement("string");
{ double speed = n.text().split(' ').front().toDouble();
n = n.nextSiblingElement("string"); m_cpuSpeed = uint64_t(speed * 1000.0);
double speed = n.text().split(' ').front().toDouble(); m_cpuSpeedStr.sprintf("%g GHz", speed);
m_cpuSpeed = uint64_t(speed * 1000.0);
m_cpuSpeedStr.sprintf("%g GHz", speed);
}
} }
}
#elif _WIN32 #elif _WIN32
HKEY hkey; HKEY hkey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _SYS_STR("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), 0,
_SYS_STR("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) {
0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) DWORD MHz;
{ DWORD size = sizeof(MHz);
DWORD MHz; if (RegQueryValueEx(hkey, _SYS_STR("~MHz"), nullptr, nullptr, (LPBYTE)&MHz, &size) == ERROR_SUCCESS) {
DWORD size = sizeof(MHz); m_cpuSpeed = uint64_t(MHz);
if (RegQueryValueEx(hkey, _SYS_STR("~MHz"), nullptr, nullptr, m_cpuSpeedStr.sprintf("%1.1f GHz", MHz / 1000.f);
(LPBYTE)&MHz, &size) == ERROR_SUCCESS)
{
m_cpuSpeed = uint64_t(MHz);
m_cpuSpeedStr.sprintf("%1.1f GHz", MHz / 1000.f);
}
} }
RegCloseKey(hkey); }
RegCloseKey(hkey);
#else #else
/* This only works for Skylake+ */ /* This only works for Skylake+ */
int regs[4] = {}; int regs[4] = {};
zeus::getCpuInfo(0, regs); zeus::getCpuInfo(0, regs);
if (regs[0] >= 0x16) if (regs[0] >= 0x16) {
{ zeus::getCpuInfo(0x16, regs);
zeus::getCpuInfo(0x16, regs); m_cpuSpeed = uint64_t(regs[0]);
m_cpuSpeed = uint64_t(regs[0]); }
} m_cpuSpeedStr.sprintf("%g GHz", m_cpuSpeed / 1000.f);
m_cpuSpeedStr.sprintf("%g GHz", m_cpuSpeed / 1000.f);
#endif #endif
#if _WIN32 #if _WIN32
ULONGLONG memSize; ULONGLONG memSize;
GetPhysicallyInstalledSystemMemory(&memSize); GetPhysicallyInstalledSystemMemory(&memSize);
m_memorySize = memSize * 1024; m_memorySize = memSize * 1024;
#else #else
m_memorySize = uint64_t(sysconf(_SC_PHYS_PAGES)) * sysconf(_SC_PAGESIZE); m_memorySize = uint64_t(sysconf(_SC_PHYS_PAGES)) * sysconf(_SC_PAGESIZE);
#endif #endif
m_memorySizeStr.sprintf("%g GiB", m_memorySize / 1024.f / 1024.f / 1024.f); m_memorySizeStr.sprintf("%g GiB", m_memorySize / 1024.f / 1024.f / 1024.f);
#ifdef __APPLE__ #ifdef __APPLE__
GetMacOSSystemVersion(m_macosMajor, m_macosMinor, m_macosPatch); GetMacOSSystemVersion(m_macosMajor, m_macosMinor, m_macosPatch);
if (m_macosPatch == 0) if (m_macosPatch == 0)
m_osVersion.sprintf("macOS %d.%d", m_macosMajor, m_macosMinor); m_osVersion.sprintf("macOS %d.%d", m_macosMajor, m_macosMinor);
else else
m_osVersion.sprintf("macOS %d.%d.%d", m_macosMajor, m_macosMinor, m_macosPatch); m_osVersion.sprintf("macOS %d.%d.%d", m_macosMajor, m_macosMinor, m_macosPatch);
#elif _WIN32 #elif _WIN32
m_win7SP1OrGreater = IsWindows7SP1OrGreater(); m_win7SP1OrGreater = IsWindows7SP1OrGreater();
m_osVersion = GetWindowsVersionString(); m_osVersion = GetWindowsVersionString();
#elif __linux__ #elif __linux__
m_osVersion = QStringLiteral("Linux"); m_osVersion = QStringLiteral("Linux");
#endif #endif
hecl::blender::FindBlender(m_blendMajor, m_blendMinor); hecl::blender::FindBlender(m_blendMajor, m_blendMinor);
if (m_blendMajor) if (m_blendMajor)
m_blendVersionStr = QStringLiteral("Blender ") + QString::number(m_blendMajor) + m_blendVersionStr =
'.' + QString::number(m_blendMinor); QStringLiteral("Blender ") + QString::number(m_blendMajor) + '.' + QString::number(m_blendMinor);
else else
m_blendVersionStr = QStringLiteral("Not Found"); m_blendVersionStr = QStringLiteral("Not Found");
} }
void SysReqTableModel::updateFreeDiskSpace(const QString& path) void SysReqTableModel::updateFreeDiskSpace(const QString& path) {
{ if (path.isEmpty()) {
if (path.isEmpty()) m_freeDiskSpace = 0;
{ m_freeDiskSpaceStr = QStringLiteral("<Set Working Directory>");
m_freeDiskSpace = 0; } else {
m_freeDiskSpaceStr = QStringLiteral("<Set Working Directory>"); m_freeDiskSpace = QStorageInfo(path).bytesFree();
} m_freeDiskSpaceStr.sprintf("%1.1f GB", m_freeDiskSpace / 1000.f / 1000.f / 1000.f);
else }
{ emit dataChanged(index(3, 0), index(3, 0));
m_freeDiskSpace = QStorageInfo(path).bytesFree();
m_freeDiskSpaceStr.sprintf("%1.1f GB", m_freeDiskSpace / 1000.f / 1000.f / 1000.f);
}
emit dataChanged(index(3, 0), index(3, 0));
} }
int SysReqTableModel::rowCount(const QModelIndex& parent) const int SysReqTableModel::rowCount(const QModelIndex& parent) const { return 7; }
{
return 7;
}
int SysReqTableModel::columnCount(const QModelIndex& parent) const int SysReqTableModel::columnCount(const QModelIndex& parent) const { return 2; }
{
return 2;
}
QVariant SysReqTableModel::data(const QModelIndex& index, int role) const QVariant SysReqTableModel::data(const QModelIndex& index, int role) const {
{ if (role != Qt::DisplayRole && role != Qt::UserRole) {
if (role != Qt::DisplayRole && role != Qt::UserRole)
{
return {};
}
if (role == Qt::UserRole)
{
switch (index.row())
{
case 0:
return true;
case 1:
return m_cpuSpeed >= 1500;
case 2:
return m_memorySize >= 0xC0000000;
case 3:
return m_freeDiskSpace >= qint64(5) * 1000 * 1000 * 1000;
case 4:
#ifdef __APPLE__
return m_macosMajor > 10 || m_macosMinor >= 9;
#elif defined(_WIN32)
return m_win7SP1OrGreater;
#else
return true;
#endif
case 5:
return isBlenderVersionOk();
}
}
else
{
if (index.column() == 0)
{
/* Recommended */
switch (index.row())
{
case 0:
#if ZEUS_ARCH_X86 || ZEUS_ARCH_X86_64
return QStringLiteral("x86_64");
#else
return {};
#endif
case 1:
return QStringLiteral("1.5 GHz");
case 2:
return QStringLiteral("3 GiB");
case 3:
return QStringLiteral("5 GB (MP1)");
case 4:
#ifdef __APPLE__
return QStringLiteral("macOS 10.9");
#elif defined(_WIN32)
return QStringLiteral("Windows 7 SP1");
#elif defined(__linux__)
return QStringLiteral("Linux");
#else
return {};
#endif
case 5:
return QStringLiteral("Blender 2.78");
}
}
else if (index.column() == 1)
{
/* Your System */
switch (index.row())
{
case 0:
#if ZEUS_ARCH_X86 || ZEUS_ARCH_X86_64
return CurArchitectureString;
#else
return {};
#endif
case 1:
return m_cpuSpeedStr;
case 2:
return m_memorySizeStr;
case 3:
return m_freeDiskSpaceStr;
case 4:
return m_osVersion;
case 5:
return m_blendVersionStr;
}
}
}
return {}; return {};
} }
QVariant SysReqTableModel::headerData(int section, Qt::Orientation orientation, int role) const if (role == Qt::UserRole) {
{ switch (index.row()) {
if (role != Qt::DisplayRole) case 0:
{ return true;
case 1:
return m_cpuSpeed >= 1500;
case 2:
return m_memorySize >= 0xC0000000;
case 3:
return m_freeDiskSpace >= qint64(5) * 1000 * 1000 * 1000;
case 4:
#ifdef __APPLE__
return m_macosMajor > 10 || m_macosMinor >= 9;
#elif defined(_WIN32)
return m_win7SP1OrGreater;
#else
return true;
#endif
case 5:
return isBlenderVersionOk();
}
} else {
if (index.column() == 0) {
/* Recommended */
switch (index.row()) {
case 0:
#if ZEUS_ARCH_X86 || ZEUS_ARCH_X86_64
return QStringLiteral("x86_64");
#else
return {}; return {};
#endif
case 1:
return QStringLiteral("1.5 GHz");
case 2:
return QStringLiteral("3 GiB");
case 3:
return QStringLiteral("5 GB (MP1)");
case 4:
#ifdef __APPLE__
return QStringLiteral("macOS 10.9");
#elif defined(_WIN32)
return QStringLiteral("Windows 7 SP1");
#elif defined(__linux__)
return QStringLiteral("Linux");
#else
return {};
#endif
case 5:
return QStringLiteral("Blender 2.78");
}
} else if (index.column() == 1) {
/* Your System */
switch (index.row()) {
case 0:
#if ZEUS_ARCH_X86 || ZEUS_ARCH_X86_64
return CurArchitectureString;
#else
return {};
#endif
case 1:
return m_cpuSpeedStr;
case 2:
return m_memorySizeStr;
case 3:
return m_freeDiskSpaceStr;
case 4:
return m_osVersion;
case 5:
return m_blendVersionStr;
}
} }
}
return {};
}
if (orientation == Qt::Horizontal) QVariant SysReqTableModel::headerData(int section, Qt::Orientation orientation, int role) const {
{ if (role != Qt::DisplayRole) {
switch (section) return {};
{ }
case 0:
default: if (orientation == Qt::Horizontal) {
return QStringLiteral("Recommended"); switch (section) {
case 1: case 0:
return QStringLiteral("Your System"); default:
} return QStringLiteral("Recommended");
case 1:
return QStringLiteral("Your System");
} }
} else {
switch (section) {
case 0:
default:
return QStringLiteral("Architecture");
case 1:
return QStringLiteral("CPU Speed");
case 2:
return QStringLiteral("Memory");
case 3:
return QStringLiteral("Disk Space");
case 4:
return QStringLiteral("OS");
case 5:
return QStringLiteral("Blender");
case 6:
return QStringLiteral("Vector ISA");
}
}
}
void SysReqTableView::paintEvent(QPaintEvent* e) {
int tableWidth = columnWidth(0) + columnWidth(1);
int tableX = verticalHeader()->width() + columnViewportPosition(0);
int tableY = horizontalHeader()->height();
for (int i = 0; i < 6; ++i) {
QWidget* w = std::get<0>(m_backgroundWidgets[i]);
QPalette pal = palette();
if (m_model.data(m_model.index(i, 0), Qt::UserRole).toBool())
pal.setColor(QPalette::Background, QColor::fromRgbF(0.f, 1.f, 0.f, 0.2f));
else else
{ pal.setColor(QPalette::Background, QColor::fromRgbF(1.f, 0.f, 0.f, 0.2f));
switch (section) w->setPalette(pal);
{
case 0: QSequentialAnimationGroup* animation = std::get<1>(m_backgroundWidgets[i]);
default: QPropertyAnimation* pAnimation = static_cast<QPropertyAnimation*>(animation->animationAt(1));
return QStringLiteral("Architecture"); bool& running = std::get<2>(m_backgroundWidgets[i]);
case 1: if (!running) {
return QStringLiteral("CPU Speed"); w->setGeometry(QRect(tableX, tableY + rowViewportPosition(i), 0, rowHeight(i)));
case 2: pAnimation->setStartValue(QRect(tableX, tableY + rowViewportPosition(i), 0, rowHeight(i)));
return QStringLiteral("Memory"); pAnimation->setEndValue(QRect(tableX, tableY + rowViewportPosition(i), tableWidth, rowHeight(i)));
case 3: animation->start();
return QStringLiteral("Disk Space"); running = true;
case 4:
return QStringLiteral("OS");
case 5:
return QStringLiteral("Blender");
case 6:
return QStringLiteral("Vector ISA");
}
} }
if (animation->state() == QAbstractAnimation::State::Running)
pAnimation->setEndValue(QRect(tableX, tableY + rowViewportPosition(i), tableWidth, rowHeight(i)));
else
w->setGeometry(QRect(tableX, tableY + rowViewportPosition(i), tableWidth, rowHeight(i)));
}
QTableView::paintEvent(e);
} }
void SysReqTableView::paintEvent(QPaintEvent* e) SysReqTableView::SysReqTableView(QWidget* parent) : QTableView(parent), m_vectorISATable(this) {
{ setModel(&m_model);
int tableWidth = columnWidth(0) + columnWidth(1); setIndexWidget(m_model.index(6, 0), &m_vectorISATable);
int tableX = verticalHeader()->width() + columnViewportPosition(0); setSpan(6, 0, 1, 2);
int tableY = horizontalHeader()->height();
for (int i = 0; i < 6; ++i)
{
QWidget* w = std::get<0>(m_backgroundWidgets[i]);
QPalette pal = palette(); horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
if (m_model.data(m_model.index(i, 0), Qt::UserRole).toBool()) verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
pal.setColor(QPalette::Background, QColor::fromRgbF(0.f, 1.f, 0.f, 0.2f)); setSelectionMode(QAbstractItemView::SelectionMode::NoSelection);
else setFocusPolicy(Qt::NoFocus);
pal.setColor(QPalette::Background, QColor::fromRgbF(1.f, 0.f, 0.f, 0.2f));
w->setPalette(pal);
QSequentialAnimationGroup* animation = std::get<1>(m_backgroundWidgets[i]); for (int i = 0; i < 6; ++i) {
QPropertyAnimation* pAnimation = static_cast<QPropertyAnimation*>(animation->animationAt(1)); QWidget* w = new QWidget(this);
bool& running = std::get<2>(m_backgroundWidgets[i]); std::get<0>(m_backgroundWidgets[i]) = w;
if (!running)
{ QPalette pal = palette();
w->setGeometry(QRect(tableX, tableY + rowViewportPosition(i), 0, rowHeight(i))); if (m_model.data(m_model.index(i, 0), Qt::UserRole).toBool())
pAnimation->setStartValue(QRect(tableX, tableY + rowViewportPosition(i), 0, rowHeight(i))); pal.setColor(QPalette::Background, QColor::fromRgbF(0.f, 1.f, 0.f, 0.2f));
pAnimation->setEndValue(QRect(tableX, tableY + rowViewportPosition(i), tableWidth, rowHeight(i))); else
animation->start(); pal.setColor(QPalette::Background, QColor::fromRgbF(1.f, 0.f, 0.f, 0.2f));
running = true;
} w->setAutoFillBackground(true);
if (animation->state() == QAbstractAnimation::State::Running) w->setPalette(pal);
pAnimation->setEndValue(QRect(tableX, tableY + rowViewportPosition(i), tableWidth, rowHeight(i))); w->lower();
else w->show();
w->setGeometry(QRect(tableX, tableY + rowViewportPosition(i), tableWidth, rowHeight(i)));
} QPropertyAnimation* animation = new QPropertyAnimation(w, "geometry", this);
QTableView::paintEvent(e); animation->setDuration(2000);
} animation->setEasingCurve(QEasingCurve::Type::InOutCubic);
SysReqTableView::SysReqTableView(QWidget* parent) QSequentialAnimationGroup* seq = new QSequentialAnimationGroup(this);
: QTableView(parent), m_vectorISATable(this) std::get<1>(m_backgroundWidgets[i]) = seq;
{ seq->addPause(i * 100);
setModel(&m_model); seq->addAnimation(animation);
setIndexWidget(m_model.index(6, 0), &m_vectorISATable); }
setSpan(6, 0, 1, 2);
horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
setSelectionMode(QAbstractItemView::SelectionMode::NoSelection);
setFocusPolicy(Qt::NoFocus);
for (int i = 0; i < 6; ++i)
{
QWidget* w = new QWidget(this);
std::get<0>(m_backgroundWidgets[i]) = w;
QPalette pal = palette();
if (m_model.data(m_model.index(i, 0), Qt::UserRole).toBool())
pal.setColor(QPalette::Background, QColor::fromRgbF(0.f, 1.f, 0.f, 0.2f));
else
pal.setColor(QPalette::Background, QColor::fromRgbF(1.f, 0.f, 0.f, 0.2f));
w->setAutoFillBackground(true);
w->setPalette(pal);
w->lower();
w->show();
QPropertyAnimation* animation = new QPropertyAnimation(w, "geometry", this);
animation->setDuration(2000);
animation->setEasingCurve(QEasingCurve::Type::InOutCubic);
QSequentialAnimationGroup* seq = new QSequentialAnimationGroup(this);
std::get<1>(m_backgroundWidgets[i]) = seq;
seq->addPause(i * 100);
seq->addAnimation(animation);
}
} }

View File

@ -5,54 +5,51 @@
class QSequentialAnimationGroup; class QSequentialAnimationGroup;
class SysReqTableModel : public QAbstractTableModel class SysReqTableModel : public QAbstractTableModel {
{ Q_OBJECT
Q_OBJECT uint64_t m_cpuSpeed = 0;
uint64_t m_cpuSpeed = 0; QString m_cpuSpeedStr;
QString m_cpuSpeedStr; uint64_t m_memorySize = 0;
uint64_t m_memorySize = 0; QString m_memorySizeStr;
QString m_memorySizeStr; qint64 m_freeDiskSpace = 0;
qint64 m_freeDiskSpace = 0; QString m_freeDiskSpaceStr = QStringLiteral("<Set Working Directory>");
QString m_freeDiskSpaceStr = QStringLiteral("<Set Working Directory>");
#if __APPLE__ #if __APPLE__
int m_macosMajor = 0; int m_macosMajor = 0;
int m_macosMinor = 0; int m_macosMinor = 0;
int m_macosPatch = 0; int m_macosPatch = 0;
#elif _WIN32 #elif _WIN32
bool m_win7SP1OrGreater = false; bool m_win7SP1OrGreater = false;
#endif #endif
QString m_osVersion; QString m_osVersion;
int m_blendMajor = 0; int m_blendMajor = 0;
int m_blendMinor = 0; int m_blendMinor = 0;
QString m_blendVersionStr; QString m_blendVersionStr;
public: public:
SysReqTableModel(QObject* parent = Q_NULLPTR); SysReqTableModel(QObject* parent = Q_NULLPTR);
int rowCount(const QModelIndex& parent = QModelIndex()) const; int rowCount(const QModelIndex& parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex& parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
bool isBlenderVersionOk() const bool isBlenderVersionOk() const { return m_blendMajor > 2 || (m_blendMajor == 2 && m_blendMinor >= 78); }
{ return m_blendMajor > 2 || (m_blendMajor == 2 && m_blendMinor >= 78); } void updateFreeDiskSpace(const QString& path);
void updateFreeDiskSpace(const QString& path);
}; };
class SysReqTableView : public QTableView class SysReqTableView : public QTableView {
{ Q_OBJECT
Q_OBJECT SysReqTableModel m_model;
SysReqTableModel m_model; VectorISATableView m_vectorISATable;
VectorISATableView m_vectorISATable; std::tuple<QWidget*, QSequentialAnimationGroup*, bool> m_backgroundWidgets[6] = {};
std::tuple<QWidget*, QSequentialAnimationGroup*, bool> m_backgroundWidgets[6] = {};
public:
SysReqTableView(QWidget* parent = Q_NULLPTR);
void paintEvent(QPaintEvent* e) Q_DECL_OVERRIDE;
const SysReqTableModel& getModel() const { return m_model; }
const VectorISATableView& getVectorISATable() const { return m_vectorISATable; }
bool willRun(const URDEVersion& v) const
{
return v.getArchitecture() == CurArchitecture && v.getPlatform() == CurPlatform &&
m_vectorISATable.willRun(v.getVectorISA());
}
bool isBlenderVersionOk() const { return m_model.isBlenderVersionOk(); }
void updateFreeDiskSpace(const QString& path) { m_model.updateFreeDiskSpace(path); }
};
public:
SysReqTableView(QWidget* parent = Q_NULLPTR);
void paintEvent(QPaintEvent* e) Q_DECL_OVERRIDE;
const SysReqTableModel& getModel() const { return m_model; }
const VectorISATableView& getVectorISATable() const { return m_vectorISATable; }
bool willRun(const URDEVersion& v) const {
return v.getArchitecture() == CurArchitecture && v.getPlatform() == CurPlatform &&
m_vectorISATable.willRun(v.getVectorISA());
}
bool isBlenderVersionOk() const { return m_model.isBlenderVersionOk(); }
void updateFreeDiskSpace(const QString& path) { m_model.updateFreeDiskSpace(path); }
};

View File

@ -3,13 +3,12 @@
#include <QTableView> #include <QTableView>
#include "zeus/Math.hpp" #include "zeus/Math.hpp"
class VectorISATableModel : public QAbstractTableModel class VectorISATableModel : public QAbstractTableModel {
{ Q_OBJECT
Q_OBJECT
protected: protected:
const zeus::CPUInfo& m_features = zeus::cpuFeatures(); const zeus::CPUInfo& m_features = zeus::cpuFeatures();
public:
VectorISATableModel(QObject* parent = Q_NULLPTR) : QAbstractTableModel(parent) {}
int rowCount(const QModelIndex& parent = QModelIndex()) const { return 1; }
};
public:
VectorISATableModel(QObject* parent = Q_NULLPTR) : QAbstractTableModel(parent) {}
int rowCount(const QModelIndex& parent = QModelIndex()) const { return 1; }
};

View File

@ -2,107 +2,95 @@
#include "VectorISATableModel.hpp" #include "VectorISATableModel.hpp"
class VectorISATableModelIntel : public VectorISATableModel class VectorISATableModelIntel : public VectorISATableModel {
{ Q_OBJECT
Q_OBJECT
public: public:
VectorISATableModelIntel(QObject* parent = Q_NULLPTR) : VectorISATableModel(parent) {} VectorISATableModelIntel(QObject* parent = Q_NULLPTR) : VectorISATableModel(parent) {}
int columnCount(const QModelIndex &parent = QModelIndex()) const { return 7; } int columnCount(const QModelIndex& parent = QModelIndex()) const { return 7; }
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const {
{ if (role != Qt::DisplayRole && role != Qt::UserRole)
if (role != Qt::DisplayRole && role != Qt::UserRole) return {};
return {};
if (role == Qt::UserRole) if (role == Qt::UserRole) {
{ switch (index.column()) {
switch (index.column()) case 0:
{ default:
case 0: return true;
default: case 1:
return true; return m_features.SSE1;
case 1: case 2:
return m_features.SSE1; return m_features.SSE2;
case 2: case 3:
return m_features.SSE2; return m_features.SSE3;
case 3: case 4:
return m_features.SSE3; return m_features.SSE41;
case 4: case 5:
return m_features.SSE41; return m_features.AVX;
case 5: case 6:
return m_features.AVX; return m_features.AVX2;
case 6: }
return m_features.AVX2; } else {
} switch (index.column()) {
} case 0:
else default:
{ return QStringLiteral("x87");
switch (index.column()) case 1:
{ return QStringLiteral("SSE");
case 0: case 2:
default: return QStringLiteral("SSE2");
return QStringLiteral("x87"); case 3:
case 1: return QStringLiteral("SSE3");
return QStringLiteral("SSE"); case 4:
case 2: return QStringLiteral("SSE4.1");
return QStringLiteral("SSE2"); case 5:
case 3: return QStringLiteral("AVX");
return QStringLiteral("SSE3"); case 6:
case 4: return QStringLiteral("AVX2");
return QStringLiteral("SSE4.1"); }
case 5:
return QStringLiteral("AVX");
case 6:
return QStringLiteral("AVX2");
}
}
} }
}
VectorISA getISA(int idx) const VectorISA getISA(int idx) const {
{ switch (idx) {
switch (idx) default:
{ return VectorISA::Invalid;
default: case 0:
return VectorISA::Invalid; return VectorISA::X87;
case 0: case 1:
return VectorISA::X87; return VectorISA::SSE;
case 1: case 2:
return VectorISA::SSE; return VectorISA::SSE2;
case 2: case 3:
return VectorISA::SSE2; return VectorISA::SSE3;
case 3: case 4:
return VectorISA::SSE3; return VectorISA::SSE41;
case 4: case 5:
return VectorISA::SSE41; return VectorISA::AVX;
case 5: case 6:
return VectorISA::AVX; return VectorISA::AVX2;
case 6:
return VectorISA::AVX2;
}
} }
}
bool willRun(VectorISA visa) const bool willRun(VectorISA visa) const {
{ switch (visa) {
switch (visa) default:
{ return false;
default: case VectorISA::X87:
return false; return true;
case VectorISA::X87: case VectorISA::SSE:
return true; return m_features.SSE1;
case VectorISA::SSE: case VectorISA::SSE2:
return m_features.SSE1; return m_features.SSE2;
case VectorISA::SSE2: case VectorISA::SSE3:
return m_features.SSE2; return m_features.SSE3;
case VectorISA::SSE3: case VectorISA::SSE41:
return m_features.SSE3; return m_features.SSE41;
case VectorISA::SSE41: case VectorISA::AVX:
return m_features.SSE41; return m_features.AVX;
case VectorISA::AVX: case VectorISA::AVX2:
return m_features.AVX; return m_features.AVX2;
case VectorISA::AVX2:
return m_features.AVX2;
}
} }
}
}; };

View File

@ -3,93 +3,83 @@
#include <QPropertyAnimation> #include <QPropertyAnimation>
#include <QSequentialAnimationGroup> #include <QSequentialAnimationGroup>
void VectorISATableView::paintEvent(QPaintEvent* e) void VectorISATableView::paintEvent(QPaintEvent* e) {
{ QTableView* p = static_cast<QTableView*>(parent()->parent());
QTableView* p = static_cast<QTableView*>(parent()->parent()); int tableY = p->horizontalHeader()->height() + p->rowViewportPosition(6);
int tableY = p->horizontalHeader()->height() + p->rowViewportPosition(6); int rHeight = rowHeight(0);
int rHeight = rowHeight(0); for (int i = 0; i < 2; ++i) {
for (int i = 0; i < 2; ++i) int tableX;
{ int width = 0;
int tableX; if (i == 0) {
int width = 0; tableX = p->verticalHeader()->width() + columnViewportPosition(0);
if (i == 0) for (int j = 0; j <= m_maxISA; ++j)
{ width += columnWidth(j);
tableX = p->verticalHeader()->width() + columnViewportPosition(0); } else {
for (int j = 0; j <= m_maxISA; ++j) tableX = p->verticalHeader()->width() + columnViewportPosition(m_maxISA + 1);
width += columnWidth(j); for (int j = m_maxISA + 1; j < m_model.columnCount({}); ++j)
} width += columnWidth(j);
else
{
tableX = p->verticalHeader()->width() + columnViewportPosition(m_maxISA + 1);
for (int j = m_maxISA + 1; j < m_model.columnCount({}); ++j)
width += columnWidth(j);
}
QWidget* w = std::get<0>(m_backgroundWidgets[i]);
QSequentialAnimationGroup* animation = std::get<1>(m_backgroundWidgets[i]);
QPropertyAnimation* pAnimation = static_cast<QPropertyAnimation*>(animation->animationAt(1));
bool& running = std::get<2>(m_backgroundWidgets[i]);
if (!running)
{
w->setGeometry(QRect(tableX, tableY, 0, rHeight));
pAnimation->setStartValue(QRect(tableX, tableY, 0, rHeight));
pAnimation->setEndValue(QRect(tableX, tableY, width, rHeight));
animation->start();
running = true;
}
if (animation->state() == QAbstractAnimation::State::Running)
pAnimation->setEndValue(QRect(tableX, tableY, width, rHeight));
else
w->setGeometry(QRect(tableX, tableY, width, rHeight));
} }
QTableView::paintEvent(e);
QWidget* w = std::get<0>(m_backgroundWidgets[i]);
QSequentialAnimationGroup* animation = std::get<1>(m_backgroundWidgets[i]);
QPropertyAnimation* pAnimation = static_cast<QPropertyAnimation*>(animation->animationAt(1));
bool& running = std::get<2>(m_backgroundWidgets[i]);
if (!running) {
w->setGeometry(QRect(tableX, tableY, 0, rHeight));
pAnimation->setStartValue(QRect(tableX, tableY, 0, rHeight));
pAnimation->setEndValue(QRect(tableX, tableY, width, rHeight));
animation->start();
running = true;
}
if (animation->state() == QAbstractAnimation::State::Running)
pAnimation->setEndValue(QRect(tableX, tableY, width, rHeight));
else
w->setGeometry(QRect(tableX, tableY, width, rHeight));
}
QTableView::paintEvent(e);
} }
VectorISATableView::VectorISATableView(QWidget* parent) VectorISATableView::VectorISATableView(QWidget* parent) : QTableView(parent) {
: QTableView(parent) setModel(&m_model);
{
setModel(&m_model);
for (int i = 0; i < m_model.columnCount({}); ++i) for (int i = 0; i < m_model.columnCount({}); ++i) {
{ if (m_model.data(m_model.index(0, i), Qt::UserRole).toBool())
if (m_model.data(m_model.index(0, i), Qt::UserRole).toBool()) m_maxISA = i;
m_maxISA = i; else
else break;
break; }
}
horizontalHeader()->hide(); horizontalHeader()->hide();
horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
setFrameShape(QFrame::Shape::NoFrame); setFrameShape(QFrame::Shape::NoFrame);
verticalHeader()->hide(); verticalHeader()->hide();
verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
setSelectionMode(QAbstractItemView::SelectionMode::NoSelection); setSelectionMode(QAbstractItemView::SelectionMode::NoSelection);
setFocusPolicy(Qt::NoFocus); setFocusPolicy(Qt::NoFocus);
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i) {
{ QWidget* w = new QWidget(parent);
QWidget* w = new QWidget(parent); std::get<0>(m_backgroundWidgets[i]) = w;
std::get<0>(m_backgroundWidgets[i]) = w;
QPalette pal = palette(); QPalette pal = palette();
if (i == 0) if (i == 0)
pal.setColor(QPalette::Background, QColor::fromRgbF(0.f, 1.f, 0.f, 0.2f)); pal.setColor(QPalette::Background, QColor::fromRgbF(0.f, 1.f, 0.f, 0.2f));
else else
pal.setColor(QPalette::Background, QColor::fromRgbF(1.f, 0.f, 0.f, 0.2f)); pal.setColor(QPalette::Background, QColor::fromRgbF(1.f, 0.f, 0.f, 0.2f));
w->setAutoFillBackground(true); w->setAutoFillBackground(true);
w->setPalette(pal); w->setPalette(pal);
w->lower(); w->lower();
w->show(); w->show();
QPropertyAnimation* animation = new QPropertyAnimation(w, "geometry", this); QPropertyAnimation* animation = new QPropertyAnimation(w, "geometry", this);
animation->setDuration(2000); animation->setDuration(2000);
animation->setEasingCurve(QEasingCurve::Type::InOutCubic); animation->setEasingCurve(QEasingCurve::Type::InOutCubic);
QSequentialAnimationGroup* seq = new QSequentialAnimationGroup(this); QSequentialAnimationGroup* seq = new QSequentialAnimationGroup(this);
std::get<1>(m_backgroundWidgets[i]) = seq; std::get<1>(m_backgroundWidgets[i]) = seq;
seq->addPause(6 * 100); seq->addPause(6 * 100);
seq->addAnimation(animation); seq->addAnimation(animation);
} }
} }

View File

@ -9,18 +9,17 @@
class QSequentialAnimationGroup; class QSequentialAnimationGroup;
class VectorISATableView : public QTableView class VectorISATableView : public QTableView {
{ Q_OBJECT
Q_OBJECT
#if ZEUS_ARCH_X86_64 || ZEUS_ARCH_X86 #if ZEUS_ARCH_X86_64 || ZEUS_ARCH_X86
VectorISATableModelIntel m_model; VectorISATableModelIntel m_model;
#endif #endif
std::tuple<QWidget*, QSequentialAnimationGroup*, bool> m_backgroundWidgets[2] = {}; std::tuple<QWidget*, QSequentialAnimationGroup*, bool> m_backgroundWidgets[2] = {};
int m_maxISA = 0; int m_maxISA = 0;
public:
VectorISATableView(QWidget* parent = Q_NULLPTR);
void paintEvent(QPaintEvent* e) Q_DECL_OVERRIDE;
VectorISA getISA() const { return m_model.getISA(m_maxISA); }
bool willRun(VectorISA visa) const { return m_model.willRun(visa); }
};
public:
VectorISATableView(QWidget* parent = Q_NULLPTR);
void paintEvent(QPaintEvent* e) Q_DECL_OVERRIDE;
VectorISA getISA() const { return m_model.getISA(m_maxISA); }
bool willRun(VectorISA visa) const { return m_model.willRun(visa); }
};

View File

@ -5,60 +5,57 @@
extern "C" const uint8_t MAINICON_QT[]; extern "C" const uint8_t MAINICON_QT[];
static QIcon MakeAppIcon() static QIcon MakeAppIcon() {
{ QIcon ret;
QIcon ret;
const uint8_t* ptr = MAINICON_QT; const uint8_t* ptr = MAINICON_QT;
for (int i = 0; i < 6; ++i) for (int i = 0; i < 6; ++i) {
{ uint32_t size = *reinterpret_cast<const uint32_t*>(ptr);
uint32_t size = *reinterpret_cast<const uint32_t*>(ptr); ptr += 4;
ptr += 4;
QPixmap pm; QPixmap pm;
pm.loadFromData(ptr, size); pm.loadFromData(ptr, size);
ret.addPixmap(pm); ret.addPixmap(pm);
ptr += size; ptr += size;
} }
return ret; return ret;
} }
int main(int argc, char* argv[]) int main(int argc, char* argv[]) {
{ InitializePlatform();
InitializePlatform();
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif #endif
QApplication::setStyle(QStyleFactory::create("Fusion")); QApplication::setStyle(QStyleFactory::create("Fusion"));
QApplication a(argc, argv); QApplication a(argc, argv);
QApplication::setWindowIcon(MakeAppIcon()); QApplication::setWindowIcon(MakeAppIcon());
QPalette darkPalette; QPalette darkPalette;
darkPalette.setColor(QPalette::Window, QColor(53,53,53)); darkPalette.setColor(QPalette::Window, QColor(53, 53, 53));
darkPalette.setColor(QPalette::WindowText, Qt::white); darkPalette.setColor(QPalette::WindowText, Qt::white);
darkPalette.setColor(QPalette::Base, QColor(42,42,42)); darkPalette.setColor(QPalette::Base, QColor(42, 42, 42));
darkPalette.setColor(QPalette::Disabled, QPalette::Base, QColor(25,25,25,53)); darkPalette.setColor(QPalette::Disabled, QPalette::Base, QColor(25, 25, 25, 53));
darkPalette.setColor(QPalette::AlternateBase, QColor(53,53,53)); darkPalette.setColor(QPalette::AlternateBase, QColor(53, 53, 53));
darkPalette.setColor(QPalette::ToolTipBase, QColor(42,42,42)); darkPalette.setColor(QPalette::ToolTipBase, QColor(42, 42, 42));
darkPalette.setColor(QPalette::ToolTipText, Qt::white); darkPalette.setColor(QPalette::ToolTipText, Qt::white);
darkPalette.setColor(QPalette::Text, Qt::white); darkPalette.setColor(QPalette::Text, Qt::white);
darkPalette.setColor(QPalette::Disabled, QPalette::Text, QColor(255,255,255,120)); darkPalette.setColor(QPalette::Disabled, QPalette::Text, QColor(255, 255, 255, 120));
darkPalette.setColor(QPalette::Button, QColor(53,53,53)); darkPalette.setColor(QPalette::Button, QColor(53, 53, 53));
darkPalette.setColor(QPalette::Disabled, QPalette::Button, QColor(53,53,53,53)); darkPalette.setColor(QPalette::Disabled, QPalette::Button, QColor(53, 53, 53, 53));
darkPalette.setColor(QPalette::ButtonText, Qt::white); darkPalette.setColor(QPalette::ButtonText, Qt::white);
darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(255,255,255,120)); darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(255, 255, 255, 120));
darkPalette.setColor(QPalette::BrightText, Qt::red); darkPalette.setColor(QPalette::BrightText, Qt::red);
darkPalette.setColor(QPalette::Link, QColor(42,130,218)); darkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
darkPalette.setColor(QPalette::Highlight, QColor(42,130,218)); darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
darkPalette.setColor(QPalette::Disabled, QPalette::Highlight, QColor(42,130,218,53)); darkPalette.setColor(QPalette::Disabled, QPalette::Highlight, QColor(42, 130, 218, 53));
darkPalette.setColor(QPalette::HighlightedText, Qt::white); darkPalette.setColor(QPalette::HighlightedText, Qt::white);
darkPalette.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(255,255,255,120)); darkPalette.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(255, 255, 255, 120));
a.setPalette(darkPalette); a.setPalette(darkPalette);
MainWindow w; MainWindow w;
w.show(); w.show();
return a.exec(); return a.exec();
} }