2024-03-29 05:43:46 +00:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2024-08-19 04:25:15 +00:00
|
|
|
#include <QClipboard>
|
2024-03-29 05:43:46 +00:00
|
|
|
#include <QDesktopServices>
|
|
|
|
#include <QMenu>
|
2024-07-05 23:57:54 +00:00
|
|
|
#include <QMessageBox>
|
2024-03-29 05:43:46 +00:00
|
|
|
#include <QTreeWidget>
|
|
|
|
#include <QTreeWidgetItem>
|
2024-07-05 23:57:54 +00:00
|
|
|
|
Cheats/Patches (#493)
* Cheats/Patches
Adds the possibility of applying cheats/patches according to the specific game serial+version
The logic for adding modifications has not yet been implemented!
Interface based on issues/372 https://github.com/shadps4-emu/shadPS4/issues/372
[X]Front-end
[]Back-end
Create a synchronized fork of the cheats/patches repository
* Clang Format
* separate files
The code has been separated into separate files as suggested by georgemoralis.
Added the Patch tab, which has not been implemented yet.
Added the 'applyCheat' area to apply the modification, not implemented yet...
And added LOG_INFO.
* reuse
* initial implementation of cheat functionality
* Update cheats_patches.cpp
sets all added buttons to the size of the largest button.
and fixes some aesthetic issues.
* move eboot_address to module.h
fixes the non-qt builds and makes more sense to be there anyway
* Patchs menu and fixes
adds the possibility to download Patches, it does not modify the memory yet.
and some other fixes
* MemoryPatcher namespace, activate cheats on start
* format
* initial patch implementation
* format
* format again...
* convertValueToHex
* Fixes
Choosing which cheat file to use.
And some other fixes
* fix bytes16, bytes32, bytes64 type patches
If a patch is any of these types we convert it from little endian to big endian
* format
* format again :(
* Implement pattern scanning for mask type patches
* add check to stop patches applying to wrong game
previously if you added a patch to a game, but closed the window and opened a different game it would still try to apply the patch, this is now fixed
* format
* Fix 'Hint' 0x400000 | and Author
* Management |save checkbox | shadps4 repository
MENU - Cheats/Patches Management (implementing Patches)
save patches checkbox
add shadps4 repository
* Load saved patches, miscellaneous fixes
* Fix an issue with mask patches not being saved
* format + remove debug log
* multiple patches | TR translation for cheats/patches
* clang
* ENABLE_QT_GUI
* OK
* move memory_patcher to qt_gui
* clang
* add cheats hu_HU
* fix log
* Remove the item from the patchesListView if no patches were added (the game has patches, but not for the current version)
---------
Co-authored-by: CrazyBloo <CrazyBloo@users.noreply.github.com>
2024-08-29 04:18:50 +00:00
|
|
|
#include "cheats_patches.h"
|
2024-12-25 07:30:09 +00:00
|
|
|
#include "common/config.h"
|
|
|
|
#include "common/version.h"
|
|
|
|
#include "compatibility_info.h"
|
2024-03-29 05:43:46 +00:00
|
|
|
#include "game_info.h"
|
2024-06-11 02:42:21 +00:00
|
|
|
#include "trophy_viewer.h"
|
2024-03-29 05:43:46 +00:00
|
|
|
|
2024-07-05 23:57:54 +00:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
#include <ShlObj.h>
|
|
|
|
#include <Windows.h>
|
|
|
|
#include <objbase.h>
|
|
|
|
#include <shlguid.h>
|
|
|
|
#include <shobjidl.h>
|
2024-09-25 15:39:04 +00:00
|
|
|
#include <wrl/client.h>
|
2024-07-05 23:57:54 +00:00
|
|
|
#endif
|
Cheats/Patches (#493)
* Cheats/Patches
Adds the possibility of applying cheats/patches according to the specific game serial+version
The logic for adding modifications has not yet been implemented!
Interface based on issues/372 https://github.com/shadps4-emu/shadPS4/issues/372
[X]Front-end
[]Back-end
Create a synchronized fork of the cheats/patches repository
* Clang Format
* separate files
The code has been separated into separate files as suggested by georgemoralis.
Added the Patch tab, which has not been implemented yet.
Added the 'applyCheat' area to apply the modification, not implemented yet...
And added LOG_INFO.
* reuse
* initial implementation of cheat functionality
* Update cheats_patches.cpp
sets all added buttons to the size of the largest button.
and fixes some aesthetic issues.
* move eboot_address to module.h
fixes the non-qt builds and makes more sense to be there anyway
* Patchs menu and fixes
adds the possibility to download Patches, it does not modify the memory yet.
and some other fixes
* MemoryPatcher namespace, activate cheats on start
* format
* initial patch implementation
* format
* format again...
* convertValueToHex
* Fixes
Choosing which cheat file to use.
And some other fixes
* fix bytes16, bytes32, bytes64 type patches
If a patch is any of these types we convert it from little endian to big endian
* format
* format again :(
* Implement pattern scanning for mask type patches
* add check to stop patches applying to wrong game
previously if you added a patch to a game, but closed the window and opened a different game it would still try to apply the patch, this is now fixed
* format
* Fix 'Hint' 0x400000 | and Author
* Management |save checkbox | shadps4 repository
MENU - Cheats/Patches Management (implementing Patches)
save patches checkbox
add shadps4 repository
* Load saved patches, miscellaneous fixes
* Fix an issue with mask patches not being saved
* format + remove debug log
* multiple patches | TR translation for cheats/patches
* clang
* ENABLE_QT_GUI
* OK
* move memory_patcher to qt_gui
* clang
* add cheats hu_HU
* fix log
* Remove the item from the patchesListView if no patches were added (the game has patches, but not for the current version)
---------
Co-authored-by: CrazyBloo <CrazyBloo@users.noreply.github.com>
2024-08-29 04:18:50 +00:00
|
|
|
#include "common/path_util.h"
|
2024-07-05 23:57:54 +00:00
|
|
|
|
2024-06-11 02:42:21 +00:00
|
|
|
class GuiContextMenus : public QObject {
|
|
|
|
Q_OBJECT
|
2024-03-29 05:43:46 +00:00
|
|
|
public:
|
2024-12-25 07:30:09 +00:00
|
|
|
void RequestGameMenu(const QPoint& pos, QVector<GameInfo> m_games,
|
|
|
|
std::shared_ptr<CompatibilityInfoClass> m_compat_info,
|
|
|
|
QTableWidget* widget, bool isList) {
|
2024-03-29 05:43:46 +00:00
|
|
|
QPoint global_pos = widget->viewport()->mapToGlobal(pos);
|
|
|
|
int itemID = 0;
|
|
|
|
if (isList) {
|
|
|
|
itemID = widget->currentRow();
|
|
|
|
} else {
|
|
|
|
itemID = widget->currentRow() * widget->columnCount() + widget->currentColumn();
|
|
|
|
}
|
|
|
|
|
Cheats/Patches (#493)
* Cheats/Patches
Adds the possibility of applying cheats/patches according to the specific game serial+version
The logic for adding modifications has not yet been implemented!
Interface based on issues/372 https://github.com/shadps4-emu/shadPS4/issues/372
[X]Front-end
[]Back-end
Create a synchronized fork of the cheats/patches repository
* Clang Format
* separate files
The code has been separated into separate files as suggested by georgemoralis.
Added the Patch tab, which has not been implemented yet.
Added the 'applyCheat' area to apply the modification, not implemented yet...
And added LOG_INFO.
* reuse
* initial implementation of cheat functionality
* Update cheats_patches.cpp
sets all added buttons to the size of the largest button.
and fixes some aesthetic issues.
* move eboot_address to module.h
fixes the non-qt builds and makes more sense to be there anyway
* Patchs menu and fixes
adds the possibility to download Patches, it does not modify the memory yet.
and some other fixes
* MemoryPatcher namespace, activate cheats on start
* format
* initial patch implementation
* format
* format again...
* convertValueToHex
* Fixes
Choosing which cheat file to use.
And some other fixes
* fix bytes16, bytes32, bytes64 type patches
If a patch is any of these types we convert it from little endian to big endian
* format
* format again :(
* Implement pattern scanning for mask type patches
* add check to stop patches applying to wrong game
previously if you added a patch to a game, but closed the window and opened a different game it would still try to apply the patch, this is now fixed
* format
* Fix 'Hint' 0x400000 | and Author
* Management |save checkbox | shadps4 repository
MENU - Cheats/Patches Management (implementing Patches)
save patches checkbox
add shadps4 repository
* Load saved patches, miscellaneous fixes
* Fix an issue with mask patches not being saved
* format + remove debug log
* multiple patches | TR translation for cheats/patches
* clang
* ENABLE_QT_GUI
* OK
* move memory_patcher to qt_gui
* clang
* add cheats hu_HU
* fix log
* Remove the item from the patchesListView if no patches were added (the game has patches, but not for the current version)
---------
Co-authored-by: CrazyBloo <CrazyBloo@users.noreply.github.com>
2024-08-29 04:18:50 +00:00
|
|
|
// Do not show the menu if an item is selected
|
|
|
|
if (itemID == -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-03-29 05:43:46 +00:00
|
|
|
// Setup menu.
|
|
|
|
QMenu menu(widget);
|
2024-11-10 08:14:48 +00:00
|
|
|
|
|
|
|
// "Open Folder..." submenu
|
|
|
|
QMenu* openFolderMenu = new QMenu(tr("Open Folder..."), widget);
|
|
|
|
QAction* openGameFolder = new QAction(tr("Open Game Folder"), widget);
|
|
|
|
QAction* openSaveDataFolder = new QAction(tr("Open Save Data Folder"), widget);
|
|
|
|
QAction* openLogFolder = new QAction(tr("Open Log Folder"), widget);
|
|
|
|
|
|
|
|
openFolderMenu->addAction(openGameFolder);
|
|
|
|
openFolderMenu->addAction(openSaveDataFolder);
|
|
|
|
openFolderMenu->addAction(openLogFolder);
|
|
|
|
|
|
|
|
menu.addMenu(openFolderMenu);
|
|
|
|
|
2024-08-25 08:45:26 +00:00
|
|
|
QAction createShortcut(tr("Create Shortcut"), widget);
|
Cheats/Patches (#493)
* Cheats/Patches
Adds the possibility of applying cheats/patches according to the specific game serial+version
The logic for adding modifications has not yet been implemented!
Interface based on issues/372 https://github.com/shadps4-emu/shadPS4/issues/372
[X]Front-end
[]Back-end
Create a synchronized fork of the cheats/patches repository
* Clang Format
* separate files
The code has been separated into separate files as suggested by georgemoralis.
Added the Patch tab, which has not been implemented yet.
Added the 'applyCheat' area to apply the modification, not implemented yet...
And added LOG_INFO.
* reuse
* initial implementation of cheat functionality
* Update cheats_patches.cpp
sets all added buttons to the size of the largest button.
and fixes some aesthetic issues.
* move eboot_address to module.h
fixes the non-qt builds and makes more sense to be there anyway
* Patchs menu and fixes
adds the possibility to download Patches, it does not modify the memory yet.
and some other fixes
* MemoryPatcher namespace, activate cheats on start
* format
* initial patch implementation
* format
* format again...
* convertValueToHex
* Fixes
Choosing which cheat file to use.
And some other fixes
* fix bytes16, bytes32, bytes64 type patches
If a patch is any of these types we convert it from little endian to big endian
* format
* format again :(
* Implement pattern scanning for mask type patches
* add check to stop patches applying to wrong game
previously if you added a patch to a game, but closed the window and opened a different game it would still try to apply the patch, this is now fixed
* format
* Fix 'Hint' 0x400000 | and Author
* Management |save checkbox | shadps4 repository
MENU - Cheats/Patches Management (implementing Patches)
save patches checkbox
add shadps4 repository
* Load saved patches, miscellaneous fixes
* Fix an issue with mask patches not being saved
* format + remove debug log
* multiple patches | TR translation for cheats/patches
* clang
* ENABLE_QT_GUI
* OK
* move memory_patcher to qt_gui
* clang
* add cheats hu_HU
* fix log
* Remove the item from the patchesListView if no patches were added (the game has patches, but not for the current version)
---------
Co-authored-by: CrazyBloo <CrazyBloo@users.noreply.github.com>
2024-08-29 04:18:50 +00:00
|
|
|
QAction openCheats(tr("Cheats / Patches"), widget);
|
2024-08-25 08:45:26 +00:00
|
|
|
QAction openSfoViewer(tr("SFO Viewer"), widget);
|
|
|
|
QAction openTrophyViewer(tr("Trophy Viewer"), widget);
|
2024-03-29 05:43:46 +00:00
|
|
|
|
2024-07-10 16:20:19 +00:00
|
|
|
menu.addAction(&createShortcut);
|
Cheats/Patches (#493)
* Cheats/Patches
Adds the possibility of applying cheats/patches according to the specific game serial+version
The logic for adding modifications has not yet been implemented!
Interface based on issues/372 https://github.com/shadps4-emu/shadPS4/issues/372
[X]Front-end
[]Back-end
Create a synchronized fork of the cheats/patches repository
* Clang Format
* separate files
The code has been separated into separate files as suggested by georgemoralis.
Added the Patch tab, which has not been implemented yet.
Added the 'applyCheat' area to apply the modification, not implemented yet...
And added LOG_INFO.
* reuse
* initial implementation of cheat functionality
* Update cheats_patches.cpp
sets all added buttons to the size of the largest button.
and fixes some aesthetic issues.
* move eboot_address to module.h
fixes the non-qt builds and makes more sense to be there anyway
* Patchs menu and fixes
adds the possibility to download Patches, it does not modify the memory yet.
and some other fixes
* MemoryPatcher namespace, activate cheats on start
* format
* initial patch implementation
* format
* format again...
* convertValueToHex
* Fixes
Choosing which cheat file to use.
And some other fixes
* fix bytes16, bytes32, bytes64 type patches
If a patch is any of these types we convert it from little endian to big endian
* format
* format again :(
* Implement pattern scanning for mask type patches
* add check to stop patches applying to wrong game
previously if you added a patch to a game, but closed the window and opened a different game it would still try to apply the patch, this is now fixed
* format
* Fix 'Hint' 0x400000 | and Author
* Management |save checkbox | shadps4 repository
MENU - Cheats/Patches Management (implementing Patches)
save patches checkbox
add shadps4 repository
* Load saved patches, miscellaneous fixes
* Fix an issue with mask patches not being saved
* format + remove debug log
* multiple patches | TR translation for cheats/patches
* clang
* ENABLE_QT_GUI
* OK
* move memory_patcher to qt_gui
* clang
* add cheats hu_HU
* fix log
* Remove the item from the patchesListView if no patches were added (the game has patches, but not for the current version)
---------
Co-authored-by: CrazyBloo <CrazyBloo@users.noreply.github.com>
2024-08-29 04:18:50 +00:00
|
|
|
menu.addAction(&openCheats);
|
2024-03-29 05:43:46 +00:00
|
|
|
menu.addAction(&openSfoViewer);
|
2024-06-11 02:42:21 +00:00
|
|
|
menu.addAction(&openTrophyViewer);
|
2024-07-05 23:57:54 +00:00
|
|
|
|
2024-08-19 04:25:15 +00:00
|
|
|
// "Copy" submenu.
|
2024-11-10 08:14:48 +00:00
|
|
|
QMenu* copyMenu = new QMenu(tr("Copy info..."), widget);
|
2024-08-25 08:45:26 +00:00
|
|
|
QAction* copyName = new QAction(tr("Copy Name"), widget);
|
|
|
|
QAction* copySerial = new QAction(tr("Copy Serial"), widget);
|
|
|
|
QAction* copyNameAll = new QAction(tr("Copy All"), widget);
|
2024-08-19 04:25:15 +00:00
|
|
|
|
|
|
|
copyMenu->addAction(copyName);
|
|
|
|
copyMenu->addAction(copySerial);
|
|
|
|
copyMenu->addAction(copyNameAll);
|
|
|
|
|
|
|
|
menu.addMenu(copyMenu);
|
|
|
|
|
2024-10-15 15:49:42 +00:00
|
|
|
// "Delete..." submenu.
|
|
|
|
QMenu* deleteMenu = new QMenu(tr("Delete..."), widget);
|
|
|
|
QAction* deleteGame = new QAction(tr("Delete Game"), widget);
|
|
|
|
QAction* deleteUpdate = new QAction(tr("Delete Update"), widget);
|
|
|
|
QAction* deleteDLC = new QAction(tr("Delete DLC"), widget);
|
|
|
|
|
|
|
|
deleteMenu->addAction(deleteGame);
|
|
|
|
deleteMenu->addAction(deleteUpdate);
|
|
|
|
deleteMenu->addAction(deleteDLC);
|
|
|
|
|
|
|
|
menu.addMenu(deleteMenu);
|
|
|
|
|
2024-12-25 07:30:09 +00:00
|
|
|
// Compatibility submenu.
|
|
|
|
QMenu* compatibilityMenu = new QMenu(tr("Compatibility..."), widget);
|
|
|
|
QAction* updateCompatibility = new QAction(tr("Update database"), widget);
|
|
|
|
QAction* viewCompatibilityReport = new QAction(tr("View report"), widget);
|
|
|
|
QAction* submitCompatibilityReport = new QAction(tr("Submit a report"), widget);
|
|
|
|
|
|
|
|
compatibilityMenu->addAction(updateCompatibility);
|
|
|
|
compatibilityMenu->addAction(viewCompatibilityReport);
|
|
|
|
compatibilityMenu->addAction(submitCompatibilityReport);
|
|
|
|
|
|
|
|
menu.addMenu(compatibilityMenu);
|
|
|
|
|
|
|
|
compatibilityMenu->setEnabled(Config::getCompatibilityEnabled());
|
|
|
|
viewCompatibilityReport->setEnabled(!m_games[itemID].compatibility.url.isEmpty());
|
|
|
|
|
2024-03-29 05:43:46 +00:00
|
|
|
// Show menu.
|
|
|
|
auto selected = menu.exec(global_pos);
|
|
|
|
if (!selected) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-11-10 08:14:48 +00:00
|
|
|
if (selected == openGameFolder) {
|
2024-09-26 08:41:59 +00:00
|
|
|
QString folderPath;
|
|
|
|
Common::FS::PathToQString(folderPath, m_games[itemID].path);
|
2024-03-29 05:43:46 +00:00
|
|
|
QDesktopServices::openUrl(QUrl::fromLocalFile(folderPath));
|
|
|
|
}
|
|
|
|
|
2024-11-10 08:14:48 +00:00
|
|
|
if (selected == openSaveDataFolder) {
|
|
|
|
QString userPath;
|
|
|
|
Common::FS::PathToQString(userPath,
|
|
|
|
Common::FS::GetUserPath(Common::FS::PathType::UserDir));
|
|
|
|
QString saveDataPath =
|
|
|
|
userPath + "/savedata/1/" + QString::fromStdString(m_games[itemID].serial);
|
|
|
|
QDir(saveDataPath).mkpath(saveDataPath);
|
|
|
|
QDesktopServices::openUrl(QUrl::fromLocalFile(saveDataPath));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selected == openLogFolder) {
|
|
|
|
QString userPath;
|
|
|
|
Common::FS::PathToQString(userPath,
|
|
|
|
Common::FS::GetUserPath(Common::FS::PathType::UserDir));
|
|
|
|
QDesktopServices::openUrl(QUrl::fromLocalFile(userPath + "/log"));
|
|
|
|
}
|
|
|
|
|
2024-03-29 05:43:46 +00:00
|
|
|
if (selected == &openSfoViewer) {
|
|
|
|
PSF psf;
|
2024-10-15 15:49:42 +00:00
|
|
|
std::filesystem::path game_folder_path = m_games[itemID].path;
|
2024-12-17 10:42:21 +00:00
|
|
|
std::filesystem::path game_update_path = game_folder_path;
|
|
|
|
game_update_path += "UPDATE";
|
|
|
|
if (std::filesystem::exists(game_update_path)) {
|
|
|
|
game_folder_path = game_update_path;
|
2024-10-15 15:49:42 +00:00
|
|
|
}
|
|
|
|
if (psf.Open(game_folder_path / "sce_sys" / "param.sfo")) {
|
2024-09-20 09:34:19 +00:00
|
|
|
int rows = psf.GetEntries().size();
|
2024-03-29 05:43:46 +00:00
|
|
|
QTableWidget* tableWidget = new QTableWidget(rows, 2);
|
2024-06-11 02:42:21 +00:00
|
|
|
tableWidget->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
connect(widget->parent(), &QWidget::destroyed, tableWidget,
|
2024-08-23 19:38:55 +00:00
|
|
|
[tableWidget]() { tableWidget->deleteLater(); });
|
2024-06-11 02:42:21 +00:00
|
|
|
|
2024-03-29 05:43:46 +00:00
|
|
|
tableWidget->verticalHeader()->setVisible(false); // Hide vertical header
|
|
|
|
int row = 0;
|
|
|
|
|
2024-09-20 09:34:19 +00:00
|
|
|
for (const auto& entry : psf.GetEntries()) {
|
2024-03-29 05:43:46 +00:00
|
|
|
QTableWidgetItem* keyItem =
|
2024-09-20 09:34:19 +00:00
|
|
|
new QTableWidgetItem(QString::fromStdString(entry.key));
|
|
|
|
QTableWidgetItem* valueItem;
|
|
|
|
switch (entry.param_fmt) {
|
|
|
|
case PSFEntryFmt::Binary: {
|
2024-09-22 05:16:06 +00:00
|
|
|
const auto bin = psf.GetBinary(entry.key);
|
|
|
|
if (!bin.has_value()) {
|
|
|
|
valueItem = new QTableWidgetItem(QString("Unknown"));
|
|
|
|
} else {
|
|
|
|
std::string text;
|
|
|
|
text.reserve(bin->size() * 2);
|
|
|
|
for (const auto& c : *bin) {
|
|
|
|
static constexpr char hex[] = "0123456789ABCDEF";
|
|
|
|
text.push_back(hex[c >> 4 & 0xF]);
|
|
|
|
text.push_back(hex[c & 0xF]);
|
|
|
|
}
|
|
|
|
valueItem = new QTableWidgetItem(QString::fromStdString(text));
|
2024-09-20 09:34:19 +00:00
|
|
|
}
|
|
|
|
} break;
|
|
|
|
case PSFEntryFmt::Text: {
|
2024-09-22 05:16:06 +00:00
|
|
|
auto text = psf.GetString(entry.key);
|
|
|
|
if (!text.has_value()) {
|
|
|
|
valueItem = new QTableWidgetItem(QString("Unknown"));
|
|
|
|
} else {
|
|
|
|
valueItem =
|
|
|
|
new QTableWidgetItem(QString::fromStdString(std::string{*text}));
|
|
|
|
}
|
2024-09-20 09:34:19 +00:00
|
|
|
} break;
|
|
|
|
case PSFEntryFmt::Integer: {
|
2024-09-22 05:16:06 +00:00
|
|
|
auto integer = psf.GetInteger(entry.key);
|
|
|
|
if (!integer.has_value()) {
|
|
|
|
valueItem = new QTableWidgetItem(QString("Unknown"));
|
|
|
|
} else {
|
|
|
|
valueItem =
|
|
|
|
new QTableWidgetItem(QString("0x") + QString::number(*integer, 16));
|
|
|
|
}
|
2024-09-20 09:34:19 +00:00
|
|
|
} break;
|
|
|
|
}
|
2024-03-29 05:43:46 +00:00
|
|
|
|
|
|
|
tableWidget->setItem(row, 0, keyItem);
|
|
|
|
tableWidget->setItem(row, 1, valueItem);
|
|
|
|
keyItem->setFlags(keyItem->flags() & ~Qt::ItemIsEditable);
|
|
|
|
valueItem->setFlags(valueItem->flags() & ~Qt::ItemIsEditable);
|
|
|
|
row++;
|
|
|
|
}
|
|
|
|
tableWidget->resizeColumnsToContents();
|
|
|
|
tableWidget->resizeRowsToContents();
|
|
|
|
|
|
|
|
int width = tableWidget->horizontalHeader()->sectionSize(0) +
|
|
|
|
tableWidget->horizontalHeader()->sectionSize(1) + 2;
|
|
|
|
int height = (rows + 1) * (tableWidget->rowHeight(0));
|
|
|
|
tableWidget->setFixedSize(width, height);
|
|
|
|
tableWidget->sortItems(0, Qt::AscendingOrder);
|
|
|
|
tableWidget->horizontalHeader()->setVisible(false);
|
|
|
|
|
|
|
|
tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
|
2024-08-25 08:45:26 +00:00
|
|
|
tableWidget->setWindowTitle(tr("SFO Viewer"));
|
2024-03-29 05:43:46 +00:00
|
|
|
tableWidget->show();
|
|
|
|
}
|
|
|
|
}
|
2024-06-11 02:42:21 +00:00
|
|
|
|
Cheats/Patches (#493)
* Cheats/Patches
Adds the possibility of applying cheats/patches according to the specific game serial+version
The logic for adding modifications has not yet been implemented!
Interface based on issues/372 https://github.com/shadps4-emu/shadPS4/issues/372
[X]Front-end
[]Back-end
Create a synchronized fork of the cheats/patches repository
* Clang Format
* separate files
The code has been separated into separate files as suggested by georgemoralis.
Added the Patch tab, which has not been implemented yet.
Added the 'applyCheat' area to apply the modification, not implemented yet...
And added LOG_INFO.
* reuse
* initial implementation of cheat functionality
* Update cheats_patches.cpp
sets all added buttons to the size of the largest button.
and fixes some aesthetic issues.
* move eboot_address to module.h
fixes the non-qt builds and makes more sense to be there anyway
* Patchs menu and fixes
adds the possibility to download Patches, it does not modify the memory yet.
and some other fixes
* MemoryPatcher namespace, activate cheats on start
* format
* initial patch implementation
* format
* format again...
* convertValueToHex
* Fixes
Choosing which cheat file to use.
And some other fixes
* fix bytes16, bytes32, bytes64 type patches
If a patch is any of these types we convert it from little endian to big endian
* format
* format again :(
* Implement pattern scanning for mask type patches
* add check to stop patches applying to wrong game
previously if you added a patch to a game, but closed the window and opened a different game it would still try to apply the patch, this is now fixed
* format
* Fix 'Hint' 0x400000 | and Author
* Management |save checkbox | shadps4 repository
MENU - Cheats/Patches Management (implementing Patches)
save patches checkbox
add shadps4 repository
* Load saved patches, miscellaneous fixes
* Fix an issue with mask patches not being saved
* format + remove debug log
* multiple patches | TR translation for cheats/patches
* clang
* ENABLE_QT_GUI
* OK
* move memory_patcher to qt_gui
* clang
* add cheats hu_HU
* fix log
* Remove the item from the patchesListView if no patches were added (the game has patches, but not for the current version)
---------
Co-authored-by: CrazyBloo <CrazyBloo@users.noreply.github.com>
2024-08-29 04:18:50 +00:00
|
|
|
if (selected == &openCheats) {
|
|
|
|
QString gameName = QString::fromStdString(m_games[itemID].name);
|
|
|
|
QString gameSerial = QString::fromStdString(m_games[itemID].serial);
|
|
|
|
QString gameVersion = QString::fromStdString(m_games[itemID].version);
|
|
|
|
QString gameSize = QString::fromStdString(m_games[itemID].size);
|
2024-09-26 08:41:59 +00:00
|
|
|
QString iconPath;
|
|
|
|
Common::FS::PathToQString(iconPath, m_games[itemID].icon_path);
|
|
|
|
QPixmap gameImage(iconPath);
|
Cheats/Patches (#493)
* Cheats/Patches
Adds the possibility of applying cheats/patches according to the specific game serial+version
The logic for adding modifications has not yet been implemented!
Interface based on issues/372 https://github.com/shadps4-emu/shadPS4/issues/372
[X]Front-end
[]Back-end
Create a synchronized fork of the cheats/patches repository
* Clang Format
* separate files
The code has been separated into separate files as suggested by georgemoralis.
Added the Patch tab, which has not been implemented yet.
Added the 'applyCheat' area to apply the modification, not implemented yet...
And added LOG_INFO.
* reuse
* initial implementation of cheat functionality
* Update cheats_patches.cpp
sets all added buttons to the size of the largest button.
and fixes some aesthetic issues.
* move eboot_address to module.h
fixes the non-qt builds and makes more sense to be there anyway
* Patchs menu and fixes
adds the possibility to download Patches, it does not modify the memory yet.
and some other fixes
* MemoryPatcher namespace, activate cheats on start
* format
* initial patch implementation
* format
* format again...
* convertValueToHex
* Fixes
Choosing which cheat file to use.
And some other fixes
* fix bytes16, bytes32, bytes64 type patches
If a patch is any of these types we convert it from little endian to big endian
* format
* format again :(
* Implement pattern scanning for mask type patches
* add check to stop patches applying to wrong game
previously if you added a patch to a game, but closed the window and opened a different game it would still try to apply the patch, this is now fixed
* format
* Fix 'Hint' 0x400000 | and Author
* Management |save checkbox | shadps4 repository
MENU - Cheats/Patches Management (implementing Patches)
save patches checkbox
add shadps4 repository
* Load saved patches, miscellaneous fixes
* Fix an issue with mask patches not being saved
* format + remove debug log
* multiple patches | TR translation for cheats/patches
* clang
* ENABLE_QT_GUI
* OK
* move memory_patcher to qt_gui
* clang
* add cheats hu_HU
* fix log
* Remove the item from the patchesListView if no patches were added (the game has patches, but not for the current version)
---------
Co-authored-by: CrazyBloo <CrazyBloo@users.noreply.github.com>
2024-08-29 04:18:50 +00:00
|
|
|
CheatsPatches* cheatsPatches =
|
|
|
|
new CheatsPatches(gameName, gameSerial, gameVersion, gameSize, gameImage);
|
|
|
|
cheatsPatches->show();
|
|
|
|
connect(widget->parent(), &QWidget::destroyed, cheatsPatches,
|
2024-08-30 13:48:21 +00:00
|
|
|
[cheatsPatches]() { cheatsPatches->deleteLater(); });
|
Cheats/Patches (#493)
* Cheats/Patches
Adds the possibility of applying cheats/patches according to the specific game serial+version
The logic for adding modifications has not yet been implemented!
Interface based on issues/372 https://github.com/shadps4-emu/shadPS4/issues/372
[X]Front-end
[]Back-end
Create a synchronized fork of the cheats/patches repository
* Clang Format
* separate files
The code has been separated into separate files as suggested by georgemoralis.
Added the Patch tab, which has not been implemented yet.
Added the 'applyCheat' area to apply the modification, not implemented yet...
And added LOG_INFO.
* reuse
* initial implementation of cheat functionality
* Update cheats_patches.cpp
sets all added buttons to the size of the largest button.
and fixes some aesthetic issues.
* move eboot_address to module.h
fixes the non-qt builds and makes more sense to be there anyway
* Patchs menu and fixes
adds the possibility to download Patches, it does not modify the memory yet.
and some other fixes
* MemoryPatcher namespace, activate cheats on start
* format
* initial patch implementation
* format
* format again...
* convertValueToHex
* Fixes
Choosing which cheat file to use.
And some other fixes
* fix bytes16, bytes32, bytes64 type patches
If a patch is any of these types we convert it from little endian to big endian
* format
* format again :(
* Implement pattern scanning for mask type patches
* add check to stop patches applying to wrong game
previously if you added a patch to a game, but closed the window and opened a different game it would still try to apply the patch, this is now fixed
* format
* Fix 'Hint' 0x400000 | and Author
* Management |save checkbox | shadps4 repository
MENU - Cheats/Patches Management (implementing Patches)
save patches checkbox
add shadps4 repository
* Load saved patches, miscellaneous fixes
* Fix an issue with mask patches not being saved
* format + remove debug log
* multiple patches | TR translation for cheats/patches
* clang
* ENABLE_QT_GUI
* OK
* move memory_patcher to qt_gui
* clang
* add cheats hu_HU
* fix log
* Remove the item from the patchesListView if no patches were added (the game has patches, but not for the current version)
---------
Co-authored-by: CrazyBloo <CrazyBloo@users.noreply.github.com>
2024-08-29 04:18:50 +00:00
|
|
|
}
|
|
|
|
|
2024-06-11 02:42:21 +00:00
|
|
|
if (selected == &openTrophyViewer) {
|
2024-09-26 08:41:59 +00:00
|
|
|
QString trophyPath, gameTrpPath;
|
|
|
|
Common::FS::PathToQString(trophyPath, m_games[itemID].serial);
|
|
|
|
Common::FS::PathToQString(gameTrpPath, m_games[itemID].path);
|
2024-06-11 02:42:21 +00:00
|
|
|
TrophyViewer* trophyViewer = new TrophyViewer(trophyPath, gameTrpPath);
|
|
|
|
trophyViewer->show();
|
|
|
|
connect(widget->parent(), &QWidget::destroyed, trophyViewer,
|
2024-08-23 19:38:55 +00:00
|
|
|
[trophyViewer]() { trophyViewer->deleteLater(); });
|
2024-06-11 02:42:21 +00:00
|
|
|
}
|
2024-07-05 23:57:54 +00:00
|
|
|
|
|
|
|
if (selected == &createShortcut) {
|
2024-09-26 08:41:59 +00:00
|
|
|
QString targetPath;
|
|
|
|
Common::FS::PathToQString(targetPath, m_games[itemID].path);
|
2024-07-05 23:57:54 +00:00
|
|
|
QString ebootPath = targetPath + "/eboot.bin";
|
|
|
|
|
|
|
|
// Get the full path to the icon
|
2024-09-26 08:41:59 +00:00
|
|
|
QString iconPath;
|
|
|
|
Common::FS::PathToQString(iconPath, m_games[itemID].icon_path);
|
2024-07-05 23:57:54 +00:00
|
|
|
QFileInfo iconFileInfo(iconPath);
|
|
|
|
QString icoPath = iconFileInfo.absolutePath() + "/" + iconFileInfo.baseName() + ".ico";
|
|
|
|
|
|
|
|
// Path to shortcut/link
|
|
|
|
QString linkPath;
|
|
|
|
|
|
|
|
// Path to the shadps4.exe executable
|
|
|
|
QString exePath;
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
linkPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/" +
|
2024-07-09 03:55:48 +00:00
|
|
|
QString::fromStdString(m_games[itemID].name)
|
|
|
|
.remove(QRegularExpression("[\\\\/:*?\"<>|]")) +
|
|
|
|
".lnk";
|
2024-07-05 23:57:54 +00:00
|
|
|
|
|
|
|
exePath = QCoreApplication::applicationFilePath().replace("\\", "/");
|
|
|
|
|
|
|
|
#else
|
|
|
|
linkPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/" +
|
2024-07-09 03:55:48 +00:00
|
|
|
QString::fromStdString(m_games[itemID].name)
|
|
|
|
.remove(QRegularExpression("[\\\\/:*?\"<>|]")) +
|
|
|
|
".desktop";
|
2024-07-05 23:57:54 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// Convert the icon to .ico if necessary
|
|
|
|
if (iconFileInfo.suffix().toLower() == "png") {
|
|
|
|
// Convert icon from PNG to ICO
|
|
|
|
if (convertPngToIco(iconPath, icoPath)) {
|
|
|
|
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
if (createShortcutWin(linkPath, ebootPath, icoPath, exePath)) {
|
|
|
|
#else
|
|
|
|
if (createShortcutLinux(linkPath, ebootPath, iconPath)) {
|
|
|
|
#endif
|
|
|
|
QMessageBox::information(
|
2024-08-25 08:45:26 +00:00
|
|
|
nullptr, tr("Shortcut creation"),
|
2024-12-27 11:54:31 +00:00
|
|
|
QString(tr("Shortcut created successfully!") + "\n%1").arg(linkPath));
|
2024-07-05 23:57:54 +00:00
|
|
|
} else {
|
|
|
|
QMessageBox::critical(
|
2024-08-25 08:45:26 +00:00
|
|
|
nullptr, tr("Error"),
|
2024-12-27 11:54:31 +00:00
|
|
|
QString(tr("Error creating shortcut!") + "\n%1").arg(linkPath));
|
2024-07-05 23:57:54 +00:00
|
|
|
}
|
|
|
|
} else {
|
2024-08-25 08:45:26 +00:00
|
|
|
QMessageBox::critical(nullptr, tr("Error"), tr("Failed to convert icon."));
|
2024-07-05 23:57:54 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// If the icon is already in ICO format, we just create the shortcut
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
if (createShortcutWin(linkPath, ebootPath, iconPath, exePath)) {
|
|
|
|
#else
|
|
|
|
if (createShortcutLinux(linkPath, ebootPath, iconPath)) {
|
|
|
|
#endif
|
|
|
|
QMessageBox::information(
|
2024-08-25 08:45:26 +00:00
|
|
|
nullptr, tr("Shortcut creation"),
|
2024-12-27 11:54:31 +00:00
|
|
|
QString(tr("Shortcut created successfully!") + "\n%1").arg(linkPath));
|
2024-07-05 23:57:54 +00:00
|
|
|
} else {
|
2024-08-25 08:45:26 +00:00
|
|
|
QMessageBox::critical(
|
|
|
|
nullptr, tr("Error"),
|
2024-12-27 11:54:31 +00:00
|
|
|
QString(tr("Error creating shortcut!") + "\n%1").arg(linkPath));
|
2024-07-05 23:57:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-08-19 04:25:15 +00:00
|
|
|
|
|
|
|
// Handle the "Copy" actions
|
|
|
|
if (selected == copyName) {
|
|
|
|
QClipboard* clipboard = QGuiApplication::clipboard();
|
|
|
|
clipboard->setText(QString::fromStdString(m_games[itemID].name));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selected == copySerial) {
|
|
|
|
QClipboard* clipboard = QGuiApplication::clipboard();
|
|
|
|
clipboard->setText(QString::fromStdString(m_games[itemID].serial));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selected == copyNameAll) {
|
|
|
|
QClipboard* clipboard = QGuiApplication::clipboard();
|
|
|
|
QString combinedText = QString("Name:%1 | Serial:%2 | Version:%3 | Size:%4")
|
|
|
|
.arg(QString::fromStdString(m_games[itemID].name))
|
|
|
|
.arg(QString::fromStdString(m_games[itemID].serial))
|
|
|
|
.arg(QString::fromStdString(m_games[itemID].version))
|
|
|
|
.arg(QString::fromStdString(m_games[itemID].size));
|
|
|
|
clipboard->setText(combinedText);
|
|
|
|
}
|
2024-10-15 15:49:42 +00:00
|
|
|
|
|
|
|
if (selected == deleteGame || selected == deleteUpdate || selected == deleteDLC) {
|
|
|
|
bool error = false;
|
2024-10-15 19:29:27 +00:00
|
|
|
QString folder_path, game_update_path, dlc_path;
|
2024-10-15 15:49:42 +00:00
|
|
|
Common::FS::PathToQString(folder_path, m_games[itemID].path);
|
2024-12-17 10:42:21 +00:00
|
|
|
game_update_path = folder_path + "-UPDATE";
|
2024-10-15 19:29:27 +00:00
|
|
|
Common::FS::PathToQString(
|
|
|
|
dlc_path, Config::getAddonInstallDir() /
|
|
|
|
Common::FS::PathFromQString(folder_path).parent_path().filename());
|
2024-10-15 15:49:42 +00:00
|
|
|
QString message_type = tr("Game");
|
2024-10-15 19:29:27 +00:00
|
|
|
|
2024-10-15 15:49:42 +00:00
|
|
|
if (selected == deleteUpdate) {
|
2024-12-17 10:42:21 +00:00
|
|
|
if (!std::filesystem::exists(Common::FS::PathFromQString(game_update_path))) {
|
2024-12-28 10:49:44 +00:00
|
|
|
QMessageBox::critical(nullptr, tr("Error"),
|
|
|
|
QString(tr("This game has no update to delete!")));
|
2024-10-15 15:49:42 +00:00
|
|
|
error = true;
|
|
|
|
} else {
|
|
|
|
folder_path = game_update_path;
|
|
|
|
message_type = tr("Update");
|
|
|
|
}
|
|
|
|
} else if (selected == deleteDLC) {
|
2024-10-15 19:29:27 +00:00
|
|
|
if (!std::filesystem::exists(Common::FS::PathFromQString(dlc_path))) {
|
2024-10-15 15:49:42 +00:00
|
|
|
QMessageBox::critical(nullptr, tr("Error"),
|
|
|
|
QString(tr("This game has no DLC to delete!")));
|
|
|
|
error = true;
|
|
|
|
} else {
|
2024-10-15 19:29:27 +00:00
|
|
|
folder_path = dlc_path;
|
2024-10-15 15:49:42 +00:00
|
|
|
message_type = tr("DLC");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!error) {
|
|
|
|
QString gameName = QString::fromStdString(m_games[itemID].name);
|
|
|
|
QDir dir(folder_path);
|
|
|
|
QMessageBox::StandardButton reply = QMessageBox::question(
|
|
|
|
nullptr, QString(tr("Delete %1")).arg(message_type),
|
|
|
|
QString(tr("Are you sure you want to delete %1's %2 directory?"))
|
|
|
|
.arg(gameName, message_type),
|
|
|
|
QMessageBox::Yes | QMessageBox::No);
|
|
|
|
if (reply == QMessageBox::Yes) {
|
|
|
|
dir.removeRecursively();
|
2024-12-10 13:40:54 +00:00
|
|
|
widget->removeRow(itemID);
|
2024-10-15 15:49:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-12-25 07:30:09 +00:00
|
|
|
|
|
|
|
if (selected == updateCompatibility) {
|
|
|
|
m_compat_info->UpdateCompatibilityDatabase(widget, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selected == viewCompatibilityReport) {
|
|
|
|
if (!m_games[itemID].compatibility.url.isEmpty())
|
|
|
|
QDesktopServices::openUrl(QUrl(m_games[itemID].compatibility.url));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selected == submitCompatibilityReport) {
|
|
|
|
QUrl url = QUrl("https://github.com/shadps4-emu/shadps4-game-compatibility/issues/new");
|
|
|
|
QUrlQuery query;
|
|
|
|
query.addQueryItem("template", QString("game_compatibility.yml"));
|
|
|
|
query.addQueryItem(
|
|
|
|
"title", QString("%1 - %2").arg(QString::fromStdString(m_games[itemID].serial),
|
|
|
|
QString::fromStdString(m_games[itemID].name)));
|
|
|
|
query.addQueryItem("game-name", QString::fromStdString(m_games[itemID].name));
|
|
|
|
query.addQueryItem("game-code", QString::fromStdString(m_games[itemID].serial));
|
|
|
|
query.addQueryItem("game-version", QString::fromStdString(m_games[itemID].version));
|
|
|
|
query.addQueryItem("emulator-version", QString(Common::VERSION));
|
|
|
|
url.setQuery(query);
|
|
|
|
|
|
|
|
QDesktopServices::openUrl(url);
|
|
|
|
}
|
2024-03-29 05:43:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int GetRowIndex(QTreeWidget* treeWidget, QTreeWidgetItem* item) {
|
|
|
|
int row = 0;
|
|
|
|
for (int i = 0; i < treeWidget->topLevelItemCount(); i++) { // check top level/parent items
|
|
|
|
QTreeWidgetItem* currentItem = treeWidget->topLevelItem(i);
|
|
|
|
if (currentItem == item) {
|
|
|
|
return row;
|
|
|
|
}
|
|
|
|
row++;
|
|
|
|
|
|
|
|
if (currentItem->childCount() > 0) { // check child items
|
|
|
|
for (int j = 0; j < currentItem->childCount(); j++) {
|
|
|
|
QTreeWidgetItem* childItem = currentItem->child(j);
|
|
|
|
if (childItem == item) {
|
|
|
|
return row;
|
|
|
|
}
|
|
|
|
row++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2024-06-11 02:42:21 +00:00
|
|
|
void RequestGameMenuPKGViewer(
|
|
|
|
const QPoint& pos, QStringList m_pkg_app_list, QTreeWidget* treeWidget,
|
|
|
|
std::function<void(std::filesystem::path, int, int)> InstallDragDropPkg) {
|
2024-03-29 05:43:46 +00:00
|
|
|
QPoint global_pos = treeWidget->viewport()->mapToGlobal(pos); // context menu position
|
|
|
|
QTreeWidgetItem* currentItem = treeWidget->currentItem(); // current clicked item
|
|
|
|
int itemIndex = GetRowIndex(treeWidget, currentItem); // row
|
|
|
|
|
|
|
|
QMenu menu(treeWidget);
|
2024-08-25 08:45:26 +00:00
|
|
|
QAction installPackage(tr("Install PKG"), treeWidget);
|
2024-03-29 05:43:46 +00:00
|
|
|
|
|
|
|
menu.addAction(&installPackage);
|
|
|
|
|
|
|
|
auto selected = menu.exec(global_pos);
|
|
|
|
if (!selected) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selected == &installPackage) {
|
2024-03-30 06:03:15 +00:00
|
|
|
QStringList pkg_app_ = m_pkg_app_list[itemIndex].split(";;");
|
2024-09-30 09:42:59 +00:00
|
|
|
std::filesystem::path path = Common::FS::PathFromQString(pkg_app_[9]);
|
2024-06-11 02:42:21 +00:00
|
|
|
InstallDragDropPkg(path, 1, 1);
|
2024-03-29 05:43:46 +00:00
|
|
|
}
|
|
|
|
}
|
2024-07-05 23:57:54 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
bool convertPngToIco(const QString& pngFilePath, const QString& icoFilePath) {
|
|
|
|
// Load the PNG image
|
|
|
|
QImage image(pngFilePath);
|
|
|
|
if (image.isNull()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Scale the image to the default icon size (256x256 pixels)
|
|
|
|
QImage scaledImage =
|
|
|
|
image.scaled(QSize(256, 256), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
|
|
|
|
|
|
// Convert the image to QPixmap
|
|
|
|
QPixmap pixmap = QPixmap::fromImage(scaledImage);
|
|
|
|
|
|
|
|
// Save the pixmap as an ICO file
|
|
|
|
if (pixmap.save(icoFilePath, "ICO")) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
bool createShortcutWin(const QString& linkPath, const QString& targetPath,
|
|
|
|
const QString& iconPath, const QString& exePath) {
|
|
|
|
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
|
|
|
|
|
|
|
|
// Create the ShellLink object
|
2024-09-25 15:39:04 +00:00
|
|
|
Microsoft::WRL::ComPtr<IShellLink> pShellLink;
|
2024-07-05 23:57:54 +00:00
|
|
|
HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER,
|
2024-09-25 15:39:04 +00:00
|
|
|
IID_PPV_ARGS(&pShellLink));
|
2024-07-05 23:57:54 +00:00
|
|
|
if (SUCCEEDED(hres)) {
|
|
|
|
// Defines the path to the program executable
|
|
|
|
pShellLink->SetPath((LPCWSTR)exePath.utf16());
|
|
|
|
|
|
|
|
// Sets the home directory ("Start in")
|
|
|
|
pShellLink->SetWorkingDirectory((LPCWSTR)QFileInfo(exePath).absolutePath().utf16());
|
|
|
|
|
|
|
|
// Set arguments, eboot.bin file location
|
2024-11-25 12:26:56 +00:00
|
|
|
QString arguments = QString("-g \"%1\"").arg(targetPath);
|
2024-07-05 23:57:54 +00:00
|
|
|
pShellLink->SetArguments((LPCWSTR)arguments.utf16());
|
|
|
|
|
|
|
|
// Set the icon for the shortcut
|
|
|
|
pShellLink->SetIconLocation((LPCWSTR)iconPath.utf16(), 0);
|
|
|
|
|
|
|
|
// Save the shortcut
|
2024-09-25 15:39:04 +00:00
|
|
|
Microsoft::WRL::ComPtr<IPersistFile> pPersistFile;
|
|
|
|
hres = pShellLink.As(&pPersistFile);
|
2024-07-05 23:57:54 +00:00
|
|
|
if (SUCCEEDED(hres)) {
|
|
|
|
hres = pPersistFile->Save((LPCWSTR)linkPath.utf16(), TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CoUninitialize();
|
|
|
|
|
|
|
|
return SUCCEEDED(hres);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
bool createShortcutLinux(const QString& linkPath, const QString& targetPath,
|
|
|
|
const QString& iconPath) {
|
|
|
|
QFile shortcutFile(linkPath);
|
|
|
|
if (!shortcutFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
|
|
|
QMessageBox::critical(nullptr, "Error",
|
2024-08-04 13:07:10 +00:00
|
|
|
QString("Error creating shortcut!\n %1").arg(linkPath));
|
2024-07-05 23:57:54 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
QTextStream out(&shortcutFile);
|
|
|
|
out << "[Desktop Entry]\n";
|
|
|
|
out << "Version=1.0\n";
|
2024-07-06 18:10:28 +00:00
|
|
|
out << "Name=" << QFileInfo(linkPath).baseName() << "\n";
|
2024-07-06 16:40:26 +00:00
|
|
|
out << "Exec=" << QCoreApplication::applicationFilePath() << " \"" << targetPath << "\"\n";
|
2024-07-06 16:42:53 +00:00
|
|
|
out << "Icon=" << iconPath << "\n";
|
2024-07-05 23:57:54 +00:00
|
|
|
out << "Terminal=false\n";
|
|
|
|
out << "Type=Application\n";
|
|
|
|
shortcutFile.close();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
2024-03-29 05:43:46 +00:00
|
|
|
};
|