mirror of
https://github.com/xenia-project/xenia.git
synced 2025-12-06 07:12:03 +01:00
[XAM] Fixed specific edge-case when DLCs or Installed Data wouldn't be visible
This was caused by including flag "exclude common" for enumerations without xuid - Added enum XContentFlag
This commit is contained in:
parent
6b055f1f74
commit
9434cc89c9
|
|
@ -22,6 +22,7 @@
|
||||||
#include "xenia/kernel/xenumerator.h"
|
#include "xenia/kernel/xenumerator.h"
|
||||||
#include "xenia/ui/imgui_dialog.h"
|
#include "xenia/ui/imgui_dialog.h"
|
||||||
#include "xenia/ui/imgui_drawer.h"
|
#include "xenia/ui/imgui_drawer.h"
|
||||||
|
#include "xenia/vfs/devices/stfs_xbox.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
DEFINE_int32(
|
DEFINE_int32(
|
||||||
|
|
@ -126,7 +127,6 @@ dword_result_t XamContentResolve_entry(dword_t user_index,
|
||||||
DECLARE_XAM_EXPORT1(XamContentResolve, kContent, kSketchy);
|
DECLARE_XAM_EXPORT1(XamContentResolve, kContent, kSketchy);
|
||||||
|
|
||||||
// https://github.com/MrColdbird/gameservice/blob/master/ContentManager.cpp
|
// https://github.com/MrColdbird/gameservice/blob/master/ContentManager.cpp
|
||||||
// https://github.com/LestaD/SourceEngine2007/blob/master/se2007/engine/xboxsystem.cpp#L499
|
|
||||||
dword_result_t XamContentCreateEnumerator_entry(
|
dword_result_t XamContentCreateEnumerator_entry(
|
||||||
dword_t user_index, dword_t device_id, dword_t content_type,
|
dword_t user_index, dword_t device_id, dword_t content_type,
|
||||||
dword_t content_flags, dword_t items_per_enumerate,
|
dword_t content_flags, dword_t items_per_enumerate,
|
||||||
|
|
@ -168,7 +168,16 @@ dword_result_t XamContentCreateEnumerator_entry(
|
||||||
std::vector<XCONTENT_AGGREGATE_DATA> enumerated_content = {};
|
std::vector<XCONTENT_AGGREGATE_DATA> enumerated_content = {};
|
||||||
|
|
||||||
if (!device_info || device_info->device_id == DummyDeviceId::HDD) {
|
if (!device_info || device_info->device_id == DummyDeviceId::HDD) {
|
||||||
|
std::vector<uint64_t> xuids_to_enumerate = {};
|
||||||
if (xuid) {
|
if (xuid) {
|
||||||
|
xuids_to_enumerate.push_back(xuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!xuid || !(content_flags & vfs::XContentFlag::kExcludeCommon)) {
|
||||||
|
xuids_to_enumerate.push_back(0); // Common content
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& xuid : xuids_to_enumerate) {
|
||||||
auto user_enumerated_data =
|
auto user_enumerated_data =
|
||||||
kernel_state()->content_manager()->ListContent(
|
kernel_state()->content_manager()->ListContent(
|
||||||
static_cast<uint32_t>(DummyDeviceId::HDD), xuid,
|
static_cast<uint32_t>(DummyDeviceId::HDD), xuid,
|
||||||
|
|
@ -180,18 +189,6 @@ dword_result_t XamContentCreateEnumerator_entry(
|
||||||
user_enumerated_data.cend());
|
user_enumerated_data.cend());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(content_flags & 0x00001000)) {
|
|
||||||
auto common_enumerated_data =
|
|
||||||
kernel_state()->content_manager()->ListContent(
|
|
||||||
static_cast<uint32_t>(DummyDeviceId::HDD), 0,
|
|
||||||
kernel_state()->title_id(),
|
|
||||||
static_cast<XContentType>(content_type.value()));
|
|
||||||
|
|
||||||
enumerated_content.insert(enumerated_content.end(),
|
|
||||||
common_enumerated_data.cbegin(),
|
|
||||||
common_enumerated_data.cend());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove duplicates
|
// Remove duplicates
|
||||||
enumerated_content.erase(
|
enumerated_content.erase(
|
||||||
std::unique(enumerated_content.begin(), enumerated_content.end()),
|
std::unique(enumerated_content.begin(), enumerated_content.end()),
|
||||||
|
|
@ -270,39 +267,39 @@ dword_result_t xeXamContentCreate(dword_t user_index, lpstring_t root_name,
|
||||||
X_RESULT result = X_ERROR_INVALID_PARAMETER;
|
X_RESULT result = X_ERROR_INVALID_PARAMETER;
|
||||||
kDispositionState disposition = kDispositionState::Unknown;
|
kDispositionState disposition = kDispositionState::Unknown;
|
||||||
switch (flags & 0xF) {
|
switch (flags & 0xF) {
|
||||||
case 1: // CREATE_NEW
|
case vfs::XContentFlag::kCreateNew:
|
||||||
// Fail if exists.
|
// Fail if exists.
|
||||||
if (content_manager->ContentExists(xuid, content_data)) {
|
if (content_manager->ContentExists(xuid, content_data)) {
|
||||||
result = X_ERROR_ALREADY_EXISTS;
|
result = X_ERROR_ALREADY_EXISTS;
|
||||||
} else {
|
} else {
|
||||||
disposition = kDispositionState::Create;
|
disposition = kDispositionState::Create;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // CREATE_ALWAYS
|
case vfs::XContentFlag::kCreateAlways:
|
||||||
// Overwrite existing, if any.
|
// Overwrite existing, if any.
|
||||||
if (content_manager->ContentExists(xuid, content_data)) {
|
if (content_manager->ContentExists(xuid, content_data)) {
|
||||||
content_manager->DeleteContent(xuid, content_data);
|
content_manager->DeleteContent(xuid, content_data);
|
||||||
}
|
}
|
||||||
disposition = kDispositionState::Create;
|
disposition = kDispositionState::Create;
|
||||||
break;
|
break;
|
||||||
case 3: // OPEN_EXISTING
|
case vfs::XContentFlag::kOpenExisting:
|
||||||
// Open only if exists.
|
// Open only if exists.
|
||||||
if (!content_manager->ContentExists(xuid, content_data)) {
|
if (!content_manager->ContentExists(xuid, content_data)) {
|
||||||
result = X_ERROR_PATH_NOT_FOUND;
|
result = X_ERROR_PATH_NOT_FOUND;
|
||||||
} else {
|
} else {
|
||||||
disposition = kDispositionState::Open;
|
disposition = kDispositionState::Open;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4: // OPEN_ALWAYS
|
case vfs::XContentFlag::kOpenAlways:
|
||||||
// Create if needed.
|
// Create if needed.
|
||||||
if (!content_manager->ContentExists(xuid, content_data)) {
|
if (!content_manager->ContentExists(xuid, content_data)) {
|
||||||
disposition = kDispositionState::Create;
|
disposition = kDispositionState::Create;
|
||||||
} else {
|
} else {
|
||||||
disposition = kDispositionState::Open;
|
disposition = kDispositionState::Open;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5: // TRUNCATE_EXISTING
|
case vfs::XContentFlag::kTruncateExisting:
|
||||||
// Fail if doesn't exist, if does exist delete and recreate.
|
// Fail if doesn't exist, if does exist delete and recreate.
|
||||||
if (!content_manager->ContentExists(xuid, content_data)) {
|
if (!content_manager->ContentExists(xuid, content_data)) {
|
||||||
result = X_ERROR_PATH_NOT_FOUND;
|
result = X_ERROR_PATH_NOT_FOUND;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,29 @@ enum class XContentVolumeType : uint32_t {
|
||||||
kSvod = 1,
|
kSvod = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum XContentFlag : uint32_t {
|
||||||
|
// Creation flags
|
||||||
|
kCreateNew = 1,
|
||||||
|
kCreateAlways = 2,
|
||||||
|
kOpenExisting = 3,
|
||||||
|
kOpenAlways = 4,
|
||||||
|
kTruncateExisting = 5,
|
||||||
|
|
||||||
|
// Attirbutes
|
||||||
|
kNoProfileTransfer = 0x10,
|
||||||
|
kNoDeviceTransfer = 0x20,
|
||||||
|
kStronglySigned = 0x40,
|
||||||
|
kAllowProfileTransfer = 0x80,
|
||||||
|
kMoveOnly = 0x800,
|
||||||
|
|
||||||
|
// Device selector?
|
||||||
|
kManageStorage = 0x100,
|
||||||
|
kForceUI = 0x200,
|
||||||
|
|
||||||
|
// Enumeration
|
||||||
|
kExcludeCommon = 0x1000
|
||||||
|
};
|
||||||
|
|
||||||
/* STFS structures */
|
/* STFS structures */
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct StfsVolumeDescriptor {
|
struct StfsVolumeDescriptor {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue