early-access version 1343
This commit is contained in:
parent
fc2ebf72a3
commit
fad803f1c0
8 changed files with 99 additions and 35 deletions
|
@ -1,7 +1,7 @@
|
|||
yuzu emulator early access
|
||||
=============
|
||||
|
||||
This is the source code for early-access 1342.
|
||||
This is the source code for early-access 1343.
|
||||
|
||||
## Legal Notice
|
||||
|
||||
|
|
|
@ -32,9 +32,15 @@
|
|||
|
||||
namespace Service::Account {
|
||||
|
||||
constexpr ResultCode ERR_INVALID_BUFFER_SIZE{ErrorModule::Account, 30};
|
||||
constexpr ResultCode ERR_INVALID_USER_ID{ErrorModule::Account, 20};
|
||||
constexpr ResultCode ERR_INVALID_APPLICATION_ID{ErrorModule::Account, 22};
|
||||
constexpr ResultCode ERR_INVALID_BUFFER{ErrorModule::Account, 30};
|
||||
constexpr ResultCode ERR_INVALID_BUFFER_SIZE{ErrorModule::Account, 31};
|
||||
constexpr ResultCode ERR_FAILED_SAVE_DATA{ErrorModule::Account, 100};
|
||||
|
||||
// Thumbnails are hard coded to be at least this size
|
||||
constexpr std::size_t THUMBNAIL_SIZE = 0x24000;
|
||||
|
||||
static std::string GetImagePath(Common::UUID uuid) {
|
||||
return Common::FS::GetUserPath(Common::FS::UserPath::NANDDir) +
|
||||
"/system/save/8000000000000010/su/avators/" + uuid.FormatSwitch() + ".jpg";
|
||||
|
@ -369,7 +375,7 @@ protected:
|
|||
if (user_data.size() < sizeof(ProfileData)) {
|
||||
LOG_ERROR(Service_ACC, "ProfileData buffer too small!");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERR_INVALID_BUFFER_SIZE);
|
||||
rb.Push(ERR_INVALID_BUFFER);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -402,7 +408,7 @@ protected:
|
|||
if (user_data.size() < sizeof(ProfileData)) {
|
||||
LOG_ERROR(Service_ACC, "ProfileData buffer too small!");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERR_INVALID_BUFFER_SIZE);
|
||||
rb.Push(ERR_INVALID_BUFFER);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -811,6 +817,55 @@ void Module::Interface::ListOpenContextStoredUsers(Kernel::HLERequestContext& ct
|
|||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Module::Interface::StoreSaveDataThumbnailApplication(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto uuid = rp.PopRaw<Common::UUID>();
|
||||
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called, uuid={}", uuid.Format());
|
||||
|
||||
// TODO(ogniK): Check if application ID is zero on acc initialize. As we don't have a reliable
|
||||
// way of confirming things like the TID, we're going to assume a non zero value for the time
|
||||
// being.
|
||||
constexpr u64 tid{1};
|
||||
StoreSaveDataThumbnail(ctx, uuid, tid);
|
||||
}
|
||||
|
||||
void Module::Interface::StoreSaveDataThumbnailSystem(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto uuid = rp.PopRaw<Common::UUID>();
|
||||
const auto tid = rp.Pop<u64_le>();
|
||||
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called, uuid={}, tid={:016X}", uuid.Format(), tid);
|
||||
StoreSaveDataThumbnail(ctx, uuid, tid);
|
||||
}
|
||||
|
||||
void Module::Interface::StoreSaveDataThumbnail(Kernel::HLERequestContext& ctx,
|
||||
const Common::UUID& uuid, const u64 tid) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
|
||||
if (tid == 0) {
|
||||
LOG_ERROR(Service_ACC, "TitleID is not valid!");
|
||||
rb.Push(ERR_INVALID_APPLICATION_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!uuid) {
|
||||
LOG_ERROR(Service_ACC, "User ID is not valid!");
|
||||
rb.Push(ERR_INVALID_USER_ID);
|
||||
return;
|
||||
}
|
||||
const auto thumbnail_size = ctx.GetReadBufferSize();
|
||||
if (thumbnail_size != THUMBNAIL_SIZE) {
|
||||
LOG_ERROR(Service_ACC, "Buffer size is empty! size={:X} expecting {:X}", thumbnail_size,
|
||||
THUMBNAIL_SIZE);
|
||||
rb.Push(ERR_INVALID_BUFFER_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(ogniK): Construct save data thumbnail
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
// A u8 is passed into this function which we can safely ignore. It's to determine if we have
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "common/uuid.h"
|
||||
#include "core/hle/service/glue/manager.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
|
@ -36,9 +37,13 @@ public:
|
|||
void ListQualifiedUsers(Kernel::HLERequestContext& ctx);
|
||||
void LoadOpenContext(Kernel::HLERequestContext& ctx);
|
||||
void ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx);
|
||||
void StoreSaveDataThumbnailApplication(Kernel::HLERequestContext& ctx);
|
||||
void StoreSaveDataThumbnailSystem(Kernel::HLERequestContext& ctx);
|
||||
|
||||
private:
|
||||
ResultCode InitializeApplicationInfoBase();
|
||||
void StoreSaveDataThumbnail(Kernel::HLERequestContext& ctx, const Common::UUID& uuid,
|
||||
const u64 tid);
|
||||
|
||||
enum class ApplicationType : u32_le {
|
||||
GameCard = 0,
|
||||
|
|
|
@ -29,7 +29,7 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
|
|||
{104, nullptr, "GetProfileUpdateNotifier"},
|
||||
{105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, // 4.0.0+
|
||||
{106, nullptr, "GetProfileSyncNotifier"}, // 9.0.0+
|
||||
{110, nullptr, "StoreSaveDataThumbnail"},
|
||||
{110, &ACC_SU::StoreSaveDataThumbnailSystem, "StoreSaveDataThumbnail"},
|
||||
{111, nullptr, "ClearSaveDataThumbnail"},
|
||||
{112, nullptr, "LoadSaveDataThumbnail"},
|
||||
{113, nullptr, "GetSaveDataThumbnailExistence"}, // 5.0.0+
|
||||
|
|
|
@ -26,7 +26,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
|
|||
{101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"},
|
||||
{102, nullptr, "AuthenticateApplicationAsync"},
|
||||
{103, nullptr, "CheckNetworkServiceAvailabilityAsync"}, // 4.0.0+
|
||||
{110, nullptr, "StoreSaveDataThumbnail"},
|
||||
{110, &ACC_U0::StoreSaveDataThumbnailApplication, "StoreSaveDataThumbnail"},
|
||||
{111, nullptr, "ClearSaveDataThumbnail"},
|
||||
{120, nullptr, "CreateGuestLoginRequest"},
|
||||
{130, &ACC_U0::LoadOpenContext, "LoadOpenContext"}, // 5.0.0+
|
||||
|
|
|
@ -29,7 +29,7 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
|
|||
{104, nullptr, "GetProfileUpdateNotifier"},
|
||||
{105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, // 4.0.0+
|
||||
{106, nullptr, "GetProfileSyncNotifier"}, // 9.0.0+
|
||||
{110, nullptr, "StoreSaveDataThumbnail"},
|
||||
{110, &ACC_U1::StoreSaveDataThumbnailApplication, "StoreSaveDataThumbnail"},
|
||||
{111, nullptr, "ClearSaveDataThumbnail"},
|
||||
{112, nullptr, "LoadSaveDataThumbnail"},
|
||||
{113, nullptr, "GetSaveDataThumbnailExistence"}, // 5.0.0+
|
||||
|
|
|
@ -173,8 +173,8 @@ void GameList::OnItemExpanded(const QModelIndex& item) {
|
|||
return;
|
||||
}
|
||||
|
||||
auto* game_dir = item.data(GameListDir::GameDirRole).value<UISettings::GameDir*>();
|
||||
game_dir->expanded = tree_view->isExpanded(item);
|
||||
UISettings::values.game_dirs[item.data(GameListDir::GameDirRole).toInt()].expanded =
|
||||
tree_view->isExpanded(item);
|
||||
}
|
||||
|
||||
// Event in order to filter the gamelist after editing the searchfield
|
||||
|
@ -262,9 +262,9 @@ void GameList::OnUpdateThemedIcons() {
|
|||
Qt::DecorationRole);
|
||||
break;
|
||||
case GameListItemType::CustomDir: {
|
||||
const UISettings::GameDir* game_dir =
|
||||
child->data(GameListDir::GameDirRole).value<UISettings::GameDir*>();
|
||||
const QString icon_name = QFileInfo::exists(game_dir->path)
|
||||
const UISettings::GameDir& game_dir =
|
||||
UISettings::values.game_dirs[child->data(GameListDir::GameDirRole).toInt()];
|
||||
const QString icon_name = QFileInfo::exists(game_dir.path)
|
||||
? QStringLiteral("folder")
|
||||
: QStringLiteral("bad_folder");
|
||||
child->setData(
|
||||
|
@ -366,7 +366,7 @@ void GameList::AddDirEntry(GameListDir* entry_items) {
|
|||
item_model->invisibleRootItem()->appendRow(entry_items);
|
||||
tree_view->setExpanded(
|
||||
entry_items->index(),
|
||||
entry_items->data(GameListDir::GameDirRole).value<UISettings::GameDir*>()->expanded);
|
||||
UISettings::values.game_dirs[entry_items->data(GameListDir::GameDirRole).toInt()].expanded);
|
||||
}
|
||||
|
||||
void GameList::AddEntry(const QList<QStandardItem*>& entry_items, GameListDir* parent) {
|
||||
|
@ -549,7 +549,7 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
|
|||
|
||||
void GameList::AddCustomDirPopup(QMenu& context_menu, QModelIndex selected) {
|
||||
UISettings::GameDir& game_dir =
|
||||
*selected.data(GameListDir::GameDirRole).value<UISettings::GameDir*>();
|
||||
UISettings::values.game_dirs[selected.data(GameListDir::GameDirRole).toInt()];
|
||||
|
||||
QAction* deep_scan = context_menu.addAction(tr("Scan Subfolders"));
|
||||
QAction* delete_dir = context_menu.addAction(tr("Remove Game Directory"));
|
||||
|
@ -568,8 +568,7 @@ void GameList::AddCustomDirPopup(QMenu& context_menu, QModelIndex selected) {
|
|||
}
|
||||
|
||||
void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) {
|
||||
UISettings::GameDir& game_dir =
|
||||
*selected.data(GameListDir::GameDirRole).value<UISettings::GameDir*>();
|
||||
const int game_dir_index = selected.data(GameListDir::GameDirRole).toInt();
|
||||
|
||||
QAction* move_up = context_menu.addAction(tr("\u25B2 Move Up"));
|
||||
QAction* move_down = context_menu.addAction(tr("\u25bc Move Down"));
|
||||
|
@ -580,34 +579,39 @@ void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) {
|
|||
move_up->setEnabled(row > 0);
|
||||
move_down->setEnabled(row < item_model->rowCount() - 2);
|
||||
|
||||
connect(move_up, &QAction::triggered, [this, selected, row, &game_dir] {
|
||||
// find the indices of the items in settings and swap them
|
||||
std::swap(UISettings::values.game_dirs[UISettings::values.game_dirs.indexOf(game_dir)],
|
||||
UISettings::values.game_dirs[UISettings::values.game_dirs.indexOf(
|
||||
*selected.sibling(row - 1, 0)
|
||||
.data(GameListDir::GameDirRole)
|
||||
.value<UISettings::GameDir*>())]);
|
||||
connect(move_up, &QAction::triggered, [this, selected, row, game_dir_index] {
|
||||
const int other_index = selected.sibling(row - 1, 0).data(GameListDir::GameDirRole).toInt();
|
||||
// swap the items in the settings
|
||||
std::swap(UISettings::values.game_dirs[game_dir_index],
|
||||
UISettings::values.game_dirs[other_index]);
|
||||
// swap the indexes held by the QVariants
|
||||
item_model->setData(selected, QVariant(other_index), GameListDir::GameDirRole);
|
||||
item_model->setData(selected.sibling(row - 1, 0), QVariant(game_dir_index),
|
||||
GameListDir::GameDirRole);
|
||||
// move the treeview items
|
||||
QList<QStandardItem*> item = item_model->takeRow(row);
|
||||
item_model->invisibleRootItem()->insertRow(row - 1, item);
|
||||
tree_view->setExpanded(selected, game_dir.expanded);
|
||||
tree_view->setExpanded(selected, UISettings::values.game_dirs[game_dir_index].expanded);
|
||||
});
|
||||
|
||||
connect(move_down, &QAction::triggered, [this, selected, row, &game_dir] {
|
||||
// find the indices of the items in settings and swap them
|
||||
std::swap(UISettings::values.game_dirs[UISettings::values.game_dirs.indexOf(game_dir)],
|
||||
UISettings::values.game_dirs[UISettings::values.game_dirs.indexOf(
|
||||
*selected.sibling(row + 1, 0)
|
||||
.data(GameListDir::GameDirRole)
|
||||
.value<UISettings::GameDir*>())]);
|
||||
connect(move_down, &QAction::triggered, [this, selected, row, game_dir_index] {
|
||||
const int other_index = selected.sibling(row + 1, 0).data(GameListDir::GameDirRole).toInt();
|
||||
// swap the items in the settings
|
||||
std::swap(UISettings::values.game_dirs[game_dir_index],
|
||||
UISettings::values.game_dirs[other_index]);
|
||||
// swap the indexes held by the QVariants
|
||||
item_model->setData(selected, QVariant(other_index), GameListDir::GameDirRole);
|
||||
item_model->setData(selected.sibling(row + 1, 0), QVariant(game_dir_index),
|
||||
GameListDir::GameDirRole);
|
||||
// move the treeview items
|
||||
const QList<QStandardItem*> item = item_model->takeRow(row);
|
||||
item_model->invisibleRootItem()->insertRow(row + 1, item);
|
||||
tree_view->setExpanded(selected, game_dir.expanded);
|
||||
tree_view->setExpanded(selected, UISettings::values.game_dirs[game_dir_index].expanded);
|
||||
});
|
||||
|
||||
connect(open_directory_location, &QAction::triggered,
|
||||
[this, game_dir] { emit OpenDirectory(game_dir.path); });
|
||||
connect(open_directory_location, &QAction::triggered, [this, game_dir_index] {
|
||||
emit OpenDirectory(UISettings::values.game_dirs[game_dir_index].path);
|
||||
});
|
||||
}
|
||||
|
||||
void GameList::LoadCompatibilityList() {
|
||||
|
|
|
@ -230,7 +230,7 @@ public:
|
|||
setData(type(), TypeRole);
|
||||
|
||||
UISettings::GameDir* game_dir = &directory;
|
||||
setData(QVariant::fromValue(game_dir), GameDirRole);
|
||||
setData(QVariant(UISettings::values.game_dirs.indexOf(directory)), GameDirRole);
|
||||
|
||||
const int icon_size = std::min(static_cast<int>(UISettings::values.icon_size), 64);
|
||||
switch (dir_type) {
|
||||
|
|
Loading…
Reference in a new issue