mirror of
https://github.com/izzy2lost/xenia-edge.git
synced 2026-07-06 00:20:26 -07:00
Merge remote-tracking branch 'upstream/canary_experimental' into edge
This commit is contained in:
@@ -1790,13 +1790,15 @@ X_STATUS Emulator::CompleteLaunch(const std::filesystem::path& path,
|
||||
|
||||
table = tabulate::Table();
|
||||
table.format().multi_byte_characters(true);
|
||||
table.add_row({"ID", "Name", "Data Size"});
|
||||
table.add_row({"ID", "Name", "Matchmaking", "Data Size"});
|
||||
|
||||
for (const kernel::util::GameInfoDatabase::Property& entry :
|
||||
properties_list) {
|
||||
std::string label =
|
||||
string_util::remove_eol(string_util::trim(entry.description));
|
||||
|
||||
table.add_row({fmt::format("{:08X}", entry.id), label,
|
||||
entry.is_matchmaking ? "True" : "False",
|
||||
fmt::format("{}", entry.data_size)});
|
||||
}
|
||||
XELOGI("\n-------------------- PROPERTIES --------------------\n{}",
|
||||
@@ -1807,13 +1809,16 @@ X_STATUS Emulator::CompleteLaunch(const std::filesystem::path& path,
|
||||
|
||||
table = tabulate::Table();
|
||||
table.format().multi_byte_characters(true);
|
||||
table.add_row({"ID", "Name", "Default Value", "Max Value"});
|
||||
table.add_row(
|
||||
{"ID", "Name", "Matchmaking", "Default Value", "Max Value"});
|
||||
|
||||
for (const kernel::util::GameInfoDatabase::Context& entry :
|
||||
contexts_list) {
|
||||
std::string label =
|
||||
string_util::remove_eol(string_util::trim(entry.description));
|
||||
|
||||
table.add_row({fmt::format("{:08X}", entry.id), label,
|
||||
entry.is_matchmaking ? "True" : "False",
|
||||
fmt::format("{}", entry.default_value),
|
||||
fmt::format("{}", entry.max_value)});
|
||||
}
|
||||
|
||||
@@ -226,11 +226,9 @@ X_RESULT SDLInputDriver::GetState(uint32_t user_index,
|
||||
return X_ERROR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
|
||||
// Make sure packet_number is only incremented by 1, even if there have been
|
||||
// multiple updates between GetState calls. Also track `is_active` to
|
||||
// increment the packet number if it changed.
|
||||
if (controller->is_active || controller->state_changed) {
|
||||
if (controller->state_changed) {
|
||||
controller->state.packet_number++;
|
||||
controller->state_changed = false;
|
||||
}
|
||||
std::memcpy(out_state, &controller->state, sizeof(*out_state));
|
||||
return X_ERROR_SUCCESS;
|
||||
|
||||
@@ -52,7 +52,6 @@ class SDLInputDriver final : public InputDriver {
|
||||
X_INPUT_CAPABILITIES caps;
|
||||
X_INPUT_STATE state;
|
||||
bool state_changed;
|
||||
bool is_active;
|
||||
};
|
||||
|
||||
enum class RepeatState {
|
||||
|
||||
@@ -103,6 +103,8 @@ GameInfoDatabase::Context GameInfoDatabase::GetContext(
|
||||
context.max_value = xdbf_context->max_value;
|
||||
context.is_system = xam::UserData::is_system_property(xdbf_context->id);
|
||||
context.is_presence = GetPresence().property_bag.contexts.contains(id);
|
||||
context.is_matchmaking =
|
||||
GetMatchmakingCollection().contexts.contains(xdbf_context->id);
|
||||
context.description = GetLocalizedString(xdbf_context->string_id);
|
||||
return context;
|
||||
}
|
||||
@@ -124,6 +126,8 @@ GameInfoDatabase::Property GameInfoDatabase::GetProperty(
|
||||
property.data_size = xdbf_property->data_size;
|
||||
property.is_system = xam::UserData::is_system_property(xdbf_property->id);
|
||||
property.is_presence = GetPresence().property_bag.properties.contains(id);
|
||||
property.is_matchmaking =
|
||||
GetMatchmakingCollection().properties.contains(xdbf_property->id);
|
||||
property.description = GetLocalizedString(xdbf_property->string_id);
|
||||
return property;
|
||||
}
|
||||
@@ -350,6 +354,11 @@ GameInfoDatabase::ProductInformation GameInfoDatabase::GetProductInformation()
|
||||
return info;
|
||||
}
|
||||
|
||||
GameInfoDatabase::PropertyBag GameInfoDatabase::GetMatchmakingCollection()
|
||||
const {
|
||||
return GetPropertyBag(*spa_gamedata_->GetMatchCollection());
|
||||
}
|
||||
|
||||
// Aggregators
|
||||
std::vector<GameInfoDatabase::Context> GameInfoDatabase::GetContexts() const {
|
||||
std::vector<Context> contexts;
|
||||
|
||||
@@ -34,6 +34,7 @@ class GameInfoDatabase {
|
||||
uint32_t default_value;
|
||||
bool is_system;
|
||||
bool is_presence;
|
||||
bool is_matchmaking;
|
||||
std::string description;
|
||||
};
|
||||
|
||||
@@ -42,6 +43,7 @@ class GameInfoDatabase {
|
||||
uint32_t data_size;
|
||||
bool is_system;
|
||||
bool is_presence;
|
||||
bool is_matchmaking;
|
||||
std::string description;
|
||||
};
|
||||
|
||||
@@ -160,6 +162,7 @@ class GameInfoDatabase {
|
||||
Query GetQueryData(const uint32_t id) const;
|
||||
std::vector<XLanguage> GetSupportedLanguages() const;
|
||||
ProductInformation GetProductInformation() const;
|
||||
PropertyBag GetMatchmakingCollection() const;
|
||||
|
||||
// Aggregators for specific usecases
|
||||
std::vector<Context> GetContexts() const;
|
||||
|
||||
@@ -64,16 +64,32 @@ X_HRESULT XamApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
||||
|
||||
assert_true(enum_struct->magic == kXObjSignature);
|
||||
|
||||
// This is a struct of XCONTENT_DATA_INTERNAL
|
||||
uint8_t* content_data_ptr =
|
||||
memory_->TranslateVirtual<uint8_t*>(data_ptr->buffer_ptr);
|
||||
XCONTENT_CROSS_TITLE_DATA cross_title_data = {};
|
||||
uint8_t* cross_title_data_ptr =
|
||||
reinterpret_cast<uint8_t*>(&cross_title_data);
|
||||
|
||||
uint32_t item_count = 0;
|
||||
X_RESULT result = e->WriteItems(0, cross_title_data_ptr, &item_count);
|
||||
|
||||
XCONTENT_DATA_INTERNAL* content_data_ptr =
|
||||
memory_->TranslateVirtual<XCONTENT_DATA_INTERNAL*>(
|
||||
data_ptr->buffer_ptr);
|
||||
|
||||
assert_true(data_ptr->buffer_size == sizeof(XCONTENT_DATA_INTERNAL));
|
||||
|
||||
std::memset(content_data_ptr, 0, data_ptr->buffer_size);
|
||||
|
||||
uint32_t item_count = 0;
|
||||
X_RESULT result = e->WriteItems(0, content_data_ptr, &item_count);
|
||||
if (!result) {
|
||||
content_data_ptr->device_id = cross_title_data.content_data.device_id;
|
||||
content_data_ptr->content_type =
|
||||
cross_title_data.content_data.content_type;
|
||||
content_data_ptr->set_display_name(
|
||||
cross_title_data.content_data.display_name());
|
||||
content_data_ptr->set_file_name(
|
||||
cross_title_data.content_data.file_name());
|
||||
content_data_ptr->padding[0] = content_data_ptr->padding[1] = 0;
|
||||
content_data_ptr->title_id = cross_title_data.title_id;
|
||||
}
|
||||
|
||||
result = X_HRESULT_FROM_WIN32(result);
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ void SpaInfo::Load() {
|
||||
LoadProperties();
|
||||
LoadContexts();
|
||||
LoadPresenceModes();
|
||||
LoadMatchmaking();
|
||||
LoadStatsViews();
|
||||
}
|
||||
|
||||
@@ -329,6 +330,41 @@ void SpaInfo::LoadPresenceModes() {
|
||||
}
|
||||
}
|
||||
|
||||
void SpaInfo::LoadMatchmaking() {
|
||||
auto matchmaking_schema =
|
||||
GetEntry(static_cast<uint16_t>(SpaSection::kMetadata), kXdbfIdXmat);
|
||||
if (!matchmaking_schema) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto xrpt_head = reinterpret_cast<const XdbfSectionHeader*>(
|
||||
matchmaking_schema->data.data());
|
||||
assert_true(xrpt_head->magic == kXdbfSignatureXmat);
|
||||
assert_true(xrpt_head->version == 1);
|
||||
|
||||
auto xpbm_head = reinterpret_cast<const XdbfSectionHeader*>(xrpt_head + 1);
|
||||
|
||||
assert_true(xpbm_head->magic == kXdbfSignatureXpbm);
|
||||
assert_true(xpbm_head->version == 1);
|
||||
|
||||
const PropertyBagEntry* property_bag_header_ptr =
|
||||
reinterpret_cast<const PropertyBagEntry*>(xpbm_head + 1);
|
||||
|
||||
auto contexts_ptr =
|
||||
reinterpret_cast<const xe::be<uint32_t>*>(property_bag_header_ptr + 1);
|
||||
|
||||
auto properties_ptr = reinterpret_cast<const xe::be<uint32_t>*>(
|
||||
contexts_ptr + property_bag_header_ptr->contexts_count);
|
||||
|
||||
for (uint32_t i = 0; i < property_bag_header_ptr->contexts_count; i++) {
|
||||
matchmaking_.contexts.insert(contexts_ptr[i]);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < property_bag_header_ptr->properties_count; i++) {
|
||||
matchmaking_.properties.insert(properties_ptr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
const uint8_t* SpaInfo::ReadXLast(uint32_t& compressed_size,
|
||||
uint32_t& decompressed_size) {
|
||||
auto xlast_table =
|
||||
|
||||
@@ -297,6 +297,8 @@ class SpaInfo : public XdbfFile {
|
||||
|
||||
const PresenceTableEntry* GetPresence() const { return &presence_; }
|
||||
|
||||
const PropertyBag* GetMatchCollection() const { return &matchmaking_; }
|
||||
|
||||
const XdbfContextTableEntry* GetContext(uint32_t id);
|
||||
const XdbfPropertyTableEntry* GetProperty(uint32_t id);
|
||||
const std::optional<ViewTable> GetStatsView(uint32_t id);
|
||||
@@ -328,6 +330,7 @@ class SpaInfo : public XdbfFile {
|
||||
std::vector<const XdbfPropertyTableEntry*> properties_;
|
||||
std::vector<ViewTable> stats_views_;
|
||||
PresenceTableEntry presence_;
|
||||
PropertyBag matchmaking_;
|
||||
|
||||
using XdbfLanguageStrings = std::map<uint16_t, std::string>;
|
||||
|
||||
@@ -342,8 +345,8 @@ class SpaInfo : public XdbfFile {
|
||||
void LoadProperties();
|
||||
|
||||
void LoadStatsViews();
|
||||
|
||||
void LoadPresenceModes();
|
||||
void LoadMatchmaking();
|
||||
|
||||
template <typename T>
|
||||
static T GetSpaEntry(std::vector<T>& container, uint32_t id);
|
||||
|
||||
@@ -254,25 +254,31 @@ dword_result_t ObReferenceObjectByHandle_entry(dword_t handle,
|
||||
}
|
||||
|
||||
uint32_t native_ptr = object->guest_object();
|
||||
auto& object_types =
|
||||
kernel_state()->host_object_type_enum_to_guest_object_type_ptr_;
|
||||
auto object_type = object_types.find(object->type());
|
||||
if (object_type != object_types.end()) {
|
||||
if (object_type_ptr && object_type_ptr != object_type->second) {
|
||||
return X_STATUS_OBJECT_TYPE_MISMATCH;
|
||||
|
||||
if (object_type_ptr) {
|
||||
auto& object_types =
|
||||
kernel_state()->host_object_type_enum_to_guest_object_type_ptr_;
|
||||
|
||||
if (object_types.contains(object->type())) {
|
||||
if (object_type_ptr != object_types[object->type()]) {
|
||||
return X_STATUS_OBJECT_TYPE_MISMATCH;
|
||||
}
|
||||
} else {
|
||||
assert_unhandled_case(object->type());
|
||||
native_ptr = 0xDEADF00D;
|
||||
}
|
||||
} else {
|
||||
assert_unhandled_case(object->type());
|
||||
native_ptr = 0xDEADF00D;
|
||||
}
|
||||
|
||||
// Caller takes the reference.
|
||||
// It's released in ObDereferenceObject.
|
||||
object->RetainHandle();
|
||||
|
||||
xenia_assert(native_ptr != 0);
|
||||
assert_not_zero(native_ptr);
|
||||
|
||||
if (out_object_ptr.guest_address()) {
|
||||
*out_object_ptr = native_ptr;
|
||||
}
|
||||
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(ObReferenceObjectByHandle, kNone, kImplemented);
|
||||
|
||||
Reference in New Issue
Block a user